From 2a210715a9a85fb48cf8f636c74e63f54605eedc Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Tue, 1 Aug 2017 19:30:34 +0100 Subject: ash: improve performance of ctrl-c The WIN32 port uses a console control handler to detect crtl-c. This replaces the signal handler used in POSIX. The control handler sets an event that can be detected in waitpid_child. However this only works when a wait is in progress, which makes it impossible to break out of a simple shell loop with ctrl-c: while true; do sleep 1 echo hi done Better performance can be achieved by setting the pending_int flag in the control handler, similar to what's done in the signal handler. The deferred signal is processed in int_on. Or at least it would be but for a bug in the WIN32 code to handle shellexec: interrupts weren't being properly turned off and on. So this had to be fixed too. --- shell/ash.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'shell') diff --git a/shell/ash.c b/shell/ash.c index b71c749aa..441da4d85 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -4306,6 +4306,7 @@ static BOOL WINAPI ctrl_handler(DWORD dwCtrlType) { if (dwCtrlType == CTRL_C_EVENT || dwCtrlType == CTRL_BREAK_EVENT) { SetEvent(hSIGINT); + pending_int = 1; return TRUE; } return FALSE; @@ -4369,6 +4370,7 @@ waitpid_child(int *status, int wait_flags) if (!idx) { /* hSIGINT */ int i; ResetEvent(hSIGINT); + pending_int = 0; for (i = 1; i < pid_nr; i++) TerminateProcess(proclist[i], 1); pid = pidlist[1]; @@ -10282,6 +10284,7 @@ evalcommand(union node *cmd, int flags) /* No, forking off a child is necessary */ struct forkshell fs; + INT_OFF; memset(&fs, 0, sizeof(fs)); fs.fpid = FS_SHELLEXEC; fs.argv = argv; @@ -14492,6 +14495,7 @@ forkshell_shellexec(struct forkshell *fs) char **argv = fs->argv; char *path = fs->string; + FORCE_INT_ON; listsetvar(varlist, VEXPORT|VSTACK); shellexec(argv[0], argv, path, idx); } -- cgit v1.2.3-55-g6feb