diff --git a/console.c b/console.c index 61c697e04..ed4f38b55 100644 --- a/console.c +++ b/console.c @@ -64,6 +64,14 @@ static bool has_infile = false; #define MAXQUIT 10 static cmd_func_t quit_helpers[MAXQUIT]; static int quit_helper_cnt = 0; +static char *headers = + "HTTP/1.1 200 OK\r\n" + "Content-Type: text/html\r\n\r\n" + "" + "\n"; static void init_in(); @@ -392,7 +400,7 @@ static bool do_time(int argc, char *argv[]) } static bool use_linenoise = true; -static int web_fd; +int web_fd = 0; static bool do_web(int argc, char *argv[]) { @@ -405,7 +413,6 @@ 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); - use_linenoise = false; } else { perror("ERROR"); exit(web_fd); @@ -553,7 +560,7 @@ static bool cmd_done() * nfds should be set to the maximum file descriptor for network sockets. * If nfds == 0, this indicates that there is no pending network activity */ -int web_connfd; +int web_connfd = 0; static int cmd_select(int nfds, fd_set *readfds, fd_set *writefds, @@ -617,15 +624,7 @@ static int cmd_select(int nfds, accept(web_fd, (struct sockaddr *) &clientaddr, &clientlen); char *p = web_recv(web_connfd, &clientaddr); - char *buffer = - "HTTP/1.1 200 OK\r\n" - "Content-Type: text/html\r\n\r\n" - "" - "
\n"; - web_send(web_connfd, buffer); + web_send(web_connfd, headers); if (p) { printf("\rweb> %s\n", p); @@ -635,6 +634,7 @@ static int cmd_select(int nfds, free(p); close(web_connfd); + web_connfd = 0; } return result; } @@ -699,10 +699,20 @@ bool run_console(char *infile_name) if (!has_infile) { char *cmdline; while (use_linenoise && (cmdline = linenoise(prompt))) { + if (web_connfd) { + web_send(web_connfd, headers); + printf("\033[Fweb> %s\n", cmdline); + fflush(stdout); + } else { + line_history_add(cmdline); /* Add to the history. */ + line_history_save(HISTORY_FILE); /* Save the history on disk. */ + } interpret_cmd(cmdline); - line_history_add(cmdline); /* Add to the history. */ - line_history_save(HISTORY_FILE); /* Save the history on disk. */ line_free(cmdline); + if (web_connfd) { + close(web_connfd); + web_connfd = 0; + } while (buf_stack && buf_stack->fd != STDIN_FILENO) cmd_select(0, NULL, NULL, NULL, NULL); has_infile = false; diff --git a/linenoise.c b/linenoise.c index a01fd59ae..ad6f9f5be 100644 --- a/linenoise.c +++ b/linenoise.c @@ -110,12 +110,15 @@ #include #include #include +#include +#include #include #include #include #include #include "linenoise.h" +#include "web.h" #define LINENOISE_DEFAULT_HISTORY_MAX_LEN 100 #define LINENOISE_MAX_LINE 4096 @@ -134,6 +137,8 @@ static bool atexit_registered = false; /* Register atexit just 1 time. */ static int history_max_len = LINENOISE_DEFAULT_HISTORY_MAX_LEN; static int history_len = 0; static char **history = NULL; +extern int web_fd; +extern int web_connfd; /* The line_state structure represents the state during line editing. * We pass this state to functions implementing specific editing @@ -893,6 +898,8 @@ static void line_edit_next_word(struct line_state *l) * * The function returns the length of the current buffer. */ +extern int web_connfd; +extern int web_fd; static int line_edit(int stdin_fd, int stdout_fd, char *buf, @@ -929,12 +936,38 @@ static int line_edit(int stdin_fd, return -1; while (1) { signed char c; - int nread; char seq[5]; - - nread = read(l.ifd, &c, 1); - if (nread <= 0) - return l.len; + fd_set set; + + FD_ZERO(&set); + FD_SET(web_fd, &set); + FD_SET(stdin_fd, &set); + int rv = select(web_fd + 1, &set, NULL, NULL, NULL); + struct sockaddr_in clientaddr; + socklen_t clientlen = sizeof clientaddr; + + switch (rv) { + case -1: + perror("select"); /* an error occurred */ + continue; + case 0: + printf("timeout occurred\n"); /* a timeout occurred */ + continue; + default: + if (web_fd && FD_ISSET(web_fd, &set)) { + web_connfd = + accept(web_fd, (struct sockaddr *) &clientaddr, &clientlen); + char *p = web_recv(web_connfd, &clientaddr); + strncpy(buf, p, strlen(p) + 1); + free(p); + return strlen(p); + } else if (FD_ISSET(stdin_fd, &set)) { + int nread = read(l.ifd, &c, 1); + if (nread <= 0) + return l.len; + } + break; + } /* Only autocomplete when the callback is set. It returns < 0 when * there was an error reading from fd. Otherwise it will return the