getty: fix for NOCTTY killing us with SIGHUP
[oweals/busybox.git] / libbb / lineedit.c
index 603bbfcae7573299809487b2025de30a1ec26c55..db8416712f40f5a8cc55adaadde7fe4ede6e2290 100644 (file)
@@ -1520,8 +1520,10 @@ static void remember_in_history(char *str)
                for (i = 0; i < state->max_history-1; i++)
                        state->history[i] = state->history[i+1];
                /* i == state->max_history-1 */
-               if (ENABLE_FEATURE_EDITING_SAVE_ON_EXIT && state->cnt_history_in_file)
+# if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT
+               if (state->cnt_history_in_file)
                        state->cnt_history_in_file--;
+# endif
        }
        /* i <= state->max_history-1 */
        state->history[i++] = xstrdup(str);
@@ -2204,14 +2206,17 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman
 #define command command_must_not_be_used
 
        new_settings = initial_settings;
-       new_settings.c_lflag &= ~ICANON;        /* unbuffered input */
-       /* Turn off echoing and CTRL-C, so we can trap it */
-       new_settings.c_lflag &= ~(ECHO | ECHONL | ISIG);
-       /* Hmm, in linux c_cc[] is not parsed if ICANON is off */
+       /* ~ICANON: unbuffered input (most c_cc[] are disabled, VMIN/VTIME are enabled) */
+       /* ~ECHO, ~ECHONL: turn off echoing, including newline echoing */
+       /* ~ISIG: turn off INTR (ctrl-C), QUIT, SUSP */
+       new_settings.c_lflag &= ~(ICANON | ECHO | ECHONL | ISIG);
+       /* reads would block only if < 1 char is available */
        new_settings.c_cc[VMIN] = 1;
+       /* no timeout (reads block forever) */
        new_settings.c_cc[VTIME] = 0;
-       /* Turn off CTRL-C, so we can trap it */
-       new_settings.c_cc[VINTR] = _POSIX_VDISABLE;
+       /* Should be not needed if ISIG is off: */
+       /* Turn off CTRL-C */
+       /* new_settings.c_cc[VINTR] = _POSIX_VDISABLE; */
        tcsetattr_stdin_TCSANOW(&new_settings);
 
 #if ENABLE_USERNAME_OR_HOMEDIR
@@ -2504,6 +2509,44 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman
                                vi_cmdmode = 1;
                                input_backward(1);
                        }
+                       /* Handle a few ESC-<key> combinations the same way
+                        * standard readline bindings (IOW: bash) do.
+                        * Often, Alt-<key> generates ESC-<key>.
+                        */
+                       ic = lineedit_read_key(read_key_buffer, timeout);
+                       switch (ic) {
+                               //case KEYCODE_LEFT: - bash doesn't do this
+                               case 'b':
+                                       ctrl_left();
+                                       break;
+                               //case KEYCODE_RIGHT: - bash doesn't do this
+                               case 'f':
+                                       ctrl_right();
+                                       break;
+                               //case KEYCODE_DELETE: - bash doesn't do this
+                               case 'd':  /* Alt-D */
+                               {
+                                       /* Delete word forward */
+                                       int nc, sc = cursor;
+                                       ctrl_right();
+                                       nc = cursor;
+                                       input_backward(cursor - sc);
+                                       while (--nc >= cursor)
+                                               input_delete(1);
+                                       break;
+                               }
+                               case '\b':   /* Alt-Backspace(?) */
+                               case '\x7f': /* Alt-Backspace(?) */
+                               //case 'w': - bash doesn't do this
+                               {
+                                       /* Delete word backward */
+                                       int sc = cursor;
+                                       ctrl_left();
+                                       while (sc-- > cursor)
+                                               input_delete(1);
+                                       break;
+                               }
+                       }
                        break;
 #endif /* FEATURE_COMMAND_EDITING_VI */
 
@@ -2532,9 +2575,11 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman
                        input_backward(1);
                        break;
                case KEYCODE_CTRL_LEFT:
+               case KEYCODE_ALT_LEFT: /* bash doesn't do it */
                        ctrl_left();
                        break;
                case KEYCODE_CTRL_RIGHT:
+               case KEYCODE_ALT_RIGHT: /* bash doesn't do it */
                        ctrl_right();
                        break;
                case KEYCODE_HOME: