aboutsummaryrefslogtreecommitdiffstats
path: root/builtin.c
diff options
context:
space:
mode:
authorAndrew J. Schorr <aschorr@telemetry-investments.com>2021-11-30 15:15:20 -0500
committerAndrew J. Schorr <aschorr@telemetry-investments.com>2021-11-30 15:15:20 -0500
commit9eb357e008385176a44b695e6117f95b2ea104a7 (patch)
tree84c94e9ff50ca39b3e139c1dc3c7d1310903bd5a /builtin.c
parent5870bfcddf538fac3b87b65abc716d34766d94cf (diff)
downloadegawk-9eb357e008385176a44b695e6117f95b2ea104a7.tar.gz
egawk-9eb357e008385176a44b695e6117f95b2ea104a7.tar.bz2
egawk-9eb357e008385176a44b695e6117f95b2ea104a7.zip
Flush output to redirections before closing to detect output errors.
Diffstat (limited to 'builtin.c')
-rw-r--r--builtin.c73
1 files changed, 43 insertions, 30 deletions
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 *