diff options
author | Ron Yorston <rmy@pobox.com> | 2017-08-01 19:30:34 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2017-08-01 19:30:34 +0100 |
commit | 2a210715a9a85fb48cf8f636c74e63f54605eedc (patch) | |
tree | 4e9f3a721abfeea361a85405084e3e3d8397f971 | |
parent | 3269a81ce20fcdc4bfb196f45585a3c632896f05 (diff) | |
download | busybox-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.c | 4 |
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 | } |