aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2017-08-01 19:30:34 +0100
committerRon Yorston <rmy@pobox.com>2017-08-01 19:30:34 +0100
commit2a210715a9a85fb48cf8f636c74e63f54605eedc (patch)
tree4e9f3a721abfeea361a85405084e3e3d8397f971
parent3269a81ce20fcdc4bfb196f45585a3c632896f05 (diff)
downloadbusybox-w32-2a210715a9a85fb48cf8f636c74e63f54605eedc.tar.gz
busybox-w32-2a210715a9a85fb48cf8f636c74e63f54605eedc.tar.bz2
busybox-w32-2a210715a9a85fb48cf8f636c74e63f54605eedc.zip
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.
-rw-r--r--shell/ash.c4
1 files changed, 4 insertions, 0 deletions
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)
4306{ 4306{
4307 if (dwCtrlType == CTRL_C_EVENT || dwCtrlType == CTRL_BREAK_EVENT) { 4307 if (dwCtrlType == CTRL_C_EVENT || dwCtrlType == CTRL_BREAK_EVENT) {
4308 SetEvent(hSIGINT); 4308 SetEvent(hSIGINT);
4309 pending_int = 1;
4309 return TRUE; 4310 return TRUE;
4310 } 4311 }
4311 return FALSE; 4312 return FALSE;
@@ -4369,6 +4370,7 @@ waitpid_child(int *status, int wait_flags)
4369 if (!idx) { /* hSIGINT */ 4370 if (!idx) { /* hSIGINT */
4370 int i; 4371 int i;
4371 ResetEvent(hSIGINT); 4372 ResetEvent(hSIGINT);
4373 pending_int = 0;
4372 for (i = 1; i < pid_nr; i++) 4374 for (i = 1; i < pid_nr; i++)
4373 TerminateProcess(proclist[i], 1); 4375 TerminateProcess(proclist[i], 1);
4374 pid = pidlist[1]; 4376 pid = pidlist[1];
@@ -10282,6 +10284,7 @@ evalcommand(union node *cmd, int flags)
10282 /* No, forking off a child is necessary */ 10284 /* No, forking off a child is necessary */
10283 struct forkshell fs; 10285 struct forkshell fs;
10284 10286
10287 INT_OFF;
10285 memset(&fs, 0, sizeof(fs)); 10288 memset(&fs, 0, sizeof(fs));
10286 fs.fpid = FS_SHELLEXEC; 10289 fs.fpid = FS_SHELLEXEC;
10287 fs.argv = argv; 10290 fs.argv = argv;
@@ -14492,6 +14495,7 @@ forkshell_shellexec(struct forkshell *fs)
14492 char **argv = fs->argv; 14495 char **argv = fs->argv;
14493 char *path = fs->string; 14496 char *path = fs->string;
14494 14497
14498 FORCE_INT_ON;
14495 listsetvar(varlist, VEXPORT|VSTACK); 14499 listsetvar(varlist, VEXPORT|VSTACK);
14496 shellexec(argv[0], argv, path, idx); 14500 shellexec(argv[0], argv, path, idx);
14497} 14501}