Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integrate linenoise with web server #162

Merged
merged 1 commit into from
Mar 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 11 additions & 43 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 Expand Up @@ -706,4 +674,4 @@ bool run_console(char *infile_name)
}

return err_cnt == 0;
}
}
23 changes: 22 additions & 1 deletion 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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Improve the descriptions by explaining the functionality of this callback invoked inside the main loop of linenoise. You should discuss the use case for example.

* 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 Expand Up @@ -1362,4 +1383,4 @@ int line_history_load(const char *filename)
}
fclose(fp);
return 0;
}
}
4 changes: 3 additions & 1 deletion 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 All @@ -74,4 +76,4 @@ void line_mask_mode_disable(void);
}
#endif

#endif /* __LINENOISE_H */
#endif /* __LINENOISE_H */
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;
}
4 changes: 3 additions & 1 deletion 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);

#endif
int web_eventmux(char *buf);

#endif
Loading