aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnold D. Robbins <arnold@skeeve.com>2016-04-05 21:41:39 +0300
committerArnold D. Robbins <arnold@skeeve.com>2016-04-05 21:41:39 +0300
commitdb6e8faca70e60d2fa80e0affda3d9bef1e82eae (patch)
tree2ede6812410f1bfdba4e098a3d9dd92d725232f1
parent2adf64c7b99ec6e8d1e4689b6484ace5295580b6 (diff)
parent1b5d1b8870cb0ac1c4b99f6cf67e3277427df864 (diff)
downloadegawk-db6e8faca70e60d2fa80e0affda3d9bef1e82eae.tar.gz
egawk-db6e8faca70e60d2fa80e0affda3d9bef1e82eae.tar.bz2
egawk-db6e8faca70e60d2fa80e0affda3d9bef1e82eae.zip
Merge branch 'gawk-4.1-stable'
-rw-r--r--ChangeLog17
-rw-r--r--NEWS4
-rw-r--r--builtin.c21
-rw-r--r--doc/ChangeLog5
-rw-r--r--doc/gawk.info439
-rw-r--r--doc/gawk.texi11
-rw-r--r--doc/gawktexi.in11
-rw-r--r--io.c5
-rw-r--r--test/ChangeLog10
-rw-r--r--test/Makefile.am12
-rw-r--r--test/Makefile.in32
-rw-r--r--test/Maketests20
-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
21 files changed, 409 insertions, 221 deletions
diff --git a/ChangeLog b/ChangeLog
index 3149d73f..025f88e9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+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..b3756ebc 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,12 @@ 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) {
+ 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 +2157,12 @@ 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) {
+ 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 +2231,12 @@ 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) {
+ 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..7f789370 100644
--- a/doc/ChangeLog
+++ b/doc/ChangeLog
@@ -3,6 +3,11 @@
* 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..c60bf429 100644
--- a/doc/gawk.info
+++ b/doc/gawk.info
@@ -19938,6 +19938,15 @@ 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: It is a fatal error to write to the '"to"' end of a
+ two-way pipe which has been closed. It is also a fatal error to
+ read from the '"from"' end of a two-way pipe that has been closed.
+
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 +33747,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 108)
* gawk, regexp constants and: Using Constant Regexps.
(line 28)
* gawk, regular expressions, case sensitivity: Case-sensitivity.
@@ -34516,7 +34525,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 108)
* 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 +35594,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-1813526
+Ref: Two-way I/O-Footnote-2813713
+Node: TCP/IP Networking813795
+Node: Profiling816913
+Ref: Profiling-Footnote-1825406
+Node: Advanced Features Summary825729
+Node: Internationalization827573
+Node: I18N and L10N829053
+Node: Explaining gettext829740
+Ref: Explaining gettext-Footnote-1834763
+Ref: Explaining gettext-Footnote-2834948
+Node: Programmer i18n835113
+Ref: Programmer i18n-Footnote-1839968
+Node: Translator i18n840017
+Node: String Extraction840811
+Ref: String Extraction-Footnote-1841943
+Node: Printf Ordering842029
+Ref: Printf Ordering-Footnote-1844815
+Node: I18N Portability844879
+Ref: I18N Portability-Footnote-1847335
+Node: I18N Example847398
+Ref: I18N Example-Footnote-1850204
+Node: Gawk I18N850277
+Node: I18N Summary850922
+Node: Debugger852263
+Node: Debugging853285
+Node: Debugging Concepts853726
+Node: Debugging Terms855535
+Node: Awk Debugging858110
+Node: Sample Debugging Session859016
+Node: Debugger Invocation859550
+Node: Finding The Bug860936
+Node: List of Debugger Commands867414
+Node: Breakpoint Control868747
+Node: Debugger Execution Control872441
+Node: Viewing And Changing Data875803
+Node: Execution Stack879177
+Node: Debugger Info880814
+Node: Miscellaneous Debugger Commands884885
+Node: Readline Support889973
+Node: Limitations890869
+Ref: Limitations-Footnote-1895100
+Node: Debugging Summary895151
+Node: Arbitrary Precision Arithmetic896430
+Node: Computer Arithmetic897846
+Ref: table-numeric-ranges901437
+Ref: Computer Arithmetic-Footnote-1902159
+Node: Math Definitions902216
+Ref: table-ieee-formats905530
+Ref: Math Definitions-Footnote-1906133
+Node: MPFR features906238
+Node: FP Math Caution907955
+Ref: FP Math Caution-Footnote-1909027
+Node: Inexactness of computations909396
+Node: Inexact representation910356
+Node: Comparing FP Values911716
+Node: Errors accumulate912798
+Node: Getting Accuracy914231
+Node: Try To Round916941
+Node: Setting precision917840
+Ref: table-predefined-precision-strings918537
+Node: Setting the rounding mode920367
+Ref: table-gawk-rounding-modes920741
+Ref: Setting the rounding mode-Footnote-1924149
+Node: Arbitrary Precision Integers924328
+Ref: Arbitrary Precision Integers-Footnote-1929245
+Node: POSIX Floating Point Problems929394
+Ref: POSIX Floating Point Problems-Footnote-1933276
+Node: Floating point summary933314
+Node: Dynamic Extensions935504
+Node: Extension Intro937057
+Node: Plugin License938323
+Node: Extension Mechanism Outline939120
+Ref: figure-load-extension939559
+Ref: figure-register-new-function941124
+Ref: figure-call-new-function942216
+Node: Extension API Description944278
+Node: Extension API Functions Introduction945810
+Node: General Data Types950669
+Ref: General Data Types-Footnote-1956624
+Node: Memory Allocation Functions956923
+Ref: Memory Allocation Functions-Footnote-1959768
+Node: Constructor Functions959867
+Node: Registration Functions961612
+Node: Extension Functions962297
+Node: Exit Callback Functions964596
+Node: Extension Version String965846
+Node: Input Parsers966509
+Node: Output Wrappers976394
+Node: Two-way processors980906
+Node: Printing Messages983170
+Ref: Printing Messages-Footnote-1984244
+Node: Updating ERRNO984397
+Node: Requesting Values985136
+Ref: table-value-types-returned985873
+Node: Accessing Parameters986756
+Node: Symbol Table Access987991
+Node: Symbol table by name988503
+Node: Symbol table by cookie990524
+Ref: Symbol table by cookie-Footnote-1994673
+Node: Cached values994737
+Ref: Cached values-Footnote-1998238
+Node: Array Manipulation998329
+Ref: Array Manipulation-Footnote-1999420
+Node: Array Data Types999457
+Ref: Array Data Types-Footnote-11002115
+Node: Array Functions1002207
+Node: Flattening Arrays1006065
+Node: Creating Arrays1012973
+Node: Redirection API1017744
+Node: Extension API Variables1020575
+Node: Extension Versioning1021208
+Node: Extension API Informational Variables1023099
+Node: Extension API Boilerplate1024163
+Node: Finding Extensions1027977
+Node: Extension Example1028536
+Node: Internal File Description1029334
+Node: Internal File Ops1033414
+Ref: Internal File Ops-Footnote-11045176
+Node: Using Internal File Ops1045316
+Ref: Using Internal File Ops-Footnote-11047699
+Node: Extension Samples1047973
+Node: Extension Sample File Functions1049502
+Node: Extension Sample Fnmatch1057151
+Node: Extension Sample Fork1058638
+Node: Extension Sample Inplace1059856
+Node: Extension Sample Ord1063066
+Node: Extension Sample Readdir1063902
+Ref: table-readdir-file-types1064791
+Node: Extension Sample Revout1065596
+Node: Extension Sample Rev2way1066185
+Node: Extension Sample Read write array1066925
+Node: Extension Sample Readfile1068867
+Node: Extension Sample Time1069962
+Node: Extension Sample API Tests1071310
+Node: gawkextlib1071802
+Node: Extension summary1074249
+Node: Extension Exercises1077941
+Node: Language History1079438
+Node: V7/SVR3.11081094
+Node: SVR41083246
+Node: POSIX1084680
+Node: BTL1086059
+Node: POSIX/GNU1086788
+Node: Feature History1092650
+Node: Common Extensions1107020
+Node: Ranges and Locales1108303
+Ref: Ranges and Locales-Footnote-11112919
+Ref: Ranges and Locales-Footnote-21112946
+Ref: Ranges and Locales-Footnote-31113181
+Node: Contributors1113402
+Node: History summary1118971
+Node: Installation1120351
+Node: Gawk Distribution1121295
+Node: Getting1121779
+Node: Extracting1122740
+Node: Distribution contents1124378
+Node: Unix Installation1130472
+Node: Quick Installation1131154
+Node: Shell Startup Files1133568
+Node: Additional Configuration Options1134646
+Node: Configuration Philosophy1136451
+Node: Non-Unix Installation1138820
+Node: PC Installation1139278
+Node: PC Binary Installation1140598
+Node: PC Compiling1142450
+Ref: PC Compiling-Footnote-11145474
+Node: PC Testing1145583
+Node: PC Using1146763
+Node: Cygwin1150877
+Node: MSYS1151647
+Node: VMS Installation1152148
+Node: VMS Compilation1152939
+Ref: VMS Compilation-Footnote-11154168
+Node: VMS Dynamic Extensions1154226
+Node: VMS Installation Details1155911
+Node: VMS Running1158164
+Node: VMS GNV1162443
+Node: VMS Old Gawk1163178
+Node: Bugs1163649
+Node: Other Versions1167846
+Node: Installation summary1174430
+Node: Notes1175488
+Node: Compatibility Mode1176353
+Node: Additions1177135
+Node: Accessing The Source1178060
+Node: Adding Code1179495
+Node: New Ports1185714
+Node: Derived Files1190202
+Ref: Derived Files-Footnote-11195687
+Ref: Derived Files-Footnote-21195722
+Ref: Derived Files-Footnote-31196320
+Node: Future Extensions1196434
+Node: Implementation Limitations1197092
+Node: Extension Design1198275
+Node: Old Extension Problems1199429
+Ref: Old Extension Problems-Footnote-11200947
+Node: Extension New Mechanism Goals1201004
+Ref: Extension New Mechanism Goals-Footnote-11204368
+Node: Extension Other Design Decisions1204557
+Node: Extension Future Growth1206670
+Node: Old Extension Mechanism1207506
+Node: Notes summary1209269
+Node: Basic Concepts1210451
+Node: Basic High Level1211132
+Ref: figure-general-flow1211414
+Ref: figure-process-flow1212099
+Ref: Basic High Level-Footnote-11215400
+Node: Basic Data Typing1215585
+Node: Glossary1218913
+Node: Copying1250859
+Node: GNU Free Documentation License1288398
+Node: Index1313516

End Tag Table
diff --git a/doc/gawk.texi b/doc/gawk.texi
index 23a25298..77bec7d1 100644
--- a/doc/gawk.texi
+++ b/doc/gawk.texi
@@ -27853,6 +27853,17 @@ 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
+It is a fatal error to write to the @code{"to"} end of a two-way
+pipe which has been closed. It is also a fatal error to read
+from the @code{"from"} end of a two-way pipe that has been closed.
+@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..75381dc4 100644
--- a/doc/gawktexi.in
+++ b/doc/gawktexi.in
@@ -26944,6 +26944,17 @@ 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
+It is a fatal error to write to the @code{"to"} end of a two-way
+pipe which has been closed. It is also a fatal error to read
+from the @code{"from"} end of a two-way pipe that has been closed.
+@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..719601c2 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,8 @@ 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) {
+ 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..eaeed87d 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -1,3 +1,13 @@
+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..8e5d0c88 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -147,6 +147,15 @@ 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 \
closebad.awk \
closebad.ok \
clsflnam.awk \
@@ -1121,7 +1130,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 \
+ 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..9fec312d 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -404,6 +404,15 @@ 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 \
closebad.awk \
closebad.ok \
clsflnam.awk \
@@ -1377,7 +1386,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 \
+ 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 +3658,26 @@ 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 _$@
+
crlf:
@echo $@
@AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
diff --git a/test/Maketests b/test/Maketests
index f1ffdf97..e39f6c3c 100644
--- a/test/Maketests
+++ b/test/Maketests
@@ -997,6 +997,26 @@ 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 _$@
+
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