bc: switch to SA_RESTART signal handling
authorDenys Vlasenko <vda.linux@googlemail.com>
Tue, 4 Dec 2018 20:21:32 +0000 (21:21 +0100)
committerDenys Vlasenko <vda.linux@googlemail.com>
Wed, 5 Dec 2018 14:43:35 +0000 (15:43 +0100)
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
miscutils/bc.c

index 15089314fae8c4ac0b8485ddd8a40716da5db8a7..148e340a5c3013fe85f3febca6405652c4678368 100644 (file)
@@ -7121,7 +7121,23 @@ static BcStatus bc_vm_run(int argc, char *argv[],
 
        if (G.ttyin) {
 #if ENABLE_FEATURE_BC_SIGNALS
-               signal_no_SA_RESTART_empty_mask(SIGINT, record_signo);
+               // With SA_RESTART, most system calls will restart
+               // (IOW: they won't fail with EINTR).
+               // In particular, this means ^C won't cause
+               // stdout to get into "error state" if SIGINT hits
+               // within write() syscall.
+               // The downside is that ^C while line input is taken
+               // will only be handled after [Enter] since read()
+               // from stdin is not interrupted by ^C either,
+               // it restarts, thus fgetc() does not return on ^C.
+               signal_SA_RESTART_empty_mask(SIGINT, record_signo);
+
+               // Without SA_RESTART, this exhibits a bug:
+               // "while (1) print 1" and try ^C-ing it.
+               // Intermittently, instead of returning to input line,
+               // you'll get "output error: Interrupted system call"
+               // and exit.
+               //signal_no_SA_RESTART_empty_mask(SIGINT, record_signo);
 #endif
                if (!(option_mask32 & BC_FLAG_Q))
                        bc_vm_info();