gawk-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[SCM] gawk branch, gawk-5.1-stable, updated. gawk-4.1.0-4357-g9eb357e


From: Andrew J. Schorr
Subject: [SCM] gawk branch, gawk-5.1-stable, updated. gawk-4.1.0-4357-g9eb357e
Date: Tue, 30 Nov 2021 15:16:08 -0500 (EST)

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "gawk".

The branch, gawk-5.1-stable has been updated
       via  9eb357e008385176a44b695e6117f95b2ea104a7 (commit)
      from  5870bfcddf538fac3b87b65abc716d34766d94cf (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://git.sv.gnu.org/cgit/gawk.git/commit/?id=9eb357e008385176a44b695e6117f95b2ea104a7

commit 9eb357e008385176a44b695e6117f95b2ea104a7
Author: Andrew J. Schorr <aschorr@telemetry-investments.com>
Date:   Tue Nov 30 15:15:20 2021 -0500

    Flush output to redirections before closing to detect output errors.

diff --git a/ChangeLog b/ChangeLog
index 6dd5258..b5b21ba 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2021-11-30         Andrew J. Schorr      <aschorr@telemetry-investments.com>
+
+       Improve output redirection error handling for problems not detected
+       until the final flush or close. Thanks to Miguel Pineiro Jr.
+       <mpj@pineiro.cc> for the bug report and suggesting a fix.
+       * awk.h (efflush): Add declaration.
+       * builtin.c (efwrite): Break up into 3 functions by moving the
+       flushing logic into efflush and the error handling loginc into
+       wrerror.
+       (wrerror): New function containing the error-handling logic extracted
+       from efwrite.
+       (efflush): New function containing the fflush logic extracted from
+       efwrite.
+       * io.c (close_redir): Call efflush prior to closing the redirection
+       to identify any problems with flushing output and to take advantage
+       of the error-handling logic used for print and printf.
+
 2021-11-21         Arnold D. Robbins     <arnold@skeeve.com>
 
        * builtin.c (do_typeof): Make Node_array_ref handling smarter.
diff --git a/awk.h b/awk.h
index cb7c499..ab088f1 100644
--- a/awk.h
+++ b/awk.h
@@ -1464,6 +1464,7 @@ extern bool is_identchar(int c);
 extern NODE *make_regnode(NODETYPE type, NODE *exp);
 extern bool validate_qualified_name(char *token);
 /* builtin.c */
+extern void efflush(FILE *fp, const char *from, struct redirect *rp);
 extern double double_to_int(double d);
 extern NODE *do_exp(int nargs);
 extern NODE *do_fflush(int nargs);
diff --git a/builtin.c b/builtin.c
index 266bf74..cc17a42 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 *
diff --git a/io.c b/io.c
index 91c94d9..bcaff3c 100644
--- a/io.c
+++ b/io.c
@@ -1375,6 +1375,9 @@ close_redir(struct redirect *rp, bool exitwarn, 
two_way_close_type how)
 
        if (rp == NULL)
                return 0;
+       if ((rp->flag & RED_WRITE) && rp->output.fp)
+               /* flush before closing to leverage special error handling */
+               efflush(rp->output.fp, "flush", rp);
        if (rp->output.fp == stdout || rp->output.fp == stderr)
                goto checkwarn;         /* bypass closing, remove from list */
 

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog | 17 +++++++++++++++
 awk.h     |  1 +
 builtin.c | 73 +++++++++++++++++++++++++++++++++++++--------------------------
 io.c      |  3 +++
 4 files changed, 64 insertions(+), 30 deletions(-)


hooks/post-receive
-- 
gawk



reply via email to

[Prev in Thread] Current Thread [Next in Thread]