Skip to content

Commit

Permalink
Merge branch 'sysprog21:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
m561247 authored Mar 11, 2024
2 parents cdf6504 + 6c80a7d commit c75b4d8
Show file tree
Hide file tree
Showing 9 changed files with 82 additions and 47 deletions.
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ level, e.g.:
}
```

If the case bock does not break, then it is strongly recommended to add a
If the case block does not break, then it is strongly recommended to add a
comment containing "fallthrough" to indicate it. Modern compilers can also
be configured to require such comment (see gcc `-Wimplicit-fallthrough`).

Expand Down
52 changes: 10 additions & 42 deletions console.c
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,7 @@ static bool do_web(int argc, char *argv[])
web_fd = web_open(port);
if (web_fd > 0) {
printf("listen on port %d, fd is %d\n", port, web_fd);
line_set_eventmux_callback(web_eventmux);
use_linenoise = false;
} else {
perror("ERROR");
Expand Down Expand Up @@ -560,13 +561,13 @@ static int cmd_select(int nfds,
fd_set *exceptfds,
struct timeval *timeout)
{
int infd;
fd_set local_readset;

if (cmd_done())
return 0;

if (!block_flag) {
int infd;
/* Process any commands in input buffer */
if (!readfds)
readfds = &local_readset;
Expand All @@ -581,51 +582,18 @@ static int cmd_select(int nfds,
FD_SET(web_fd, readfds);

if (infd == STDIN_FILENO && prompt_flag) {
printf("%s", prompt);
char *cmdline = linenoise(prompt);
if (cmdline)
interpret_cmd(cmdline);
fflush(stdout);
prompt_flag = true;
} else if (infd != STDIN_FILENO) {
char *cmdline = readline();
if (cmdline)
interpret_cmd(cmdline);
}

if (infd >= nfds)
nfds = infd + 1;
if (web_fd >= nfds)
nfds = web_fd + 1;
}
if (nfds == 0)
return 0;

int result = select(nfds, readfds, writefds, exceptfds, timeout);
if (result <= 0)
return result;

infd = buf_stack->fd;
if (readfds && FD_ISSET(infd, readfds)) {
/* Commandline input available */
FD_CLR(infd, readfds);
result--;

set_echo(0);
char *cmdline = readline();
if (cmdline)
interpret_cmd(cmdline);
} else if (readfds && FD_ISSET(web_fd, readfds)) {
FD_CLR(web_fd, readfds);
result--;
struct sockaddr_in clientaddr;
socklen_t clientlen = sizeof(clientaddr);
web_connfd =
accept(web_fd, (struct sockaddr *) &clientaddr, &clientlen);

char *p = web_recv(web_connfd, &clientaddr);
char *buffer = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\n";
web_send(web_connfd, buffer);

if (p)
interpret_cmd(p);
free(p);
close(web_connfd);
}
return result;
return 0;
}

bool finish_cmd()
Expand Down
21 changes: 21 additions & 0 deletions linenoise.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ static char *unsupported_term[] = {"dumb", "cons25", "emacs", NULL};
static line_completion_callback_t *completion_callback = NULL;
static line_hints_callback_t *hints_callback = NULL;
static line_free_hints_callback_t *free_hints_callback = NULL;
static line_eventmux_callback_t *eventmux_callback = NULL;

static struct termios orig_termios; /* In order to restore at exit.*/
static bool maskmode = false; /* Show "***" instead of input. For passwords. */
Expand Down Expand Up @@ -472,6 +473,20 @@ void line_set_free_hints_callback(line_free_hints_callback_t *fn)
free_hints_callback = fn;
}

/* Register a function to perform I/O multiplexing to monitor multiple file
* descriptor from different input at the same time, so we can allow the ability
* of receiving commands from different input sources and still provides the
* command-line auto-complete feature of this package. For example, the main
* loop of this package can only deal with standard input file descriptor
* originally. When this callback function is invoked, it allows the main loop
* of this package to deal with multiple file descriptors from different input
* alongside with the origin feature to deal with the standard input.
*/
void line_set_eventmux_callback(line_eventmux_callback_t *fn)
{
eventmux_callback = fn;
}

/* This function is used by the callback function registered by the user
* in order to add completion options given the input string when the
* user typed <tab>.
Expand Down Expand Up @@ -932,6 +947,12 @@ static int line_edit(int stdin_fd,
int nread;
char seq[5];

if (eventmux_callback != NULL) {
int result = eventmux_callback(l.buf);
if (result != 0)
return result;
}

nread = read(l.ifd, &c, 1);
if (nread <= 0)
return l.len;
Expand Down
2 changes: 2 additions & 0 deletions linenoise.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,11 @@ typedef struct {
typedef void(line_completion_callback_t)(const char *, line_completions_t *);
typedef char *(line_hints_callback_t)(const char *, int *color, int *bold);
typedef void(line_free_hints_callback_t)(void *);
typedef int(line_eventmux_callback_t)(char *);
void line_set_completion_callback(line_completion_callback_t *);
void line_set_hints_callback(line_hints_callback_t *);
void line_set_free_hints_callback(line_free_hints_callback_t *);
void line_set_eventmux_callback(line_eventmux_callback_t *);
void line_add_completion(line_completions_t *, const char *);
/* clang-format on */

Expand Down
6 changes: 3 additions & 3 deletions queue.h
Original file line number Diff line number Diff line change
Expand Up @@ -239,9 +239,9 @@ int q_descend(struct list_head *head);
* This function merge the second to the last queues in the chain into the first
* queue. The queues are guaranteed to be sorted before this function is called.
* No effect if there is only one queue in the chain. Allocation is disallowed
* in this function. There is no need to free the 'qcontext_t' and its member
* 'q' since they will be released externally. However, q_merge() is responsible
* for making the queues to be NULL-queue, except the first one.
* in this function. There is no need to free the 'queue_contex_t' and its
* member 'q' since they will be released externally. However, q_merge() is
* responsible for making the queues to be NULL-queue, except the first one.
*
* Reference:
* https://leetcode.com/problems/merge-k-sorted-lists/
Expand Down
2 changes: 1 addition & 1 deletion scripts/checksums
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
fc83d2142cdebd29bf8dbf01d2c21c59f8c6a7ce queue.h
444bab14cb8ad4c949f61b3c10a22a3ed2401425 queue.h
3337dbccc33eceedda78e36cc118d5a374838ec7 list.h
2 changes: 2 additions & 0 deletions scripts/pre-commit.hook
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ for f in *.c; do
CPPCHECK_unmatched="$CPPCHECK_unmatched --suppress=unmatchedSuppression:$f"
done

# We suppress the checkLevelNormal warning for Cppcheck versions 2.11 and above.
# Please refer to issues/153 for more details.
CPPCHECK_suppresses="--inline-suppr harness.c \
--suppress=missingIncludeSystem \
--suppress=noValidConfiguration \
Expand Down
40 changes: 40 additions & 0 deletions web.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
#define TCP_CORK TCP_NOPUSH
#endif

static int server_fd;

typedef struct {
int fd; /* descriptor for this buf */
int count; /* unread byte in this buf */
Expand Down Expand Up @@ -153,6 +155,9 @@ int web_open(int port)
/* Make it a listening socket ready to accept connection requests */
if (listen(listenfd, LISTENQ) < 0)
return -1;

server_fd = listenfd;

return listenfd;
}

Expand Down Expand Up @@ -228,3 +233,38 @@ char *web_recv(int fd, struct sockaddr_in *clientaddr)

return ret;
}

int web_eventmux(char *buf)
{
fd_set listenset;

FD_ZERO(&listenset);
FD_SET(STDIN_FILENO, &listenset);
int max_fd = STDIN_FILENO;
if (server_fd > 0) {
FD_SET(server_fd, &listenset);
max_fd = max_fd > server_fd ? max_fd : server_fd;
}
int result = select(max_fd + 1, &listenset, NULL, NULL, NULL);
if (result < 0)
return -1;

if (server_fd > 0 && FD_ISSET(server_fd, &listenset)) {
FD_CLR(server_fd, &listenset);
struct sockaddr_in clientaddr;
socklen_t clientlen = sizeof(clientaddr);
int web_connfd =
accept(server_fd, (struct sockaddr *) &clientaddr, &clientlen);

char *p = web_recv(web_connfd, &clientaddr);
char *buffer = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\n";
web_send(web_connfd, buffer);
strncpy(buf, p, strlen(p) + 1);
free(p);
close(web_connfd);
return strlen(buf);
}

FD_CLR(STDIN_FILENO, &listenset);
return 0;
}
2 changes: 2 additions & 0 deletions web.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,6 @@ char *web_recv(int fd, struct sockaddr_in *clientaddr);

void web_send(int out_fd, char *buffer);

int web_eventmux(char *buf);

#endif

0 comments on commit c75b4d8

Please sign in to comment.