aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnold D. Robbins <arnold@skeeve.com>2016-04-06 06:00:28 +0300
committerArnold D. Robbins <arnold@skeeve.com>2016-04-06 06:00:28 +0300
commit62342b5ad8522da5cbc0623f2b645c48b31c2838 (patch)
tree71cef270090969e33b68825dfa003efc25ff5602
parent525d6122c57db7b5f193b1fc22dc680a44f6c962 (diff)
parent43a645fe05c57576d9d41a7f3b18bb55b1dbdc3e (diff)
downloadegawk-62342b5ad8522da5cbc0623f2b645c48b31c2838.tar.gz
egawk-62342b5ad8522da5cbc0623f2b645c48b31c2838.tar.bz2
egawk-62342b5ad8522da5cbc0623f2b645c48b31c2838.zip
Merge branch 'master' into feature/cmake
-rw-r--r--ChangeLog26
-rw-r--r--NEWS4
-rw-r--r--builtin.c33
-rw-r--r--doc/ChangeLog11
-rw-r--r--doc/gawk.info445
-rw-r--r--doc/gawk.texi18
-rw-r--r--doc/gawktexi.in18
-rw-r--r--io.c9
-rw-r--r--test/ChangeLog15
-rw-r--r--test/Makefile.am14
-rw-r--r--test/Makefile.in39
-rw-r--r--test/Maketests25
-rw-r--r--test/clos1way2.awk6
-rw-r--r--test/clos1way2.in1
-rw-r--r--test/clos1way2.ok4
-rw-r--r--test/clos1way3.awk7
-rw-r--r--test/clos1way3.ok3
-rw-r--r--test/clos1way4.awk7
-rw-r--r--test/clos1way4.ok3
-rw-r--r--test/clos1way5.awk9
-rw-r--r--test/clos1way5.ok3
-rw-r--r--test/clos1way6.awk7
-rw-r--r--test/clos1way6.ok3
23 files changed, 489 insertions, 221 deletions
diff --git a/ChangeLog b/ChangeLog
index 3149d73f..a96375c1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,29 @@
+2016-04-06 Arnold D. Robbins <arnold@skeeve.com>
+
+ * builtin.c (do_printf): Allow a write to the closed write-end of
+ a two-way pipe to be nonfatal if NONFATAL is set for it.
+ (do_print): Ditto.
+ (do_print_rec): Ditto.
+ * io.c (do_getline_redir): Same thing for reading from a closed
+ read end of a two-way pipe. Fatal error.
+
+2016-04-04 Arnold D. Robbins <arnold@skeeve.com>
+
+ * builtin.c (do_fflush): Add warning for flush to two-way
+ pipe where write end was closed.
+ * io.c (flush_io): Add some braces for the for loop.
+
+2016-04-02 Arnold D. Robbins <arnold@skeeve.com>
+
+ * builtin.c (do_printf): If the redirection is two way but the
+ fp is NULL, it means we're writing to the closed write-end of
+ a two-way pipe. Issue a fatal error message.
+ (do_print): Ditto.
+ (do_print_rec): Ditto.
+ * io.c (do_getline_redir): Same thing for reading from a closed
+ read end of a two-way pipe. Fatal error.
+ * NEWS: Updated.
+
2016-03-27 Stephen Davies <sdavies@sdc.com.au>
* awkgram.y (get_comment): Strip CRs from comment. Strip
diff --git a/NEWS b/NEWS
index 6978d2be..91f19902 100644
--- a/NEWS
+++ b/NEWS
@@ -103,6 +103,10 @@ Changes from 4.1.3 to 4.1.x
8. The return value of system() has been enhanced to convey more information.
See the doc.
+9. Attempting to write to the "to" end of a two-way pipe that has been
+ closed is now a fatal error. Similarly, so is reading from the "from"
+ end that has been closed.
+
Changes from 4.1.2 to 4.1.3
---------------------------
diff --git a/builtin.c b/builtin.c
index 9bd8e5eb..e07bdb53 100644
--- a/builtin.c
+++ b/builtin.c
@@ -241,6 +241,9 @@ do_fflush(int nargs)
fp = rp->output.fp;
if (fp != NULL)
status = rp->output.gawk_fflush(fp, rp->output.opaque);
+ else if ((rp->flag & RED_TWOWAY) != 0)
+ warning(_("fflush: cannot flush: two-way pipe `%s' has closed write end"),
+ file);
} else if ((fp = stdfile(tmp->stptr, tmp->stlen)) != NULL) {
status = fflush(fp);
} else {
@@ -1674,8 +1677,16 @@ do_printf(int nargs, int redirtype)
if (redir_exp->type != Node_val)
fatal(_("attempt to use array `%s' in a scalar context"), array_vname(redir_exp));
rp = redirect(redir_exp, redirtype, & errflg, true);
- if (rp != NULL)
+ if (rp != NULL) {
+ if ((rp->flag & RED_TWOWAY) != 0 && rp->output.fp == NULL) {
+ if (is_non_fatal_redirect(redir_exp->stptr)) {
+ update_ERRNO_int(EBADF);
+ return;
+ }
+ fatal(_("printf: attempt to write to closed write end of two-way pipe"));
+ }
fp = rp->output.fp;
+ }
else if (errflg) {
update_ERRNO_int(errflg);
return;
@@ -2150,8 +2161,16 @@ do_print(int nargs, int redirtype)
if (redir_exp->type != Node_val)
fatal(_("attempt to use array `%s' in a scalar context"), array_vname(redir_exp));
rp = redirect(redir_exp, redirtype, & errflg, true);
- if (rp != NULL)
+ if (rp != NULL) {
+ if ((rp->flag & RED_TWOWAY) != 0 && rp->output.fp == NULL) {
+ if (is_non_fatal_redirect(redir_exp->stptr)) {
+ update_ERRNO_int(EBADF);
+ return;
+ }
+ fatal(_("print: attempt to write to closed write end of two-way pipe"));
+ }
fp = rp->output.fp;
+ }
else if (errflg) {
update_ERRNO_int(errflg);
return;
@@ -2220,8 +2239,16 @@ do_print_rec(int nargs, int redirtype)
if (redirtype != 0) {
redir_exp = TOP();
rp = redirect(redir_exp, redirtype, & errflg, true);
- if (rp != NULL)
+ if (rp != NULL) {
+ if ((rp->flag & RED_TWOWAY) != 0 && rp->output.fp == NULL) {
+ if (is_non_fatal_redirect(redir_exp->stptr)) {
+ update_ERRNO_int(EBADF);
+ return;
+ }
+ fatal(_("print: attempt to write to closed write end of two-way pipe"));
+ }
fp = rp->output.fp;
+ }
DEREF(redir_exp);
decr_sp();
} else
diff --git a/doc/ChangeLog b/doc/ChangeLog
index 9fe1a706..7ea2afe0 100644
--- a/doc/ChangeLog
+++ b/doc/ChangeLog
@@ -1,8 +1,19 @@
+2016-04-06 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in (Two-way I/O): Document that writing to the closed
+ write end of a two way pipe or reading from the closed read end
+ can be made nonfatal.
+
2016-04-04 Arnold D. Robbins <arnold@skeeve.com>
* gawktexi.in, gawkinet.texi: Enable use of braces in
indexes. Requires Texinfo 6.0 or later.
+2016-04-02 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in (Two-way I/O): Document that closing the "from"
+ end waits for the process to exit, so it's not such a great idea.
+
2016-03-27 Arnold D. Robbins <arnold@skeeve.com>
* gawkinet.texi: Small update about end of line vs full
diff --git a/doc/gawk.info b/doc/gawk.info
index c1e44de8..16f06d4c 100644
--- a/doc/gawk.info
+++ b/doc/gawk.info
@@ -19938,6 +19938,21 @@ the coprocess and exits.
ensures traditional Unix (ASCII) sorting from 'sort'. This is not
strictly necessary here, but it's good to know how to do this.
+ Be careful when closing the '"from"' end of a two-way pipe; in this
+case 'gawk' waits for the child process to exit, which may cause your
+program to hang. (Thus, this particular feature is of much less use in
+practice than being able to close the '"to"' end.)
+
+ CAUTION: Normally, it is a fatal error to write to the '"to"' end
+ of a two-way pipe which has been closed, and it is also a fatal
+ error to read from the '"from"' end of a two-way pipe that has been
+ closed.
+
+ You may set 'PROCINFO["COMMAND", "NONFATAL"]' to make such
+ operations become nonfatal, in which case you then need to check
+ 'ERRNO' after each 'print', 'printf', or 'getline'. *Note
+ Nonfatal::, for more information.
+
You may also use pseudo-ttys (ptys) for two-way communication instead
of pipes, if your system supports them. This is done on a per-command
basis, by setting a special element in the 'PROCINFO' array (*note
@@ -33738,7 +33753,7 @@ Index
* gawk, predefined variables and: Built-in Variables. (line 14)
* gawk, PROCINFO array in: Auto-set. (line 148)
* gawk, PROCINFO array in <1>: Time Functions. (line 47)
-* gawk, PROCINFO array in <2>: Two-way I/O. (line 99)
+* gawk, PROCINFO array in <2>: Two-way I/O. (line 114)
* gawk, regexp constants and: Using Constant Regexps.
(line 28)
* gawk, regular expressions, case sensitivity: Case-sensitivity.
@@ -34516,7 +34531,7 @@ Index
* PROCINFO array: Auto-set. (line 148)
* PROCINFO array <1>: Time Functions. (line 47)
* PROCINFO array <2>: Passwd Functions. (line 6)
-* PROCINFO array, and communications via ptys: Two-way I/O. (line 99)
+* PROCINFO array, and communications via ptys: Two-way I/O. (line 114)
* PROCINFO array, and group membership: Group Functions. (line 6)
* PROCINFO array, and user and group ID numbers: Id Program. (line 15)
* PROCINFO array, testing the field splitting: Passwd Functions.
@@ -35585,218 +35600,218 @@ Ref: Controlling Array Traversal-Footnote-1801827
Node: Array Sorting Functions801945
Ref: Array Sorting Functions-Footnote-1807036
Node: Two-way I/O807232
-Ref: Two-way I/O-Footnote-1813052
-Ref: Two-way I/O-Footnote-2813239
-Node: TCP/IP Networking813321
-Node: Profiling816439
-Ref: Profiling-Footnote-1824932
-Node: Advanced Features Summary825255
-Node: Internationalization827099
-Node: I18N and L10N828579
-Node: Explaining gettext829266
-Ref: Explaining gettext-Footnote-1834289
-Ref: Explaining gettext-Footnote-2834474
-Node: Programmer i18n834639
-Ref: Programmer i18n-Footnote-1839494
-Node: Translator i18n839543
-Node: String Extraction840337
-Ref: String Extraction-Footnote-1841469
-Node: Printf Ordering841555
-Ref: Printf Ordering-Footnote-1844341
-Node: I18N Portability844405
-Ref: I18N Portability-Footnote-1846861
-Node: I18N Example846924
-Ref: I18N Example-Footnote-1849730
-Node: Gawk I18N849803
-Node: I18N Summary850448
-Node: Debugger851789
-Node: Debugging852811
-Node: Debugging Concepts853252
-Node: Debugging Terms855061
-Node: Awk Debugging857636
-Node: Sample Debugging Session858542
-Node: Debugger Invocation859076
-Node: Finding The Bug860462
-Node: List of Debugger Commands866940
-Node: Breakpoint Control868273
-Node: Debugger Execution Control871967
-Node: Viewing And Changing Data875329
-Node: Execution Stack878703
-Node: Debugger Info880340
-Node: Miscellaneous Debugger Commands884411
-Node: Readline Support889499
-Node: Limitations890395
-Ref: Limitations-Footnote-1894626
-Node: Debugging Summary894677
-Node: Arbitrary Precision Arithmetic895956
-Node: Computer Arithmetic897372
-Ref: table-numeric-ranges900963
-Ref: Computer Arithmetic-Footnote-1901685
-Node: Math Definitions901742
-Ref: table-ieee-formats905056
-Ref: Math Definitions-Footnote-1905659
-Node: MPFR features905764
-Node: FP Math Caution907481
-Ref: FP Math Caution-Footnote-1908553
-Node: Inexactness of computations908922
-Node: Inexact representation909882
-Node: Comparing FP Values911242
-Node: Errors accumulate912324
-Node: Getting Accuracy913757
-Node: Try To Round916467
-Node: Setting precision917366
-Ref: table-predefined-precision-strings918063
-Node: Setting the rounding mode919893
-Ref: table-gawk-rounding-modes920267
-Ref: Setting the rounding mode-Footnote-1923675
-Node: Arbitrary Precision Integers923854
-Ref: Arbitrary Precision Integers-Footnote-1928771
-Node: POSIX Floating Point Problems928920
-Ref: POSIX Floating Point Problems-Footnote-1932802
-Node: Floating point summary932840
-Node: Dynamic Extensions935030
-Node: Extension Intro936583
-Node: Plugin License937849
-Node: Extension Mechanism Outline938646
-Ref: figure-load-extension939085
-Ref: figure-register-new-function940650
-Ref: figure-call-new-function941742
-Node: Extension API Description943804
-Node: Extension API Functions Introduction945336
-Node: General Data Types950195
-Ref: General Data Types-Footnote-1956150
-Node: Memory Allocation Functions956449
-Ref: Memory Allocation Functions-Footnote-1959294
-Node: Constructor Functions959393
-Node: Registration Functions961138
-Node: Extension Functions961823
-Node: Exit Callback Functions964122
-Node: Extension Version String965372
-Node: Input Parsers966035
-Node: Output Wrappers975920
-Node: Two-way processors980432
-Node: Printing Messages982696
-Ref: Printing Messages-Footnote-1983770
-Node: Updating ERRNO983923
-Node: Requesting Values984662
-Ref: table-value-types-returned985399
-Node: Accessing Parameters986282
-Node: Symbol Table Access987517
-Node: Symbol table by name988029
-Node: Symbol table by cookie990050
-Ref: Symbol table by cookie-Footnote-1994199
-Node: Cached values994263
-Ref: Cached values-Footnote-1997764
-Node: Array Manipulation997855
-Ref: Array Manipulation-Footnote-1998946
-Node: Array Data Types998983
-Ref: Array Data Types-Footnote-11001641
-Node: Array Functions1001733
-Node: Flattening Arrays1005591
-Node: Creating Arrays1012499
-Node: Redirection API1017270
-Node: Extension API Variables1020101
-Node: Extension Versioning1020734
-Node: Extension API Informational Variables1022625
-Node: Extension API Boilerplate1023689
-Node: Finding Extensions1027503
-Node: Extension Example1028062
-Node: Internal File Description1028860
-Node: Internal File Ops1032940
-Ref: Internal File Ops-Footnote-11044702
-Node: Using Internal File Ops1044842
-Ref: Using Internal File Ops-Footnote-11047225
-Node: Extension Samples1047499
-Node: Extension Sample File Functions1049028
-Node: Extension Sample Fnmatch1056677
-Node: Extension Sample Fork1058164
-Node: Extension Sample Inplace1059382
-Node: Extension Sample Ord1062592
-Node: Extension Sample Readdir1063428
-Ref: table-readdir-file-types1064317
-Node: Extension Sample Revout1065122
-Node: Extension Sample Rev2way1065711
-Node: Extension Sample Read write array1066451
-Node: Extension Sample Readfile1068393
-Node: Extension Sample Time1069488
-Node: Extension Sample API Tests1070836
-Node: gawkextlib1071328
-Node: Extension summary1073775
-Node: Extension Exercises1077467
-Node: Language History1078964
-Node: V7/SVR3.11080620
-Node: SVR41082772
-Node: POSIX1084206
-Node: BTL1085585
-Node: POSIX/GNU1086314
-Node: Feature History1092176
-Node: Common Extensions1106546
-Node: Ranges and Locales1107829
-Ref: Ranges and Locales-Footnote-11112445
-Ref: Ranges and Locales-Footnote-21112472
-Ref: Ranges and Locales-Footnote-31112707
-Node: Contributors1112928
-Node: History summary1118497
-Node: Installation1119877
-Node: Gawk Distribution1120821
-Node: Getting1121305
-Node: Extracting1122266
-Node: Distribution contents1123904
-Node: Unix Installation1129998
-Node: Quick Installation1130680
-Node: Shell Startup Files1133094
-Node: Additional Configuration Options1134172
-Node: Configuration Philosophy1135977
-Node: Non-Unix Installation1138346
-Node: PC Installation1138804
-Node: PC Binary Installation1140124
-Node: PC Compiling1141976
-Ref: PC Compiling-Footnote-11145000
-Node: PC Testing1145109
-Node: PC Using1146289
-Node: Cygwin1150403
-Node: MSYS1151173
-Node: VMS Installation1151674
-Node: VMS Compilation1152465
-Ref: VMS Compilation-Footnote-11153694
-Node: VMS Dynamic Extensions1153752
-Node: VMS Installation Details1155437
-Node: VMS Running1157690
-Node: VMS GNV1161969
-Node: VMS Old Gawk1162704
-Node: Bugs1163175
-Node: Other Versions1167372
-Node: Installation summary1173956
-Node: Notes1175014
-Node: Compatibility Mode1175879
-Node: Additions1176661
-Node: Accessing The Source1177586
-Node: Adding Code1179021
-Node: New Ports1185240
-Node: Derived Files1189728
-Ref: Derived Files-Footnote-11195213
-Ref: Derived Files-Footnote-21195248
-Ref: Derived Files-Footnote-31195846
-Node: Future Extensions1195960
-Node: Implementation Limitations1196618
-Node: Extension Design1197801
-Node: Old Extension Problems1198955
-Ref: Old Extension Problems-Footnote-11200473
-Node: Extension New Mechanism Goals1200530
-Ref: Extension New Mechanism Goals-Footnote-11203894
-Node: Extension Other Design Decisions1204083
-Node: Extension Future Growth1206196
-Node: Old Extension Mechanism1207032
-Node: Notes summary1208795
-Node: Basic Concepts1209977
-Node: Basic High Level1210658
-Ref: figure-general-flow1210940
-Ref: figure-process-flow1211625
-Ref: Basic High Level-Footnote-11214926
-Node: Basic Data Typing1215111
-Node: Glossary1218439
-Node: Copying1250385
-Node: GNU Free Documentation License1287924
-Node: Index1313042
+Ref: Two-way I/O-Footnote-1813782
+Ref: Two-way I/O-Footnote-2813969
+Node: TCP/IP Networking814051
+Node: Profiling817169
+Ref: Profiling-Footnote-1825662
+Node: Advanced Features Summary825985
+Node: Internationalization827829
+Node: I18N and L10N829309
+Node: Explaining gettext829996
+Ref: Explaining gettext-Footnote-1835019
+Ref: Explaining gettext-Footnote-2835204
+Node: Programmer i18n835369
+Ref: Programmer i18n-Footnote-1840224
+Node: Translator i18n840273
+Node: String Extraction841067
+Ref: String Extraction-Footnote-1842199
+Node: Printf Ordering842285
+Ref: Printf Ordering-Footnote-1845071
+Node: I18N Portability845135
+Ref: I18N Portability-Footnote-1847591
+Node: I18N Example847654
+Ref: I18N Example-Footnote-1850460
+Node: Gawk I18N850533
+Node: I18N Summary851178
+Node: Debugger852519
+Node: Debugging853541
+Node: Debugging Concepts853982
+Node: Debugging Terms855791
+Node: Awk Debugging858366
+Node: Sample Debugging Session859272
+Node: Debugger Invocation859806
+Node: Finding The Bug861192
+Node: List of Debugger Commands867670
+Node: Breakpoint Control869003
+Node: Debugger Execution Control872697
+Node: Viewing And Changing Data876059
+Node: Execution Stack879433
+Node: Debugger Info881070
+Node: Miscellaneous Debugger Commands885141
+Node: Readline Support890229
+Node: Limitations891125
+Ref: Limitations-Footnote-1895356
+Node: Debugging Summary895407
+Node: Arbitrary Precision Arithmetic896686
+Node: Computer Arithmetic898102
+Ref: table-numeric-ranges901693
+Ref: Computer Arithmetic-Footnote-1902415
+Node: Math Definitions902472
+Ref: table-ieee-formats905786
+Ref: Math Definitions-Footnote-1906389
+Node: MPFR features906494
+Node: FP Math Caution908211
+Ref: FP Math Caution-Footnote-1909283
+Node: Inexactness of computations909652
+Node: Inexact representation910612
+Node: Comparing FP Values911972
+Node: Errors accumulate913054
+Node: Getting Accuracy914487
+Node: Try To Round917197
+Node: Setting precision918096
+Ref: table-predefined-precision-strings918793
+Node: Setting the rounding mode920623
+Ref: table-gawk-rounding-modes920997
+Ref: Setting the rounding mode-Footnote-1924405
+Node: Arbitrary Precision Integers924584
+Ref: Arbitrary Precision Integers-Footnote-1929501
+Node: POSIX Floating Point Problems929650
+Ref: POSIX Floating Point Problems-Footnote-1933532
+Node: Floating point summary933570
+Node: Dynamic Extensions935760
+Node: Extension Intro937313
+Node: Plugin License938579
+Node: Extension Mechanism Outline939376
+Ref: figure-load-extension939815
+Ref: figure-register-new-function941380
+Ref: figure-call-new-function942472
+Node: Extension API Description944534
+Node: Extension API Functions Introduction946066
+Node: General Data Types950925
+Ref: General Data Types-Footnote-1956880
+Node: Memory Allocation Functions957179
+Ref: Memory Allocation Functions-Footnote-1960024
+Node: Constructor Functions960123
+Node: Registration Functions961868
+Node: Extension Functions962553
+Node: Exit Callback Functions964852
+Node: Extension Version String966102
+Node: Input Parsers966765
+Node: Output Wrappers976650
+Node: Two-way processors981162
+Node: Printing Messages983426
+Ref: Printing Messages-Footnote-1984500
+Node: Updating ERRNO984653
+Node: Requesting Values985392
+Ref: table-value-types-returned986129
+Node: Accessing Parameters987012
+Node: Symbol Table Access988247
+Node: Symbol table by name988759
+Node: Symbol table by cookie990780
+Ref: Symbol table by cookie-Footnote-1994929
+Node: Cached values994993
+Ref: Cached values-Footnote-1998494
+Node: Array Manipulation998585
+Ref: Array Manipulation-Footnote-1999676
+Node: Array Data Types999713
+Ref: Array Data Types-Footnote-11002371
+Node: Array Functions1002463
+Node: Flattening Arrays1006321
+Node: Creating Arrays1013229
+Node: Redirection API1018000
+Node: Extension API Variables1020831
+Node: Extension Versioning1021464
+Node: Extension API Informational Variables1023355
+Node: Extension API Boilerplate1024419
+Node: Finding Extensions1028233
+Node: Extension Example1028792
+Node: Internal File Description1029590
+Node: Internal File Ops1033670
+Ref: Internal File Ops-Footnote-11045432
+Node: Using Internal File Ops1045572
+Ref: Using Internal File Ops-Footnote-11047955
+Node: Extension Samples1048229
+Node: Extension Sample File Functions1049758
+Node: Extension Sample Fnmatch1057407
+Node: Extension Sample Fork1058894
+Node: Extension Sample Inplace1060112
+Node: Extension Sample Ord1063322
+Node: Extension Sample Readdir1064158
+Ref: table-readdir-file-types1065047
+Node: Extension Sample Revout1065852
+Node: Extension Sample Rev2way1066441
+Node: Extension Sample Read write array1067181
+Node: Extension Sample Readfile1069123
+Node: Extension Sample Time1070218
+Node: Extension Sample API Tests1071566
+Node: gawkextlib1072058
+Node: Extension summary1074505
+Node: Extension Exercises1078197
+Node: Language History1079694
+Node: V7/SVR3.11081350
+Node: SVR41083502
+Node: POSIX1084936
+Node: BTL1086315
+Node: POSIX/GNU1087044
+Node: Feature History1092906
+Node: Common Extensions1107276
+Node: Ranges and Locales1108559
+Ref: Ranges and Locales-Footnote-11113175
+Ref: Ranges and Locales-Footnote-21113202
+Ref: Ranges and Locales-Footnote-31113437
+Node: Contributors1113658
+Node: History summary1119227
+Node: Installation1120607
+Node: Gawk Distribution1121551
+Node: Getting1122035
+Node: Extracting1122996
+Node: Distribution contents1124634
+Node: Unix Installation1130728
+Node: Quick Installation1131410
+Node: Shell Startup Files1133824
+Node: Additional Configuration Options1134902
+Node: Configuration Philosophy1136707
+Node: Non-Unix Installation1139076
+Node: PC Installation1139534
+Node: PC Binary Installation1140854
+Node: PC Compiling1142706
+Ref: PC Compiling-Footnote-11145730
+Node: PC Testing1145839
+Node: PC Using1147019
+Node: Cygwin1151133
+Node: MSYS1151903
+Node: VMS Installation1152404
+Node: VMS Compilation1153195
+Ref: VMS Compilation-Footnote-11154424
+Node: VMS Dynamic Extensions1154482
+Node: VMS Installation Details1156167
+Node: VMS Running1158420
+Node: VMS GNV1162699
+Node: VMS Old Gawk1163434
+Node: Bugs1163905
+Node: Other Versions1168102
+Node: Installation summary1174686
+Node: Notes1175744
+Node: Compatibility Mode1176609
+Node: Additions1177391
+Node: Accessing The Source1178316
+Node: Adding Code1179751
+Node: New Ports1185970
+Node: Derived Files1190458
+Ref: Derived Files-Footnote-11195943
+Ref: Derived Files-Footnote-21195978
+Ref: Derived Files-Footnote-31196576
+Node: Future Extensions1196690
+Node: Implementation Limitations1197348
+Node: Extension Design1198531
+Node: Old Extension Problems1199685
+Ref: Old Extension Problems-Footnote-11201203
+Node: Extension New Mechanism Goals1201260
+Ref: Extension New Mechanism Goals-Footnote-11204624
+Node: Extension Other Design Decisions1204813
+Node: Extension Future Growth1206926
+Node: Old Extension Mechanism1207762
+Node: Notes summary1209525
+Node: Basic Concepts1210707
+Node: Basic High Level1211388
+Ref: figure-general-flow1211670
+Ref: figure-process-flow1212355
+Ref: Basic High Level-Footnote-11215656
+Node: Basic Data Typing1215841
+Node: Glossary1219169
+Node: Copying1251115
+Node: GNU Free Documentation License1288654
+Node: Index1313772

End Tag Table
diff --git a/doc/gawk.texi b/doc/gawk.texi
index 23a25298..fd71dbc9 100644
--- a/doc/gawk.texi
+++ b/doc/gawk.texi
@@ -27853,6 +27853,24 @@ As a side note, the assignment @samp{LC_ALL=C} in the @command{sort}
command ensures traditional Unix (ASCII) sorting from @command{sort}.
This is not strictly necessary here, but it's good to know how to do this.
+Be careful when closing the @code{"from"} end of a two-way pipe; in this
+case @command{gawk} waits for the child process to exit, which may cause
+your program to hang. (Thus, this particular feature is of much less
+use in practice than being able to close the @code{"to"} end.)
+
+@quotation CAUTION
+Normally,
+it is a fatal error to write to the @code{"to"} end of a two-way
+pipe which has been closed, and it is also a fatal error to read
+from the @code{"from"} end of a two-way pipe that has been closed.
+
+You may set @code{PROCINFO["@var{command}", "NONFATAL"]} to
+make such operations become nonfatal, in which case you then need
+to check @code{ERRNO} after each @code{print}, @code{printf},
+or @code{getline}.
+@xref{Nonfatal}, for more information.
+@end quotation
+
@cindex @command{gawk}, @code{PROCINFO} array in
@cindex @code{PROCINFO} array, and communications via ptys
You may also use pseudo-ttys (ptys) for
diff --git a/doc/gawktexi.in b/doc/gawktexi.in
index e43d7137..f47c8459 100644
--- a/doc/gawktexi.in
+++ b/doc/gawktexi.in
@@ -26944,6 +26944,24 @@ As a side note, the assignment @samp{LC_ALL=C} in the @command{sort}
command ensures traditional Unix (ASCII) sorting from @command{sort}.
This is not strictly necessary here, but it's good to know how to do this.
+Be careful when closing the @code{"from"} end of a two-way pipe; in this
+case @command{gawk} waits for the child process to exit, which may cause
+your program to hang. (Thus, this particular feature is of much less
+use in practice than being able to close the @code{"to"} end.)
+
+@quotation CAUTION
+Normally,
+it is a fatal error to write to the @code{"to"} end of a two-way
+pipe which has been closed, and it is also a fatal error to read
+from the @code{"from"} end of a two-way pipe that has been closed.
+
+You may set @code{PROCINFO["@var{command}", "NONFATAL"]} to
+make such operations become nonfatal, in which case you then need
+to check @code{ERRNO} after each @code{print}, @code{printf},
+or @code{getline}.
+@xref{Nonfatal}, for more information.
+@end quotation
+
@cindex @command{gawk}, @code{PROCINFO} array in
@cindex @code{PROCINFO} array, and communications via ptys
You may also use pseudo-ttys (ptys) for
diff --git a/io.c b/io.c
index 335e1255..fafc1003 100644
--- a/io.c
+++ b/io.c
@@ -1391,7 +1391,7 @@ flush_io()
warning(_("error writing standard error (%s)"), strerror(errno));
status++;
}
- for (rp = red_head; rp != NULL; rp = rp->next)
+ for (rp = red_head; rp != NULL; rp = rp->next) {
/* 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)) {
@@ -1407,6 +1407,7 @@ flush_io()
status++;
}
}
+ }
if (status != 0)
status = -1; /* canonicalize it */
return status;
@@ -2602,6 +2603,12 @@ do_getline_redir(int into_variable, enum redirval redirtype)
update_ERRNO_int(redir_error);
}
return make_number((AWKNUM) -1.0);
+ } else if ((rp->flag & RED_TWOWAY) != 0 && rp->iop == NULL) {
+ if (is_non_fatal_redirect(redir_exp->stptr)) {
+ update_ERRNO_int(EBADF);
+ return make_number((AWKNUM) -1.0);
+ }
+ fatal(_("getline: attempt to read from closed read end of two-way pipe"));
}
iop = rp->iop;
if (iop == NULL) /* end of input */
diff --git a/test/ChangeLog b/test/ChangeLog
index 2b44b4b5..bfb05de6 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -1,3 +1,18 @@
+2016-04-06 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (clos1way6): New test.
+ * clos1way6.awk, clos1way6.ok: New files.
+
+2016-04-04 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Makefile.am (clos1way2, clos1way3, clos1way4, clos1way5):
+ New tests.
+ * clos1way2.awk, clos1way2.in, clos1way2.ok, clos1way3.awk,
+ clos1way3.ok, clos1way4.awk, clos1way4.ok, clos1way5.awk,
+ clos1way5.ok: New files.
+ * clos1way2.awk: Add call to fflush() to test it too.
+ * clos1way2.ok: Updated after code change.
+
2016-03-27 Arnold D. Robbins <arnold@skeeve.com>
* profile5.ok: Adjust after code changes.
diff --git a/test/Makefile.am b/test/Makefile.am
index 776dfbd0..fdb163d7 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -147,6 +147,17 @@ EXTRA_DIST = \
clobber.ok \
clos1way.awk \
clos1way.ok \
+ clos1way2.awk \
+ clos1way2.in \
+ clos1way2.ok \
+ clos1way3.awk \
+ clos1way3.ok \
+ clos1way4.awk \
+ clos1way4.ok \
+ clos1way5.awk \
+ clos1way5.ok \
+ clos1way6.awk \
+ clos1way6.ok \
closebad.awk \
closebad.ok \
clsflnam.awk \
@@ -1121,7 +1132,8 @@ UNIX_TESTS = \
GAWK_EXT_TESTS = \
aadelete1 aadelete2 aarray1 aasort aasorti argtest arraysort \
backw badargs beginfile1 beginfile2 binmode1 charasbytes \
- colonwarn clos1way crlf dbugeval dbugeval2 dbugtypedre1 dbugtypedre2 delsub \
+ colonwarn clos1way clos1way2 clos1way3 clos1way4 clos1way5 clos1way6 \
+ crlf dbugeval dbugeval2 dbugtypedre1 dbugtypedre2 delsub \
devfd devfd1 devfd2 dumpvars errno exit \
fieldwdth fpat1 fpat2 fpat3 fpat4 fpat5 fpatnull fsfwfs funlen \
functab1 functab2 functab3 fwtest fwtest2 fwtest3 \
diff --git a/test/Makefile.in b/test/Makefile.in
index 7c3a5a00..3fa8fbc4 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -404,6 +404,17 @@ EXTRA_DIST = \
clobber.ok \
clos1way.awk \
clos1way.ok \
+ clos1way2.awk \
+ clos1way2.in \
+ clos1way2.ok \
+ clos1way3.awk \
+ clos1way3.ok \
+ clos1way4.awk \
+ clos1way4.ok \
+ clos1way5.awk \
+ clos1way5.ok \
+ clos1way6.awk \
+ clos1way6.ok \
closebad.awk \
closebad.ok \
clsflnam.awk \
@@ -1377,7 +1388,8 @@ UNIX_TESTS = \
GAWK_EXT_TESTS = \
aadelete1 aadelete2 aarray1 aasort aasorti argtest arraysort \
backw badargs beginfile1 beginfile2 binmode1 charasbytes \
- colonwarn clos1way crlf dbugeval dbugeval2 dbugtypedre1 dbugtypedre2 delsub \
+ colonwarn clos1way clos1way2 clos1way3 clos1way4 clos1way5 clos1way6 \
+ crlf dbugeval dbugeval2 dbugtypedre1 dbugtypedre2 delsub \
devfd devfd1 devfd2 dumpvars errno exit \
fieldwdth fpat1 fpat2 fpat3 fpat4 fpat5 fpatnull fsfwfs funlen \
functab1 functab2 functab3 fwtest fwtest2 fwtest3 \
@@ -3648,6 +3660,31 @@ backw:
@AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+clos1way2:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+clos1way3:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+clos1way4:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+clos1way5:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+clos1way6:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
crlf:
@echo $@
@AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
diff --git a/test/Maketests b/test/Maketests
index f1ffdf97..3b4691d2 100644
--- a/test/Maketests
+++ b/test/Maketests
@@ -997,6 +997,31 @@ backw:
@AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+clos1way2:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+clos1way3:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+clos1way4:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+clos1way5:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
+clos1way6:
+ @echo $@
+ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
+
crlf:
@echo $@
@AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
diff --git a/test/clos1way2.awk b/test/clos1way2.awk
new file mode 100644
index 00000000..5794bec5
--- /dev/null
+++ b/test/clos1way2.awk
@@ -0,0 +1,6 @@
+{
+ cmd = "cat - 1>&2; sleep 2"
+ print |& cmd; close(cmd, "to")
+ fflush(cmd)
+ print |& cmd; print ERRNO
+}
diff --git a/test/clos1way2.in b/test/clos1way2.in
new file mode 100644
index 00000000..9daeafb9
--- /dev/null
+++ b/test/clos1way2.in
@@ -0,0 +1 @@
+test
diff --git a/test/clos1way2.ok b/test/clos1way2.ok
new file mode 100644
index 00000000..063c4213
--- /dev/null
+++ b/test/clos1way2.ok
@@ -0,0 +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
diff --git a/test/clos1way3.awk b/test/clos1way3.awk
new file mode 100644
index 00000000..f69f6675
--- /dev/null
+++ b/test/clos1way3.awk
@@ -0,0 +1,7 @@
+BEGIN {
+ cmd = "cat - 1>&2; sleep 2"
+ print "test1" |& cmd
+ close(cmd, "to")
+ print "test2" |& cmd
+ print ERRNO
+}
diff --git a/test/clos1way3.ok b/test/clos1way3.ok
new file mode 100644
index 00000000..74f67738
--- /dev/null
+++ b/test/clos1way3.ok
@@ -0,0 +1,3 @@
+gawk: clos1way3.awk:5: fatal: print: attempt to write to closed write end of two-way pipe
+test1
+ODE: 2
diff --git a/test/clos1way4.awk b/test/clos1way4.awk
new file mode 100644
index 00000000..6c68c5c8
--- /dev/null
+++ b/test/clos1way4.awk
@@ -0,0 +1,7 @@
+BEGIN {
+ cmd = "cat - 1>&2; sleep 2"
+ printf "%s\n", "test1" |& cmd
+ close(cmd, "to")
+ printf "%s\n", "test2" |& cmd
+ print ERRNO
+}
diff --git a/test/clos1way4.ok b/test/clos1way4.ok
new file mode 100644
index 00000000..707f9813
--- /dev/null
+++ b/test/clos1way4.ok
@@ -0,0 +1,3 @@
+gawk: clos1way4.awk:5: fatal: printf: attempt to write to closed write end of two-way pipe
+test1
+ODE: 2
diff --git a/test/clos1way5.awk b/test/clos1way5.awk
new file mode 100644
index 00000000..ca1bd94c
--- /dev/null
+++ b/test/clos1way5.awk
@@ -0,0 +1,9 @@
+BEGIN {
+ cmd = "echo test1; echo test2; sleep 2"
+ cmd |& getline x
+ print x
+ close(cmd, "from")
+ cmd |& getline x
+ print x
+ print ERRNO
+}
diff --git a/test/clos1way5.ok b/test/clos1way5.ok
new file mode 100644
index 00000000..1ff15402
--- /dev/null
+++ b/test/clos1way5.ok
@@ -0,0 +1,3 @@
+test1
+gawk: clos1way5.awk:6: fatal: getline: attempt to read from closed read end of two-way pipe
+EXIT CODE: 2
diff --git a/test/clos1way6.awk b/test/clos1way6.awk
new file mode 100644
index 00000000..19779d73
--- /dev/null
+++ b/test/clos1way6.awk
@@ -0,0 +1,7 @@
+BEGIN {
+ cmd = "cat - 1>&2; sleep 2"
+ PROCINFO[cmd, "NONFATAL"] = 1
+ print "test1" |& cmd; close(cmd, "to")
+ fflush(cmd)
+ print "test2" |& cmd; print ERRNO
+}
diff --git a/test/clos1way6.ok b/test/clos1way6.ok
new file mode 100644
index 00000000..5768617d
--- /dev/null
+++ b/test/clos1way6.ok
@@ -0,0 +1,3 @@
+gawk: clos1way6.awk:5: warning: fflush: cannot flush: two-way pipe `cat - 1>&2; sleep 2' has closed write end
+test1
+Bad file descriptor