ash,hush: ^C from command line should set $? to 128+SIGINT
authorDenys Vlasenko <vda.linux@googlemail.com>
Thu, 24 Nov 2016 16:44:02 +0000 (17:44 +0100)
committerDenys Vlasenko <vda.linux@googlemail.com>
Thu, 24 Nov 2016 16:44:02 +0000 (17:44 +0100)
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
shell/ash.c
shell/hush.c

index 15246f55f78ce2e238f7343dc2fc5b0684b055e4..3e5a3b3e9ec5c9774fc1e8c412d0beebd199b000 100644 (file)
@@ -9876,6 +9876,7 @@ preadfd(void)
                                raise(SIGINT);
                                return 1;
                        }
+                       exitstatus = 128 + SIGINT;
                        goto retry;
                }
                if (nr < 0) {
index 2f07f4ac1392afbbc8744f314385bda5efd1af93..5b720ce98921387f66edc9f02cb844e73cbbb509 100644 (file)
@@ -1746,6 +1746,7 @@ static int check_and_run_traps(void)
                                argv[2] = NULL;
                                save_rcode = G.last_exitcode;
                                builtin_eval(argv);
+//FIXME: shouldn't it be set to 128 + sig instead?
                                G.last_exitcode = save_rcode;
                                last_sig = sig;
                        } /* else: "" trap, ignoring signal */
@@ -2192,7 +2193,7 @@ static int get_user_input(struct in_str *i)
 
        prompt_str = setup_prompt_string(i->promptmode);
 # if ENABLE_FEATURE_EDITING
-       do {
+       for (;;) {
                reinit_unicode_for_hush();
                G.flag_SIGINT = 0;
                /* buglet: SIGINT will not make new prompt to appear _at once_,
@@ -2201,9 +2202,15 @@ static int get_user_input(struct in_str *i)
                                G.user_input_buf, CONFIG_FEATURE_EDITING_MAX_LEN-1,
                                /*timeout*/ -1
                );
-               /* catch *SIGINT* etc (^C is handled by read_line_input) */
+               /* read_line_input intercepts ^C, "convert" it into SIGINT */
+               if (r == 0)
+                       raise(SIGINT);
                check_and_run_traps();
-       } while (r == 0 || G.flag_SIGINT); /* repeat if ^C or SIGINT */
+               if (r != 0 && !G.flag_SIGINT)
+                       break;
+               /* ^C or SIGINT: repeat */
+               G.last_exitcode = 128 + SIGINT;
+       }
        if (r < 0) {
                /* EOF/error detected */
                i->p = NULL;
@@ -2213,7 +2220,7 @@ static int get_user_input(struct in_str *i)
        i->p = G.user_input_buf;
        return (unsigned char)*i->p++;
 # else
-       do {
+       for (;;) {
                G.flag_SIGINT = 0;
                if (i->last_char == '\0' || i->last_char == '\n') {
                        /* Why check_and_run_traps here? Try this interactively:
@@ -2226,7 +2233,16 @@ static int get_user_input(struct in_str *i)
                }
                fflush_all();
                r = fgetc(i->file);
-       } while (G.flag_SIGINT || r == '\0');
+               /* In !ENABLE_FEATURE_EDITING we don't use read_line_input,
+                * no ^C masking happens during fgetc, no special code for ^C:
+                * it generates SIGINT as usual.
+                */
+               check_and_run_traps();
+               if (G.flag_SIGINT)
+                       G.last_exitcode = 128 + SIGINT;
+               if (r != '\0')
+                       break;
+       }
        return r;
 # endif
 }