diff options
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | awk.h | 2 | ||||
-rw-r--r-- | builtin.c | 4 | ||||
-rw-r--r-- | io.c | 2 | ||||
-rw-r--r-- | main.c | 5 |
5 files changed, 18 insertions, 4 deletions
@@ -1,3 +1,12 @@ +2017-03-27 Arnold D. Robbins <arnold@skeeve.com> + + Cause EPIPE errors to stdout to generate a real SIGPIPE. + + * awk.h (die_via_sigpipe): New macro. + * builtin.c (efwrite): Use it. + * io.c (non_fatal_flush_std_file): Ditto. + * main.c (usage): Ditto. + 2017-03-25 Arnold D. Robbins <arnold@skeeve.com> * io.c (flush_io): Use r_fatal and r_warning for messagefunc @@ -1966,7 +1966,9 @@ erealloc_real(void *ptr, size_t count, const char *where, const char *var, const #ifdef SIGPIPE #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)) #else #define ignore_sigpipe() #define set_sigpipe_to_default() +#define die_via_sigpipe() exit(EXIT_FATAL) #endif @@ -129,9 +129,9 @@ wrerror: if (errno == 0 || errno == EINVAL) w32_maybe_set_errno(); #endif - /* die silently on EPIPE to stdout */ + /* for stdout, die with a real SIGPIPE, like other awks */ if (fp == stdout && errno == EPIPE) - gawk_exit(EXIT_SUCCESS); // a la SIGPIPE + die_via_sigpipe(); /* otherwise die verbosely */ if ((rp != NULL) ? is_non_fatal_redirect(rp->value, strlen(rp->value)) : is_non_fatal_std(fp)) @@ -1400,7 +1400,7 @@ non_fatal_flush_std_file(FILE *fp) if (is_fatal) { if (errno == EPIPE) - exit(EXIT_SUCCESS); // simulate SIGPIPE + die_via_sigpipe(); else fatal(fp == stdout ? _("fflush: cannot flush standard output: %s") @@ -633,7 +633,10 @@ By default it reads standard input and writes standard output.\n\n"), fp); warning(_("error writing standard output (%s)"), strerror(errno)); else if (fp == stderr) warning(_("error writing standard error (%s)"), strerror(errno)); - } + } else if (errno == SIGPIPE) + die_via_sigpipe(); + + // some other problem than SIGPIPE exit(EXIT_FAILURE); } |