[njs] Shell: improved working with libedit.

Dmitry Volyntsev xeioex at nginx.com
Sat May 20 04:31:04 UTC 2023


details:   https://hg.nginx.org/njs/rev/5889afe2a4b7
branches:  
changeset: 2126:5889afe2a4b7
user:      Dmitry Volyntsev <xeioex at nginx.com>
date:      Fri May 19 20:22:16 2023 -0700
description:
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.

diffstat:

 external/njs_shell.c |  21 ++++++++++++++++-----
 test/shell_test.exp  |  10 +++++-----
 2 files changed, 21 insertions(+), 10 deletions(-)

diffs (81 lines):

diff -r 7cd80c77433b -r 5889afe2a4b7 external/njs_shell.c
--- a/external/njs_shell.c	Fri May 19 20:22:15 2023 -0700
+++ b/external/njs_shell.c	Fri May 19 20:22:16 2023 -0700
@@ -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, 
 
     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 -r 7cd80c77433b -r 5889afe2a4b7 test/shell_test.exp
--- a/test/shell_test.exp	Fri May 19 20:22:15 2023 -0700
+++ b/test/shell_test.exp	Fri May 19 20:22:16 2023 -0700
@@ -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 {


More information about the nginx-devel mailing list