summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko2016-11-25 03:41:03 +0100
committerDenys Vlasenko2016-11-25 03:41:03 +0100
commit4b89d512b1215e7b9d619af03496540d30cbbd1a (patch)
tree166830c57d912e78dfac591c4e47a5cd80cb886e
parent24860fa09cf954704232406055d7ca291c636eab (diff)
downloadbusybox-4b89d512b1215e7b9d619af03496540d30cbbd1a.zip
busybox-4b89d512b1215e7b9d619af03496540d30cbbd1a.tar.gz
ash,hush: make ^C in interactive mode visually much closer to bash behavior
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--libbb/lineedit.c2
-rw-r--r--shell/ash.c4
-rw-r--r--shell/hush.c17
3 files changed, 15 insertions, 8 deletions
diff --git a/libbb/lineedit.c b/libbb/lineedit.c
index ac049f5..4d7828c 100644
--- a/libbb/lineedit.c
+++ b/libbb/lineedit.c
@@ -2251,6 +2251,7 @@ static int32_t reverse_i_search(void)
* Returns:
* -1 on read errors or EOF, or on bare Ctrl-D,
* 0 on ctrl-C (the line entered is still returned in 'command'),
+ * (in both cases the cursor remains on the input line, '\n' is not printed)
* >0 length of input string, including terminating '\n'
*/
int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *command, int maxsize, int timeout)
@@ -2686,7 +2687,6 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman
&& ic_raw == initial_settings.c_cc[VINTR]
) {
/* Ctrl-C (usually) - stop gathering input */
- goto_new_line();
command_len = 0;
break_out = -1; /* "do not append '\n'" */
break;
diff --git a/shell/ash.c b/shell/ash.c
index 3e5a3b3..2bdb4aa 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -9869,7 +9869,8 @@ preadfd(void)
reinit_unicode_for_ash();
nr = read_line_input(line_input_state, cmdedit_prompt, buf, IBUFSIZ, timeout);
if (nr == 0) {
- /* Ctrl+C pressed */
+ /* ^C pressed, "convert" to SIGINT */
+ write(STDOUT_FILENO, "^C", 2);
if (trap[SIGINT]) {
buf[0] = '\n';
buf[1] = '\0';
@@ -9877,6 +9878,7 @@ preadfd(void)
return 1;
}
exitstatus = 128 + SIGINT;
+ bb_putchar('\n');
goto retry;
}
if (nr < 0) {
diff --git a/shell/hush.c b/shell/hush.c
index 5b720ce..bcd4dff 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -1756,8 +1756,6 @@ static int check_and_run_traps(void)
switch (sig) {
case SIGINT:
debug_printf_exec("%s: sig:%d default SIGINT handler\n", __func__, sig);
- /* Builtin was ^C'ed, make it look prettier: */
- bb_putchar('\n');
G.flag_SIGINT = 1;
last_sig = sig;
break;
@@ -2195,16 +2193,22 @@ static int get_user_input(struct in_str *i)
# if ENABLE_FEATURE_EDITING
for (;;) {
reinit_unicode_for_hush();
- G.flag_SIGINT = 0;
+ if (G.flag_SIGINT) {
+ /* There was ^C'ed, make it look prettier: */
+ bb_putchar('\n');
+ G.flag_SIGINT = 0;
+ }
/* buglet: SIGINT will not make new prompt to appear _at once_,
- * only after <Enter>. (^C will work) */
+ * only after <Enter>. (^C works immediately) */
r = read_line_input(G.line_input_state, prompt_str,
G.user_input_buf, CONFIG_FEATURE_EDITING_MAX_LEN-1,
/*timeout*/ -1
);
- /* read_line_input intercepts ^C, "convert" it into SIGINT */
- if (r == 0)
+ /* read_line_input intercepts ^C, "convert" it to SIGINT */
+ if (r == 0) {
+ write(STDOUT_FILENO, "^C", 2);
raise(SIGINT);
+ }
check_and_run_traps();
if (r != 0 && !G.flag_SIGINT)
break;
@@ -2232,6 +2236,7 @@ static int get_user_input(struct in_str *i)
fputs(prompt_str, stdout);
}
fflush_all();
+//FIXME: here ^C or SIGINT will have effect only after <Enter>
r = fgetc(i->file);
/* In !ENABLE_FEATURE_EDITING we don't use read_line_input,
* no ^C masking happens during fgetc, no special code for ^C: