diff options
-rw-r--r-- | ChangeLog | 17 | ||||
-rw-r--r-- | NEWS | 4 | ||||
-rw-r--r-- | builtin.c | 21 | ||||
-rw-r--r-- | doc/ChangeLog | 5 | ||||
-rw-r--r-- | doc/gawk.info | 439 | ||||
-rw-r--r-- | doc/gawk.texi | 11 | ||||
-rw-r--r-- | doc/gawktexi.in | 11 | ||||
-rw-r--r-- | io.c | 5 | ||||
-rw-r--r-- | test/ChangeLog | 10 | ||||
-rw-r--r-- | test/Makefile.am | 12 | ||||
-rw-r--r-- | test/Makefile.in | 32 | ||||
-rw-r--r-- | test/Maketests | 20 | ||||
-rw-r--r-- | test/clos1way2.awk | 6 | ||||
-rw-r--r-- | test/clos1way2.in | 1 | ||||
-rw-r--r-- | test/clos1way2.ok | 4 | ||||
-rw-r--r-- | test/clos1way3.awk | 7 | ||||
-rw-r--r-- | test/clos1way3.ok | 3 | ||||
-rw-r--r-- | test/clos1way4.awk | 7 | ||||
-rw-r--r-- | test/clos1way4.ok | 3 | ||||
-rw-r--r-- | test/clos1way5.awk | 9 | ||||
-rw-r--r-- | test/clos1way5.ok | 3 |
21 files changed, 409 insertions, 221 deletions
@@ -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 @@ -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 --------------------------- @@ -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 @@ -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 |