From ec9c169a675040ae55536f01270581bf5b4f158a Mon Sep 17 00:00:00 2001 From: Dmitry Volyntsev Date: Fri, 19 May 2023 20:22:16 -0700 Subject: [PATCH] Shell: improved working with libedit. Previously, libedit unlike GNU readline does not reinstall rl_callback_handler_install handler after the handler was called. As a result make shell_test executed ~20 times longer with libedit. The fix is to reinstall the rl_callback_handler_install handler explicitely every time the handler is invoked. --- external/njs_shell.c | 21 ++++++++++++++++----- test/shell_test.exp | 10 +++++----- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/external/njs_shell.c b/external/njs_shell.c index 3d0cb34f..bd91c467 100644 --- a/external/njs_shell.c +++ b/external/njs_shell.c @@ -1087,6 +1087,7 @@ njs_cb_line_handler(char *line_in) line.length = njs_strlen(line.start); if (line.length == 0) { + rl_callback_handler_install(">> ", njs_cb_line_handler); return; } @@ -1097,6 +1098,10 @@ njs_cb_line_handler(char *line_in) njs_running = NJS_ERROR; } + if (ret == NJS_OK) { + rl_callback_handler_install(">> ", njs_cb_line_handler); + } + free(line.start); } @@ -1104,9 +1109,11 @@ njs_cb_line_handler(char *line_in) static njs_int_t njs_interactive_shell(njs_opts_t *opts, njs_vm_opt_t *vm_options) { - fd_set fds; - njs_vm_t *vm; - njs_int_t ret; + int flags; + fd_set fds; + njs_vm_t *vm; + njs_int_t ret; + struct timeval timeout; if (njs_editline_init() != NJS_OK) { njs_stderror("failed to init completions\n"); @@ -1126,13 +1133,17 @@ njs_interactive_shell(njs_opts_t *opts, njs_vm_opt_t *vm_options) rl_callback_handler_install(">> ", njs_cb_line_handler); + flags = fcntl(STDIN_FILENO, F_GETFL, 0); + fcntl(STDIN_FILENO, F_SETFL, flags | O_NONBLOCK); + njs_running = NJS_OK; while (njs_running == NJS_OK) { FD_ZERO(&fds); - FD_SET(fileno(rl_instream), &fds); + FD_SET(STDIN_FILENO, &fds); + timeout = (struct timeval) {1, 0}; - ret = select(FD_SETSIZE, &fds, NULL, NULL, NULL); + ret = select(FD_SETSIZE, &fds, NULL, NULL, &timeout); if (ret < 0 && errno != EINTR) { njs_stderror("select() failed\n"); njs_running = NJS_ERROR; diff --git a/test/shell_test.exp b/test/shell_test.exp index 126ddb32..4afc10b8 100644 --- a/test/shell_test.exp +++ b/test/shell_test.exp @@ -100,15 +100,15 @@ njs_test { } njs_test { - {"O\t" - "O\a*bject"} + {"Type\t" + "Type\a*Error"} {"\t\t" - "Object.create*Object.isSealed"} + "TypeError.length"} } njs_test { - {"Object.\t\t" - "Object.create*Object.isSealed"} + {"TypeError.\t\t" + "TypeError.length*TypeError.prototype"} } njs_test { -- 2.47.3