aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnold D. Robbins <arnold@skeeve.com>2016-04-07 21:46:44 +0300
committerArnold D. Robbins <arnold@skeeve.com>2016-04-07 21:46:44 +0300
commit658ede8ca657fe56c7ea6b0a3a1bd89fb858d26d (patch)
tree928465fc4f72e2467451cf774d8dd96fdb958927
parent82dec6932ed868d9466d23ac5956e09594707dd2 (diff)
downloadegawk-658ede8ca657fe56c7ea6b0a3a1bd89fb858d26d.tar.gz
egawk-658ede8ca657fe56c7ea6b0a3a1bd89fb858d26d.tar.bz2
egawk-658ede8ca657fe56c7ea6b0a3a1bd89fb858d26d.zip
Fix race condition in fatal errors for one end closed on two way pipe.
-rw-r--r--ChangeLog11
-rw-r--r--awk.h2
-rw-r--r--builtin.c3
-rw-r--r--io.c5
-rw-r--r--test/ChangeLog5
-rw-r--r--test/clos1way2.ok4
-rw-r--r--test/clos1way3.ok4
-rw-r--r--test/clos1way4.ok4
8 files changed, 29 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index d25772c6..00dda864 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2016-04-07 Arnold D. Robbins <arnold@skeeve.com>
+
+ * awk.h (two_way_close_type): Move here from io.c.
+ (close_rp): Add declaration.
+ * builtin.c (do_printf): Call close_rp before fatal message when
+ attempting to write the closed write end of a two way pipe.
+ (do_print): Ditto.
+ (do_print_rec): Ditto.
+ * io.c (do_getline_redir): Same, for reading closed read end.
+ (close_rp): Make not static.
+
2016-04-07 Eli Zaretskii <eliz@gnu.org>
* nonposix.h (WEXITSTATUS, WIFEXITED, WIFSIGNALED, WTERMSIG)
diff --git a/awk.h b/awk.h
index c74c6881..86c8883d 100644
--- a/awk.h
+++ b/awk.h
@@ -1501,6 +1501,8 @@ extern struct redirect *redirect(NODE *redir_exp, int redirtype, int *errflg);
extern NODE *do_close(int nargs);
extern int flush_io(void);
extern int close_io(bool *stdio_problem);
+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);
extern int devopen(const char *name, const char *mode);
extern int srcopen(SRCFILE *s);
diff --git a/builtin.c b/builtin.c
index 8aee1177..108bcb89 100644
--- a/builtin.c
+++ b/builtin.c
@@ -1669,6 +1669,7 @@ do_printf(int nargs, int redirtype)
rp = redirect(redir_exp, redirtype, & errflg);
if (rp != NULL) {
if ((rp->flag & RED_TWOWAY) != 0 && rp->output.fp == NULL) {
+ (void) close_rp(rp, CLOSE_ALL);
fatal(_("printf: attempt to write to closed write end of two-way pipe"));
}
fp = rp->output.fp;
@@ -2149,6 +2150,7 @@ do_print(int nargs, int redirtype)
rp = redirect(redir_exp, redirtype, & errflg);
if (rp != NULL) {
if ((rp->flag & RED_TWOWAY) != 0 && rp->output.fp == NULL) {
+ (void) close_rp(rp, CLOSE_ALL);
fatal(_("print: attempt to write to closed write end of two-way pipe"));
}
fp = rp->output.fp;
@@ -2217,6 +2219,7 @@ do_print_rec(int nargs, int redirtype)
rp = redirect(redir_exp, redirtype, & errflg);
if (rp != NULL) {
if ((rp->flag & RED_TWOWAY) != 0 && rp->output.fp == NULL) {
+ (void) close_rp(rp, CLOSE_ALL);
fatal(_("print: attempt to write to closed write end of two-way pipe"));
}
fp = rp->output.fp;
diff --git a/io.c b/io.c
index fe1261aa..3a5748b2 100644
--- a/io.c
+++ b/io.c
@@ -212,8 +212,6 @@
#define INCREMENT_REC(X) X++
#endif
-typedef enum { CLOSE_ALL, CLOSE_TO, CLOSE_FROM } two_way_close_type;
-
/* Several macros to make the code a bit clearer. */
#define at_eof(iop) (((iop)->flag & IOP_AT_EOF) != 0)
#define has_no_data(iop) ((iop)->dataend == NULL)
@@ -1170,7 +1168,7 @@ do_close(int nargs)
/* close_rp --- separate function to just do closing */
-static int
+int
close_rp(struct redirect *rp, two_way_close_type how)
{
int status = 0;
@@ -2475,6 +2473,7 @@ do_getline_redir(int into_variable, enum redirval redirtype)
}
return make_number((AWKNUM) -1.0);
} else if ((rp->flag & RED_TWOWAY) != 0 && rp->iop == NULL) {
+ (void) close_rp(rp, CLOSE_ALL);
fatal(_("getline: attempt to read from closed read end of two-way pipe"));
}
iop = rp->iop;
diff --git a/test/ChangeLog b/test/ChangeLog
index 2867f6cb..bf40d8a6 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -1,3 +1,8 @@
+2016-04-07 Arnold D. Robbins <arnold@skeeve.com>
+
+ * clos1way2.ok, clos1way3.ok, clos1way4.ok: Updated after
+ code changes.
+
2016-04-04 Arnold D. Robbins <arnold@skeeve.com>
* Makefile.am (clos1way2, clos1way3, clos1way4, clos1way5):
diff --git a/test/clos1way2.ok b/test/clos1way2.ok
index 063c4213..67240ac9 100644
--- a/test/clos1way2.ok
+++ b/test/clos1way2.ok
@@ -1,4 +1,4 @@
gawk: clos1way2.awk:4: (FILENAME=- FNR=1) warning: fflush: cannot flush: two-way pipe `cat - 1>&2; sleep 2' has closed write end
-gawk: clos1way2.awk:5: (FILENAME=- FNR=1) fatal: print: attempt to write to closed write end of two-way pipe
test
-CODE: 2
+gawk: clos1way2.awk:5: (FILENAME=- FNR=1) fatal: print: attempt to write to closed write end of two-way pipe
+EXIT CODE: 2
diff --git a/test/clos1way3.ok b/test/clos1way3.ok
index 74f67738..b0157fa1 100644
--- a/test/clos1way3.ok
+++ b/test/clos1way3.ok
@@ -1,3 +1,3 @@
-gawk: clos1way3.awk:5: fatal: print: attempt to write to closed write end of two-way pipe
test1
-ODE: 2
+gawk: clos1way3.awk:5: fatal: print: attempt to write to closed write end of two-way pipe
+EXIT CODE: 2
diff --git a/test/clos1way4.ok b/test/clos1way4.ok
index 707f9813..e30aa7f6 100644
--- a/test/clos1way4.ok
+++ b/test/clos1way4.ok
@@ -1,3 +1,3 @@
-gawk: clos1way4.awk:5: fatal: printf: attempt to write to closed write end of two-way pipe
test1
-ODE: 2
+gawk: clos1way4.awk:5: fatal: printf: attempt to write to closed write end of two-way pipe
+EXIT CODE: 2