diff options
author | Ron Yorston <rmy@pobox.com> | 2018-12-11 15:52:31 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2018-12-11 15:52:31 +0000 |
commit | 68ddd4ec3c1275c66e01172498055817cbb10f04 (patch) | |
tree | e31826ae839535bef102a7ad61bc0e029b20ffae /win32 | |
parent | 6c3fd20e67cab2331b1e862c03eeb95a70625454 (diff) | |
download | busybox-w32-68ddd4ec3c1275c66e01172498055817cbb10f04.tar.gz busybox-w32-68ddd4ec3c1275c66e01172498055817cbb10f04.tar.bz2 busybox-w32-68ddd4ec3c1275c66e01172498055817cbb10f04.zip |
win32: emulate SIGPIPE
The code to check whether a write error is due to a broken pipe
can now either:
- return with error EPIPE;
- cause the process to exit with code 128+SIGPIPE.
The default is the latter but the behaviour can be changed by issuing
signal(SIGPIPE, SIG_IGN) and signal(SIGPIPE, SIG_DFL) calls.
No actual signal is involved so kill can't send SIGPIPE and handlers
other than SIG_IGN and SIG_DFL aren't supported.
This does, however, avoid unsightly 'broken pipe' errors from commands
like the example in GitHub issue #99:
dd if=/dev/urandom | tr -dc _A-Z-a-z-0-9 | head -c${1:-32};echo;
Diffstat (limited to 'win32')
-rw-r--r-- | win32/winansi.c | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/win32/winansi.c b/win32/winansi.c index a8f5dba79..167b4b0b1 100644 --- a/win32/winansi.c +++ b/win32/winansi.c | |||
@@ -475,12 +475,32 @@ int winansi_puts(const char *s) | |||
475 | return (winansi_fputs(s, stdout) == EOF || putchar('\n') == EOF) ? EOF : 0; | 475 | return (winansi_fputs(s, stdout) == EOF || putchar('\n') == EOF) ? EOF : 0; |
476 | } | 476 | } |
477 | 477 | ||
478 | static sighandler_t sigpipe_handler = SIG_DFL; | ||
479 | |||
480 | #undef signal | ||
481 | sighandler_t winansi_signal(int signum, sighandler_t handler) | ||
482 | { | ||
483 | sighandler_t old; | ||
484 | |||
485 | if (signum == SIGPIPE) { | ||
486 | old = sigpipe_handler; | ||
487 | sigpipe_handler = handler; | ||
488 | return old; | ||
489 | } | ||
490 | return signal(signum, handler); | ||
491 | } | ||
492 | |||
478 | static void check_pipe_fd(int fd) | 493 | static void check_pipe_fd(int fd) |
479 | { | 494 | { |
480 | if (GetLastError() == ERROR_NO_DATA) { | 495 | int error = GetLastError(); |
481 | if (GetFileType((HANDLE)_get_osfhandle(fd)) == FILE_TYPE_PIPE) { | 496 | |
497 | if ((error == ERROR_NO_DATA && | ||
498 | GetFileType((HANDLE)_get_osfhandle(fd)) == FILE_TYPE_PIPE) || | ||
499 | error == ERROR_BROKEN_PIPE) { | ||
500 | if (sigpipe_handler == SIG_DFL) | ||
501 | exit(128+SIGPIPE); | ||
502 | else /* SIG_IGN */ | ||
482 | errno = EPIPE; | 503 | errno = EPIPE; |
483 | } | ||
484 | } | 504 | } |
485 | } | 505 | } |
486 | 506 | ||