diff --git a/awk.h b/awk.h index 8e38976d..08ef36c1 100644 --- a/awk.h +++ b/awk.h @@ -1668,8 +1668,7 @@ extern bool inrec(IOBUF *iop, int *errcode); extern int nextfile(IOBUF **curfile, bool skipping); extern bool is_non_fatal_std(FILE *fp); extern bool is_non_fatal_redirect(const char *str, size_t len); -extern void ignore_sigpipe(void); -extern void set_sigpipe_to_default(void); +extern void do_nothing_on_signal(int sig); extern bool non_fatal_flush_std_file(FILE *fp); extern size_t gawk_fwrite(const void *buf, size_t size, size_t count, FILE *fp, void *opaque); @@ -2160,9 +2159,11 @@ str_terminate_f(NODE *n, char *savep) #define ignore_sigpipe() signal(SIGPIPE, SIG_IGN) #define set_sigpipe_to_default() signal(SIGPIPE, SIG_DFL) #define die_via_sigpipe() (signal(SIGPIPE, SIG_DFL), kill(getpid(), SIGPIPE)) +#define silent_catch_sigpipe() signal(SIGPIPE, do_nothing_on_signal) #else #define ignore_sigpipe() #define set_sigpipe_to_default() +#define silent_catch_sigpipe() #ifdef __MINGW32__ /* 0xC0000008 is EXCEPTION_INVALID_HANDLE, somewhat appropriate for EPIPE */ #define die_via_sigpipe() exit(0xC0000008) diff --git a/builtin.c b/builtin.c index 6fc76b72..84a0dff5 100644 --- a/builtin.c +++ b/builtin.c @@ -2269,7 +2269,7 @@ do_system(int nargs) cmd[tmp->stlen] = '\0'; os_restore_mode(fileno(stdin)); - set_sigpipe_to_default(); + silent_catch_sigpipe(); status = system(cmd); /* diff --git a/io.c b/io.c index c595c009..dcddbf4f 100644 --- a/io.c +++ b/io.c @@ -946,7 +946,7 @@ redirect_string(const char *str, size_t explen, bool not_string, (void) flush_io(); os_restore_mode(fileno(stdin)); - set_sigpipe_to_default(); + silent_catch_sigpipe(); /* * Don't check failure_fatal; see input pipe below. * Note that the failure happens upon failure to fork, @@ -2768,7 +2768,7 @@ gawk_popen(const char *cmd, struct redirect *rp) FILE *current; os_restore_mode(fileno(stdin)); - set_sigpipe_to_default(); + silent_catch_sigpipe(); current = popen(cmd, binmode("r")); @@ -4587,3 +4587,19 @@ avoid_flush(const char *name) return in_PROCINFO(bufferpipe, NULL, NULL) != NULL || in_PROCINFO(name, bufferpipe, NULL) != NULL; } + +/* do_nothing_on_signal --- empty signal catcher for SIGPIPE */ + +/* + * See the thread starting at + * https://lists.gnu.org/archive/html/bug-gawk/2023-12/msg00011.html. + * + * The hope is that by using this do-nothing function to catch + * SIGPIPE, instead of setting it to default, that when race conditions + * occur, gawk won't fatal out. + */ + +void +do_nothing_on_signal(int sig) +{ +}