From 9eb357e008385176a44b695e6117f95b2ea104a7 Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Tue, 30 Nov 2021 15:15:20 -0500 Subject: Flush output to redirections before closing to detect output errors. --- builtin.c | 73 +++++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 43 insertions(+), 30 deletions(-) (limited to 'builtin.c') diff --git a/builtin.c b/builtin.c index 266bf74a..cc17a42f 100644 --- a/builtin.c +++ b/builtin.c @@ -96,39 +96,12 @@ fatal(_("attempt to use array `%s' in a scalar context"), array_vname(s1)); \ */ #define GAWK_RANDOM_MAX 0x7fffffffL -/* efwrite --- like fwrite, but with error checking */ + +/* wrerror --- handle a write or flush error */ static void -efwrite(const void *ptr, - size_t size, - size_t count, - FILE *fp, - const char *from, - struct redirect *rp, - bool flush) +wrerror(FILE *fp, const char *from, struct redirect *rp) { - errno = 0; - if (rp != NULL) { - if (rp->output.gawk_fwrite(ptr, size, count, fp, rp->output.opaque) != count) - goto wrerror; - } else if (fwrite(ptr, size, count, fp) != count) - goto wrerror; - if (flush - && ((fp == stdout && output_is_tty) - || (rp != NULL && (rp->flag & RED_NOBUF) != 0))) { - if (rp != NULL) { - rp->output.gawk_fflush(fp, rp->output.opaque); - if (rp->output.gawk_ferror(fp, rp->output.opaque)) - goto wrerror; - } else { - fflush(fp); - if (ferror(fp)) - goto wrerror; - } - } - return; - -wrerror: #ifdef __MINGW32__ if (errno == 0 || errno == EINVAL) w32_maybe_set_errno(); @@ -150,6 +123,46 @@ wrerror: errno ? strerror(errno) : _("reason unknown")); } +/* efflush --- flush output with proper error handling */ + +void +efflush(FILE *fp, const char *from, struct redirect *rp) +{ + errno = 0; + if (rp != NULL) { + rp->output.gawk_fflush(fp, rp->output.opaque); + if (rp->output.gawk_ferror(fp, rp->output.opaque)) + return wrerror(fp, from, rp); + } else { + fflush(fp); + if (ferror(fp)) + return wrerror(fp, from, rp); + } +} + +/* efwrite --- like fwrite, but with error checking */ + +static void +efwrite(const void *ptr, + size_t size, + size_t count, + FILE *fp, + const char *from, + struct redirect *rp, + bool flush) +{ + errno = 0; + if (rp != NULL) { + if (rp->output.gawk_fwrite(ptr, size, count, fp, rp->output.opaque) != count) + return wrerror(fp, from, rp); + } else if (fwrite(ptr, size, count, fp) != count) + return wrerror(fp, from, rp); + if (flush + && ((fp == stdout && output_is_tty) + || (rp != NULL && (rp->flag & RED_NOBUF) != 0))) + efflush(fp, from, rp); +} + /* do_exp --- exponential function */ NODE * -- cgit v1.2.3 From 4285d605b8c0cbe4e0b15724af1b4bd223f25403 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Wed, 1 Dec 2021 22:33:47 +0200 Subject: Don't use return in a call to a void function. --- builtin.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'builtin.c') diff --git a/builtin.c b/builtin.c index cc17a42f..766f7ceb 100644 --- a/builtin.c +++ b/builtin.c @@ -132,11 +132,11 @@ efflush(FILE *fp, const char *from, struct redirect *rp) if (rp != NULL) { rp->output.gawk_fflush(fp, rp->output.opaque); if (rp->output.gawk_ferror(fp, rp->output.opaque)) - return wrerror(fp, from, rp); + wrerror(fp, from, rp); } else { fflush(fp); if (ferror(fp)) - return wrerror(fp, from, rp); + wrerror(fp, from, rp); } } -- cgit v1.2.3 From f77e1318c515d495ac9c08bdfdf2dadf79a9649f Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Wed, 1 Dec 2021 22:42:07 +0200 Subject: Convert w32_maybe_set_errno to os_maybe_set_errno. --- builtin.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'builtin.c') diff --git a/builtin.c b/builtin.c index 766f7ceb..d77d276e 100644 --- a/builtin.c +++ b/builtin.c @@ -102,10 +102,8 @@ fatal(_("attempt to use array `%s' in a scalar context"), array_vname(s1)); \ static void wrerror(FILE *fp, const char *from, struct redirect *rp) { -#ifdef __MINGW32__ - if (errno == 0 || errno == EINVAL) - w32_maybe_set_errno(); -#endif + os_maybe_set_errno(); + /* for stdout, die with a real SIGPIPE, like other awks */ if (fp == stdout && errno == EPIPE) die_via_sigpipe(); -- cgit v1.2.3