From: Dmitry Volyntsev Date: Sat, 20 May 2023 03:22:16 +0000 (-0700) Subject: Shell: improved working with libedit. X-Git-Url: http://www.kaiwu.me/postgresql/commit/static/gitweb.js?a=commitdiff_plain;h=ec9c169a675040ae55536f01270581bf5b4f158a;p=njs.git 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. --- 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 {