diff options
-rw-r--r-- | ChangeLog | 12 | ||||
-rw-r--r-- | awk.h | 2 | ||||
-rw-r--r-- | debug.c | 4 | ||||
-rw-r--r-- | interpret.h | 6 | ||||
-rw-r--r-- | io.c | 9 |
5 files changed, 28 insertions, 5 deletions
@@ -1,3 +1,15 @@ +2018-06-17 Arnold D. Robbins <arnold@skeeve.com> + + Fix a corner case with EPIPE to stdout/stderr. + Thanks to Peng Yu for the report. + + * io.c (close_io): Add new parameter for indicating EPIPE happened, + update the code to set it if so. + * awk.h (close_io): Revise declaration. + * debug.c (close_all): Change call to close_io(). + * interpret.h (interpret): For Op_atexit, if got an EPIPE, call + die_via_sigpipe(). + 2018-05-24 Arnold D. Robbins <arnold@skeeve.com> * awkgram.y (add_lint): For no-effect case, also check for @@ -1574,7 +1574,7 @@ extern struct redirect *redirect_string(const char *redir_exp_str, int *errflg, int extfd, bool failure_fatal); extern NODE *do_close(int nargs); extern int flush_io(void); -extern int close_io(bool *stdio_problem); +extern int close_io(bool *stdio_problem, bool *got_EPIPE); typedef enum { CLOSE_ALL, CLOSE_TO, CLOSE_FROM } two_way_close_type; extern int close_rp(struct redirect *rp, two_way_close_type how); extern int devopen_simple(const char *name, const char *mode, bool try_real_open); @@ -5405,11 +5405,11 @@ save_options(const char *file) static void close_all() { - bool stdio_problem; + bool stdio_problem, got_EPIPE; struct command_source *cs; (void) nextfile(& curfile, true); /* close input data file */ - (void) close_io(& stdio_problem); + (void) close_io(& stdio_problem, & got_EPIPE); if (cur_srcfile->fd != INVALID_HANDLE) { close(cur_srcfile->fd); cur_srcfile->fd = INVALID_HANDLE; diff --git a/interpret.h b/interpret.h index 20fcb7ad..8408a532 100644 --- a/interpret.h +++ b/interpret.h @@ -110,6 +110,7 @@ top: case Op_atexit: { bool stdio_problem = false; + bool got_EPIPE = false; /* avoid false source indications */ source = NULL; @@ -125,7 +126,7 @@ top: * and pipes, in that it doesn't affect their exit status. * So we no longer do either. */ - (void) close_io(& stdio_problem); + (void) close_io(& stdio_problem, & got_EPIPE); /* * However, we do want to exit non-zero if there was a problem * with stdout/stderr, so we reinstate a slightly different @@ -135,6 +136,9 @@ top: exit_val = 1; close_extensions(); + + if (got_EPIPE) + die_via_sigpipe(); } break; @@ -1474,12 +1474,13 @@ flush_io() /* close_io --- close all open files, called when exiting */ int -close_io(bool *stdio_problem) +close_io(bool *stdio_problem, bool *got_EPIPE) { struct redirect *rp; struct redirect *next; int status = 0; + *stdio_problem = *got_EPIPE = false; errno = 0; for (rp = red_head; rp != NULL; rp = next) { next = rp->next; @@ -1505,6 +1506,9 @@ close_io(bool *stdio_problem) #endif if (errno != EPIPE) warning(_("error writing standard output (%s)"), strerror(errno)); + else + *got_EPIPE = true; + status++; *stdio_problem = true; } @@ -1515,6 +1519,9 @@ close_io(bool *stdio_problem) #endif if (errno != EPIPE) warning(_("error writing standard error (%s)"), strerror(errno)); + else + *got_EPIPE = true; + status++; *stdio_problem = true; } |