summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArnold D. Robbins <arnold@skeeve.com>2017-03-24 10:05:21 +0300
committerArnold D. Robbins <arnold@skeeve.com>2017-03-24 10:05:21 +0300
commitbc97284df48d79d57450aae746c08f8d55d3a57a (patch)
tree0a33796a21ef3102563f7ff28f9198f10cecf6e7
parent10c17fe33a10746bd44fc4b62f764ca4c3f3c5a6 (diff)
downloadgawk-bc97284df48d79d57450aae746c08f8d55d3a57a.tar.gz
Improve handling of flushing for non-fatal files.
-rw-r--r--ChangeLog10
-rw-r--r--builtin.c13
-rw-r--r--io.c19
3 files changed, 33 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index 3cf9ddab..ae69b7e2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2017-03-24 Arnold D. Robbins <arnold@skeeve.com>
+
+ * builtin.c (efwrite): Exit successfully upon EPIPE, as SIGPIPE
+ done. Improve error messages upon failure to write.
+ (do_fflush): Update ERRNO for non-fatal flush failures.
+ * io.c (non_fatal_flush_std_file): Update ERRNO when flush is
+ non-fatal.
+ (flush_io): If a redirect is marked non-fatal, only warning,
+ not fatal message.
+
2017-03-23 Arnold D. Robbins <arnold@skeeve.com>
* config.sub: Updated again.
diff --git a/builtin.c b/builtin.c
index b92eb19d..0f2c62f8 100644
--- a/builtin.c
+++ b/builtin.c
@@ -131,14 +131,18 @@ wrerror:
#endif
/* die silently on EPIPE to stdout */
if (fp == stdout && errno == EPIPE)
- gawk_exit(EXIT_FATAL);
+ gawk_exit(EXIT_SUCCESS); // a la SIGPIPE
/* otherwise die verbosely */
if ((rp != NULL) ? is_non_fatal_redirect(rp->value, strlen(rp->value)) : is_non_fatal_std(fp))
update_ERRNO_int(errno);
else
fatal(_("%s to \"%s\" failed (%s)"), from,
- rp ? rp->value : _("standard output"),
+ rp != NULL
+ ? rp->value
+ : fp == stdout
+ ? _("standard output")
+ : _("standard error"),
errno ? strerror(errno) : _("reason unknown"));
}
@@ -214,7 +218,7 @@ do_fflush(int nargs)
/* fflush() */
if (nargs == 0) {
- status = flush_io();
+ status = flush_io(); // ERRNO updated
return make_number((AWKNUM) status);
}
@@ -224,7 +228,7 @@ do_fflush(int nargs)
/* fflush("") */
if (tmp->stlen == 0) {
- status = flush_io();
+ status = flush_io(); // ERRNO updated
DEREF(tmp);
return make_number((AWKNUM) status);
}
@@ -251,6 +255,7 @@ do_fflush(int nargs)
if (! is_non_fatal_redirect(tmp->stptr, tmp->stlen))
fatal(_("fflush: cannot flush file `%.*s': %s"),
len, file, strerror(errno));
+ update_ERRNO_int(errno);
}
} else if ((rp->flag & RED_TWOWAY) != 0)
warning(_("fflush: cannot flush: two-way pipe `%.*s' has closed write end"),
diff --git a/io.c b/io.c
index 0da27575..00a0ba3c 100644
--- a/io.c
+++ b/io.c
@@ -1407,6 +1407,7 @@ non_fatal_flush_std_file(FILE *fp)
: _("fflush: cannot flush standard error: %s"),
strerror(errno));
} else {
+ update_ERRNO_int(errno);
warning(fp == stdout
? _("error writing standard output (%s)")
: _("error writing standard error (%s)"),
@@ -1427,26 +1428,34 @@ flush_io()
int status = 0;
errno = 0;
- if (! non_fatal_flush_std_file(stdout))
+ if (! non_fatal_flush_std_file(stdout)) // ERRNO updated
status++;
errno = 0;
- if (! non_fatal_flush_std_file(stderr))
+ if (! non_fatal_flush_std_file(stderr)) // ERRNO updated
status++;
+
// now for all open redirections
for (rp = red_head; rp != NULL; rp = rp->next) {
+ void (*messagefunc)(const char *mesg, ...) = fatal;
+
/* flush both files and pipes, what the heck */
if ((rp->flag & RED_WRITE) != 0 && rp->output.fp != NULL) {
if (rp->output.gawk_fflush(rp->output.fp, rp->output.opaque) != 0) {
+ update_ERRNO_int(errno);
+
+ if (is_non_fatal_redirect(rp->value, strlen(rp->value)))
+ messagefunc = warning;
+
if ((rp->flag & RED_PIPE) != 0)
- warning(_("pipe flush of `%s' failed (%s)."),
+ messagefunc(_("pipe flush of `%s' failed (%s)."),
rp->value, strerror(errno));
else if ((rp->flag & RED_TWOWAY) != 0)
- warning(_("co-process flush of pipe to `%s' failed (%s)."),
+ messagefunc(_("co-process flush of pipe to `%s' failed (%s)."),
rp->value, strerror(errno));
else
- warning(_("file flush of `%s' failed (%s)."),
+ messagefunc(_("file flush of `%s' failed (%s)."),
rp->value, strerror(errno));
status++;
}