diff options
-rw-r--r-- | ChangeLog | 61 | ||||
-rw-r--r-- | TODO | 5 | ||||
-rw-r--r-- | awk.h | 4 | ||||
-rw-r--r-- | builtin.c | 37 | ||||
-rw-r--r-- | doc/ChangeLog | 16 | ||||
-rw-r--r-- | doc/gawk.info | 1193 | ||||
-rw-r--r-- | doc/gawk.texi | 83 | ||||
-rw-r--r-- | doc/gawktexi.in | 83 | ||||
-rw-r--r-- | io.c | 142 | ||||
-rw-r--r-- | missing_d/ChangeLog | 6 | ||||
-rw-r--r-- | missing_d/getaddrinfo.c | 16 | ||||
-rw-r--r-- | missing_d/getaddrinfo.h | 2 | ||||
-rw-r--r-- | test/ChangeLog | 31 | ||||
-rw-r--r-- | test/Makefile.am | 7 | ||||
-rw-r--r-- | test/Makefile.in | 22 | ||||
-rw-r--r-- | test/Maketests | 15 | ||||
-rw-r--r-- | test/nonfatal1.awk | 6 | ||||
-rw-r--r-- | test/nonfatal1.ok | 2 | ||||
-rw-r--r-- | test/nonfatal2.awk | 5 | ||||
-rw-r--r-- | test/nonfatal2.ok | 1 | ||||
-rw-r--r-- | test/nonfatal3.awk | 6 | ||||
-rw-r--r-- | test/nonfatal3.ok | 1 |
22 files changed, 1132 insertions, 612 deletions
@@ -1,3 +1,25 @@ +2015-03-08 Arnold D. Robbins <arnold@skeeve.com> + + * io.c (devopen): Change the logic such that if nonfatal is true + for the socket, don't do retries. Also clean up the formatting + some. At strictopen, check if errno is ENOENT and if so, propagate + the error from getaddrinfo() up to the caller. Add explanatory + comments. + +2015-02-28 Andrew J. Schorr <aschorr@telemetry-investments.com> + + * io.c (pty_vs_pipe): Remove check for NULL PROCINFO_node, since + this is now checked inside in_PROCINFO. + +2015-02-27 Andrew J. Schorr <aschorr@telemetry-investments.com> + + * io.c (socketopen): New parameter hard_error; set it if + getaddrinfo() fails. Change fatals to warnings. + (devopen): Pass in address of boolean hard_error variable + and stop trying to open the file if hard_error is true. + Save and restore errno around call to socketopen() and + use restored errno if open() fails at strictopen. + 2015-02-27 Arnold D. Robbins <arnold@skeeve.com> * symbol.c (check_param_names): Fix argument order in memset() call. @@ -33,6 +55,29 @@ * profile.c (pprint): Restore printing of count for rules. Bug report by Hermann Peifer. +2015-02-08 Arnold D. Robbins <arnold@skeeve.com> + + * io.c: Make it "NONFATAL" everywhere. + +2015-02-08 Andrew J. Schorr <aschorr@telemetry-investments.com> + + * awk.h (RED_NON_FATAL): Removed. + (redirect): Add new failure_fatal parameter. + (is_non_fatal_redirect): Add declaration. + * builtin.c (efwrite): Rework check for non-fatal. + (do_printf): Adjust calls to redirect. + (do_print_rec): Ditto. Move check for redirection error up. + * io.c (redflags2str): Remove RED_NON_FATAL. + (redirect): Add new failure_fatal parameter. Simplify the code. + (is_non_fatal_redirect): New function. + (do_getline_redir): Adjust calls to redirect. + +2014-12-27 Arnold D. Robbins <arnold@skeeve.com> + + * awk.h (is_non_fatal_std): Declare new function. + * io.c (is_non_fatal_std): New function. + * builtin.c (efwrite): Call it. + 2015-02-07 Arnold D. Robbins <arnold@skeeve.com> * regcomp.c, regex.c, regex.h, regex_internal.c, regex_internal.h, @@ -140,6 +185,22 @@ * profile.c (pprint): Be sure to set ip2 in all paths through the code. Thanks to GCC 4.9 for the warning. +2014-12-20 Arnold D. Robbins <arnold@skeeve.com> + + Enable non-fatal output on per-file or global basis, + via PROCINFO. + + * awk.h (RED_NON_FATAL): New redirection flag. + * builtin.c (efwrite): If RED_NON_FATAL set, just set ERRNO and return. + (do_printf): Check errflg and if set, set ERRNO and return. + (do_print): Ditto. + (do_print_rec): Ditto. + * io.c (redflags2str): Update table. + (redirect): Check for global PROCINFO["nonfatal"] or for + PROCINFO[file, "nonfatal"] and don't fail on open if set. + Add RED_NON_FATAL to flags. + (in_PROCINFO): Make smarter and more general. + 2014-12-12 Stephen Davies <sdavies@sdc.com.au> Improve comment handling in pretty printing. @@ -1,4 +1,4 @@ -Sun Sep 28 22:19:10 IDT 2014 +Wed Dec 24 20:41:38 IST 2014 ============================ There were too many files tracking different thoughts and ideas for @@ -44,9 +44,6 @@ Minor New Features Consider relaxing the strictness of --posix. - Make it possible to put print/printf + redirections into - an expression. - ? Add an optional base to strtonum, allowing 2-36. ? Optional third argument for index indicating where to start the @@ -1482,7 +1482,7 @@ extern void register_two_way_processor(awk_two_way_processor_t *processor); extern void set_FNR(void); extern void set_NR(void); -extern struct redirect *redirect(NODE *redir_exp, int redirtype, int *errflg); +extern struct redirect *redirect(NODE *redir_exp, int redirtype, int *errflg, bool failure_fatal); extern NODE *do_close(int nargs); extern int flush_io(void); extern int close_io(bool *stdio_problem); @@ -1494,6 +1494,8 @@ extern NODE *do_getline(int intovar, IOBUF *iop); extern struct redirect *getredirect(const char *str, int len); extern bool inrec(IOBUF *iop, int *errcode); extern int nextfile(IOBUF **curfile, bool skipping); +extern bool is_non_fatal_std(FILE *fp); +extern bool is_non_fatal_redirect(const char *str); /* main.c */ extern int arg_assign(char *arg, bool initing); extern int is_std_var(const char *var); @@ -129,10 +129,14 @@ wrerror: if (fp == stdout && errno == EPIPE) gawk_exit(EXIT_FATAL); + /* otherwise die verbosely */ - fatal(_("%s to \"%s\" failed (%s)"), from, - rp ? rp->value : _("standard output"), - errno ? strerror(errno) : _("reason unknown")); + if ((rp != NULL) ? is_non_fatal_redirect(rp->value) : is_non_fatal_std(fp)) + update_ERRNO_int(errno); + else + fatal(_("%s to \"%s\" failed (%s)"), from, + rp ? rp->value : _("standard output"), + errno ? strerror(errno) : _("reason unknown")); } /* do_exp --- exponential function */ @@ -1639,7 +1643,7 @@ do_printf(int nargs, int redirtype) FILE *fp = NULL; NODE *tmp; struct redirect *rp = NULL; - int errflg; /* not used, sigh */ + int errflg = 0; NODE *redir_exp = NULL; if (nargs == 0) { @@ -1650,7 +1654,7 @@ do_printf(int nargs, int redirtype) redir_exp = TOP(); 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); + rp = redirect(redir_exp, redirtype, & errflg, true); DEREF(redir_exp); decr_sp(); } @@ -1663,9 +1667,13 @@ do_printf(int nargs, int redirtype) redir_exp = PEEK(nargs); 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); + rp = redirect(redir_exp, redirtype, & errflg, true); if (rp != NULL) fp = rp->output.fp; + else if (errflg) { + update_ERRNO_int(errflg); + return; + } } else if (do_debug) /* only the debugger can change the default output */ fp = output_fp; else @@ -2078,7 +2086,7 @@ void do_print(int nargs, int redirtype) { struct redirect *rp = NULL; - int errflg; /* not used, sigh */ + int errflg = 0; FILE *fp = NULL; int i; NODE *redir_exp = NULL; @@ -2090,9 +2098,13 @@ do_print(int nargs, int redirtype) redir_exp = PEEK(nargs); 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); + rp = redirect(redir_exp, redirtype, & errflg, true); if (rp != NULL) fp = rp->output.fp; + else if (errflg) { + update_ERRNO_int(errflg); + return; + } } else if (do_debug) /* only the debugger can change the default output */ fp = output_fp; else @@ -2148,13 +2160,13 @@ do_print_rec(int nargs, int redirtype) FILE *fp = NULL; NODE *f0; struct redirect *rp = NULL; - int errflg; /* not used, sigh */ + int errflg = 0; NODE *redir_exp = NULL; assert(nargs == 0); if (redirtype != 0) { redir_exp = TOP(); - rp = redirect(redir_exp, redirtype, & errflg); + rp = redirect(redir_exp, redirtype, & errflg, true); if (rp != NULL) fp = rp->output.fp; DEREF(redir_exp); @@ -2162,6 +2174,11 @@ do_print_rec(int nargs, int redirtype) } else fp = output_fp; + if (errflg) { + update_ERRNO_int(errflg); + return; + } + if (fp == NULL) return; diff --git a/doc/ChangeLog b/doc/ChangeLog index 6ed6b7bc..b58699a4 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,9 @@ +2015-03-08 Arnold D. Robbins <arnold@skeeve.com> + + * gawktexi.in: Briefly describe that nonfatal I/O overrides + GAWK_SOCK_RETRIES, in the env var part and in the nonfatal I/O + part. + 2015-03-01 Arnold D. Robbins <arnold@skeeve.com> * gawktexi.in: Change quotes to @dfn for pseudorandom. @@ -54,6 +60,7 @@ 2015-02-08 Arnold D. Robbins <arnold@skeeve.com> * gawktexi.in: O'Reilly fixes. + Make non-fatal i/o use "NONFATAL". 2015-02-06 Arnold D. Robbins <arnold@skeeve.com> @@ -114,12 +121,21 @@ * gawkinet.texi: Fix capitalization in document title. * gawktexi.in: Here we go again: Starting on more O'Reilly fixes. +2014-12-27 Arnold D. Robbins <arnold@skeeve.com> + + * gawktexi.in: Add info that nonfatal I/O works with stdout and + stderr. Revise version info and what was added when. + 2014-12-26 Antonio Giovanni Colombo <azc100@gmail.com> * gawktexi.in (Glossary): Really sort the items. 2014-12-24 Arnold D. Robbins <arnold@skeeve.com> + * gawktexi.in: Start documenting nonfatal output. + +2014-12-24 Arnold D. Robbins <arnold@skeeve.com> + * gawktexi.in: Add one more paragraph to new foreword. * gawktexi.in: Fix exponentiation in TeX mode. Thanks to Marco Curreli by way of Antonio Giovanni Colombo. diff --git a/doc/gawk.info b/doc/gawk.info index 82641494..7e548a8e 100644 --- a/doc/gawk.info +++ b/doc/gawk.info @@ -246,6 +246,7 @@ entitled "GNU Free Documentation License". * Special Caveats:: Things to watch out for. * Close Files And Pipes:: Closing Input and Output Files and Pipes. +* Nonfatal:: Enabling Nonfatal Output. * Output Summary:: Output summary. * Output Exercises:: Exercises. * Values:: Constants, Variables, and Regular @@ -3013,7 +3014,8 @@ used by regular users: `GAWK_SOCK_RETRIES' Controls the number of times `gawk' attempts to retry a two-way TCP/IP (socket) connection before giving up. *Note TCP/IP - Networking::. + Networking::. Note that when nonfatal I/O is enabled (*note + Nonfatal::), `gawk' only tries to open a TCP/IP socket once. `POSIXLY_CORRECT' Causes `gawk' to switch to POSIX-compatibility mode, disabling all @@ -6128,6 +6130,7 @@ function. `gawk' allows access to inherited file descriptors. * Close Files And Pipes:: Closing Input and Output Files and Pipes. +* Nonfatal:: Enabling Nonfatal Output. * Output Summary:: Output summary. * Output Exercises:: Exercises. @@ -7041,7 +7044,7 @@ that `gawk' provides: behavior. -File: gawk.info, Node: Close Files And Pipes, Next: Output Summary, Prev: Special Files, Up: Printing +File: gawk.info, Node: Close Files And Pipes, Next: Nonfatal, Prev: Special Files, Up: Printing 5.9 Closing Input and Output Redirections ========================================= @@ -7210,9 +7213,68 @@ call. See the system manual pages for information on how to decode this value. -File: gawk.info, Node: Output Summary, Next: Output Exercises, Prev: Close Files And Pipes, Up: Printing +File: gawk.info, Node: Nonfatal, Next: Output Summary, Prev: Close Files And Pipes, Up: Printing -5.10 Summary +5.10 Enabling Nonfatal Output +============================= + +This minor node describes a `gawk'-specific feature. + + In standard `awk', output with `print' or `printf' to a nonexistent +file, or some other I/O error (such as filling up the disk) is a fatal +error. + + $ gawk 'BEGIN { print "hi" > "/no/such/file" }' + error--> gawk: cmd. line:1: fatal: can't redirect to `/no/such/file' (No such file or directory) + + `gawk' makes it possible to detect that an error has occurred, +allowing you to possibly recover from the error, or at least print an +error message of your choosing before exiting. You can do this in one +of two ways: + + * For all output files, by assigning any value to + `PROCINFO["NONFATAL"]'. + + * On a per-file basis, by assigning any value to `PROCINFO[FILENAME, + "NONFATAL"]'. Here, FILENAME is the name of the file to which you + wish output to be nonfatal. + + Once you have enabled nonfatal output, you must check `ERRNO' after +every relevant `print' or `printf' statement to see if something went +wrong. It is also a good idea to initialize `ERRNO' to zero before +attempting the output. For example: + + $ gawk ' + > BEGIN { + > PROCINFO["NONFATAL"] = 1 + > ERRNO = 0 + > print "hi" > "/no/such/file" + > if (ERRNO) { + > print("Output failed:", ERRNO) > "/dev/stderr" + > exit 1 + > } + > }' + error--> Output failed: No such file or directory + + Here, `gawk' did not produce a fatal error; instead it let the `awk' +program code detect the problem and handle it. + + This mechanism works also for standard output and standard error. +For standard output, you may use `PROCINFO["-", "NONFATAL"]' or +`PROCINFO["/dev/stdout", "NONFATAL"]'. For standard error, use +`PROCINFO["/dev/stderr", "NONFATAL"]'. + + When attempting to open a TCP/IP socket (*note TCP/IP Networking::), +`gawk' tries multiple times. The `GAWK_SOCK_RETRIES' environment +variable (*note Other Environment Variables::) allows you to override +`gawk''s builtin default number of attempts. However, once nonfatal +I/O is enabled for a given socket, `gawk' only retries once, relying on +`awk'-level code to notice that there was a problem. + + +File: gawk.info, Node: Output Summary, Next: Output Exercises, Prev: Nonfatal, Up: Printing + +5.11 Summary ============ * The `print' statement prints comma-separated expressions. Each @@ -7234,11 +7296,16 @@ File: gawk.info, Node: Output Summary, Next: Output Exercises, Prev: Close Fi For coprocesses, it is possible to close only one direction of the communications. + * Normally errors with `print' or `printf' are fatal. `gawk' lets + you make output errors be nonfatal either for all files or on a + per-file basis. You must then check for errors after every + relevant output statement. + File: gawk.info, Node: Output Exercises, Prev: Output Summary, Up: Printing -5.11 Exercises +5.12 Exercises ============== 1. Rewrite the program: @@ -26479,6 +26546,9 @@ the current version of `gawk'. - Directories on the command line produce a warning and are skipped (*note Command-line directories::) + - Output with `print' and `printf' need not be fatal (*note + Nonfatal::) + * New keywords: - The `BEGINFILE' and `ENDFILE' special patterns (*note @@ -26994,6 +27064,8 @@ in POSIX `awk', in the order they were added to `gawk'. * The maximum number of hexdecimal digits in `\x' escapes is now two. *Note Escape Sequences::. + * Nonfatal output with `print' and `printf'. *Note Nonfatal::. + * Support for MirBSD was removed. @@ -34667,560 +34739,561 @@ Index Tag Table: Node: Top1204 -Node: Foreword342225 -Node: Foreword446669 -Node: Preface48200 -Ref: Preface-Footnote-151071 -Ref: Preface-Footnote-251178 -Ref: Preface-Footnote-351411 -Node: History51553 -Node: Names53904 -Ref: Names-Footnote-154998 -Node: This Manual55144 -Ref: This Manual-Footnote-161644 -Node: Conventions61744 -Node: Manual History64081 -Ref: Manual History-Footnote-167074 -Ref: Manual History-Footnote-267115 -Node: How To Contribute67189 -Node: Acknowledgments68318 -Node: Getting Started73184 -Node: Running gawk75623 -Node: One-shot76813 -Node: Read Terminal78077 -Node: Long80108 -Node: Executable Scripts81621 -Ref: Executable Scripts-Footnote-184410 -Node: Comments84513 -Node: Quoting86995 -Node: DOS Quoting92513 -Node: Sample Data Files93188 -Node: Very Simple95783 -Node: Two Rules100682 -Node: More Complex102568 -Node: Statements/Lines105430 -Ref: Statements/Lines-Footnote-1109885 -Node: Other Features110150 -Node: When111086 -Ref: When-Footnote-1112840 -Node: Intro Summary112905 -Node: Invoking Gawk113789 -Node: Command Line115303 -Node: Options116101 -Ref: Options-Footnote-1131896 -Ref: Options-Footnote-2132125 -Node: Other Arguments132150 -Node: Naming Standard Input135098 -Node: Environment Variables136191 -Node: AWKPATH Variable136749 -Ref: AWKPATH Variable-Footnote-1140156 -Ref: AWKPATH Variable-Footnote-2140201 -Node: AWKLIBPATH Variable140461 -Node: Other Environment Variables141717 -Node: Exit Status145235 -Node: Include Files145911 -Node: Loading Shared Libraries149500 -Node: Obsolete150927 -Node: Undocumented151619 -Node: Invoking Summary151886 -Node: Regexp153549 -Node: Regexp Usage155003 -Node: Escape Sequences157040 -Node: Regexp Operators163269 -Ref: Regexp Operators-Footnote-1170679 -Ref: Regexp Operators-Footnote-2170826 -Node: Bracket Expressions170924 -Ref: table-char-classes172939 -Node: Leftmost Longest175881 -Node: Computed Regexps177183 -Node: GNU Regexp Operators180612 -Node: Case-sensitivity184284 -Ref: Case-sensitivity-Footnote-1187169 -Ref: Case-sensitivity-Footnote-2187404 -Node: Regexp Summary187512 -Node: Reading Files188979 -Node: Records191072 -Node: awk split records191805 -Node: gawk split records196734 -Ref: gawk split records-Footnote-1201273 -Node: Fields201310 -Ref: Fields-Footnote-1204088 -Node: Nonconstant Fields204174 -Ref: Nonconstant Fields-Footnote-1206412 -Node: Changing Fields206615 -Node: Field Separators212546 -Node: Default Field Splitting215250 -Node: Regexp Field Splitting216367 -Node: Single Character Fields219717 -Node: Command Line Field Separator220776 -Node: Full Line Fields223993 -Ref: Full Line Fields-Footnote-1225514 -Ref: Full Line Fields-Footnote-2225560 -Node: Field Splitting Summary225661 -Node: Constant Size227735 -Node: Splitting By Content232318 -Ref: Splitting By Content-Footnote-1236283 -Node: Multiple Line236446 -Ref: Multiple Line-Footnote-1242327 -Node: Getline242506 -Node: Plain Getline244713 -Node: Getline/Variable247353 -Node: Getline/File248502 -Node: Getline/Variable/File249887 -Ref: Getline/Variable/File-Footnote-1251490 -Node: Getline/Pipe251577 -Node: Getline/Variable/Pipe254255 -Node: Getline/Coprocess255386 -Node: Getline/Variable/Coprocess256650 -Node: Getline Notes257389 -Node: Getline Summary260183 -Ref: table-getline-variants260595 -Node: Read Timeout261424 -Ref: Read Timeout-Footnote-1265261 -Node: Command-line directories265319 -Node: Input Summary266224 -Node: Input Exercises269609 -Node: Printing270337 -Node: Print272114 -Node: Print Examples273571 -Node: Output Separators276350 -Node: OFMT278368 -Node: Printf279723 -Node: Basic Printf280508 -Node: Control Letters282080 -Node: Format Modifiers286065 -Node: Printf Examples292071 -Node: Redirection294557 -Node: Special FD301395 -Ref: Special FD-Footnote-1304561 -Node: Special Files304635 -Node: Other Inherited Files305252 -Node: Special Network306252 -Node: Special Caveats307114 -Node: Close Files And Pipes308063 -Ref: Close Files And Pipes-Footnote-1315254 -Ref: Close Files And Pipes-Footnote-2315402 -Node: Output Summary315552 -Node: Output Exercises316550 -Node: Expressions317230 -Node: Values318419 -Node: Constants319096 -Node: Scalar Constants319787 -Ref: Scalar Constants-Footnote-1320649 -Node: Nondecimal-numbers320899 -Node: Regexp Constants323909 -Node: Using Constant Regexps324435 -Node: Variables327598 -Node: Using Variables328255 -Node: Assignment Options330166 -Node: Conversion332041 -Node: Strings And Numbers332565 -Ref: Strings And Numbers-Footnote-1335630 -Node: Locale influences conversions335739 -Ref: table-locale-affects338485 -Node: All Operators339077 -Node: Arithmetic Ops339706 -Node: Concatenation342211 -Ref: Concatenation-Footnote-1345030 -Node: Assignment Ops345137 -Ref: table-assign-ops350116 -Node: Increment Ops351426 -Node: Truth Values and Conditions354857 -Node: Truth Values355940 -Node: Typing and Comparison356989 -Node: Variable Typing357805 -Node: Comparison Operators361472 -Ref: table-relational-ops361882 -Node: POSIX String Comparison365377 -Ref: POSIX String Comparison-Footnote-1366449 -Node: Boolean Ops366588 -Ref: Boolean Ops-Footnote-1371066 -Node: Conditional Exp371157 -Node: Function Calls372895 -Node: Precedence376775 -Node: Locales380435 -Node: Expressions Summary382067 -Node: Patterns and Actions384638 -Node: Pattern Overview385758 -Node: Regexp Patterns387437 -Node: Expression Patterns387980 -Node: Ranges391760 -Node: BEGIN/END394867 -Node: Using BEGIN/END395628 -Ref: Using BEGIN/END-Footnote-1398364 -Node: I/O And BEGIN/END398470 -Node: BEGINFILE/ENDFILE400785 -Node: Empty403682 -Node: Using Shell Variables403999 -Node: Action Overview406272 -Node: Statements408598 -Node: If Statement410446 -Node: While Statement411941 -Node: Do Statement413969 -Node: For Statement415117 -Node: Switch Statement418275 -Node: Break Statement420657 -Node: Continue Statement422750 -Node: Next Statement424577 -Node: Nextfile Statement426958 -Node: Exit Statement429586 -Node: Built-in Variables431997 -Node: User-modified433130 -Ref: User-modified-Footnote-1440764 -Node: Auto-set440826 -Ref: Auto-set-Footnote-1454535 -Ref: Auto-set-Footnote-2454740 -Node: ARGC and ARGV454796 -Node: Pattern Action Summary459014 -Node: Arrays461447 -Node: Array Basics462776 -Node: Array Intro463620 -Ref: figure-array-elements465554 -Ref: Array Intro-Footnote-1468174 -Node: Reference to Elements468302 -Node: Assigning Elements470764 -Node: Array Example471255 -Node: Scanning an Array473014 -Node: Controlling Scanning476034 -Ref: Controlling Scanning-Footnote-1481428 -Node: Numeric Array Subscripts481744 -Node: Uninitialized Subscripts483929 -Node: Delete485546 -Ref: Delete-Footnote-1488295 -Node: Multidimensional488352 -Node: Multiscanning491449 -Node: Arrays of Arrays493038 -Node: Arrays Summary497792 -Node: Functions499883 -Node: Built-in500922 -Node: Calling Built-in502000 -Node: Numeric Functions503995 -Ref: Numeric Functions-Footnote-1508813 -Ref: Numeric Functions-Footnote-2509170 -Ref: Numeric Functions-Footnote-3509218 -Node: String Functions509490 -Ref: String Functions-Footnote-1532991 -Ref: String Functions-Footnote-2533120 -Ref: String Functions-Footnote-3533368 -Node: Gory Details533455 -Ref: table-sub-escapes535236 -Ref: table-sub-proposed536751 -Ref: table-posix-sub538113 -Ref: table-gensub-escapes539650 -Ref: Gory Details-Footnote-1540483 -Node: I/O Functions540634 -Ref: I/O Functions-Footnote-1547870 -Node: Time Functions548017 -Ref: Time Functions-Footnote-1558526 -Ref: Time Functions-Footnote-2558594 -Ref: Time Functions-Footnote-3558752 -Ref: Time Functions-Footnote-4558863 -Ref: Time Functions-Footnote-5558975 -Ref: Time Functions-Footnote-6559202 -Node: Bitwise Functions559468 -Ref: table-bitwise-ops560030 -Ref: Bitwise Functions-Footnote-1564358 -Node: Type Functions564530 -Node: I18N Functions565682 -Node: User-defined567329 -Node: Definition Syntax568134 -Ref: Definition Syntax-Footnote-1573793 -Node: Function Example573864 -Ref: Function Example-Footnote-1576785 -Node: Function Caveats576807 -Node: Calling A Function577325 -Node: Variable Scope578283 -Node: Pass By Value/Reference581276 -Node: Return Statement584773 -Node: Dynamic Typing587752 -Node: Indirect Calls588681 -Ref: Indirect Calls-Footnote-1598546 -Node: Functions Summary598674 -Node: Library Functions601376 -Ref: Library Functions-Footnote-1604984 -Ref: Library Functions-Footnote-2605127 -Node: Library Names605298 -Ref: Library Names-Footnote-1608756 -Ref: Library Names-Footnote-2608979 -Node: General Functions609065 -Node: Strtonum Function610168 -Node: Assert Function613190 -Node: Round Function616514 -Node: Cliff Random Function618055 -Node: Ordinal Functions619071 -Ref: Ordinal Functions-Footnote-1622134 -Ref: Ordinal Functions-Footnote-2622386 -Node: Join Function622597 -Ref: Join Function-Footnote-1624367 -Node: Getlocaltime Function624567 -Node: Readfile Function628311 -Node: Shell Quoting630283 -Node: Data File Management631684 -Node: Filetrans Function632316 -Node: Rewind Function636412 -Node: File Checking637798 -Ref: File Checking-Footnote-1639131 -Node: Empty Files639332 -Node: Ignoring Assigns641311 -Node: Getopt Function642861 -Ref: Getopt Function-Footnote-1654325 -Node: Passwd Functions654525 -Ref: Passwd Functions-Footnote-1663365 -Node: Group Functions663453 -Ref: Group Functions-Footnote-1671350 -Node: Walking Arrays671555 -Node: Library Functions Summary674561 -Node: Library Exercises675963 -Node: Sample Programs677243 -Node: Running Examples678013 -Node: Clones678741 -Node: Cut Program679965 -Node: Egrep Program689685 -Ref: Egrep Program-Footnote-1697188 -Node: Id Program697298 -Node: Split Program700974 -Ref: Split Program-Footnote-1704428 -Node: Tee Program704556 -Node: Uniq Program707345 -Node: Wc Program714764 -Ref: Wc Program-Footnote-1719014 -Node: Miscellaneous Programs719108 -Node: Dupword Program720321 -Node: Alarm Program722352 -Node: Translate Program727157 -Ref: Translate Program-Footnote-1731720 -Node: Labels Program731990 -Ref: Labels Program-Footnote-1735341 -Node: Word Sorting735425 -Node: History Sorting739495 -Node: Extract Program741330 -Node: Simple Sed748854 -Node: Igawk Program751924 -Ref: Igawk Program-Footnote-1766250 -Ref: Igawk Program-Footnote-2766451 -Ref: Igawk Program-Footnote-3766573 -Node: Anagram Program766688 -Node: Signature Program769749 -Node: Programs Summary770996 -Node: Programs Exercises772217 -Ref: Programs Exercises-Footnote-1776348 -Node: Advanced Features776439 -Node: Nondecimal Data778421 -Node: Array Sorting780011 -Node: Controlling Array Traversal780711 -Ref: Controlling Array Traversal-Footnote-1789077 -Node: Array Sorting Functions789195 -Ref: Array Sorting Functions-Footnote-1793081 -Node: Two-way I/O793277 -Ref: Two-way I/O-Footnote-1798222 -Ref: Two-way I/O-Footnote-2798408 -Node: TCP/IP Networking798490 -Node: Profiling801362 -Node: Advanced Features Summary809633 -Node: Internationalization811566 -Node: I18N and L10N813046 -Node: Explaining gettext813732 -Ref: Explaining gettext-Footnote-1818757 -Ref: Explaining gettext-Footnote-2818941 -Node: Programmer i18n819106 -Ref: Programmer i18n-Footnote-1823982 -Node: Translator i18n824031 -Node: String Extraction824825 -Ref: String Extraction-Footnote-1825956 -Node: Printf Ordering826042 -Ref: Printf Ordering-Footnote-1828828 -Node: I18N Portability828892 -Ref: I18N Portability-Footnote-1831348 -Node: I18N Example831411 -Ref: I18N Example-Footnote-1834214 -Node: Gawk I18N834286 -Node: I18N Summary834930 -Node: Debugger836270 -Node: Debugging837292 -Node: Debugging Concepts837733 -Node: Debugging Terms839543 -Node: Awk Debugging842115 -Node: Sample Debugging Session843021 -Node: Debugger Invocation843555 -Node: Finding The Bug844940 -Node: List of Debugger Commands851419 -Node: Breakpoint Control852751 -Node: Debugger Execution Control856428 -Node: Viewing And Changing Data859787 -Node: Execution Stack863163 -Node: Debugger Info864798 -Node: Miscellaneous Debugger Commands868843 -Node: Readline Support873844 -Node: Limitations874738 -Node: Debugging Summary876853 -Node: Arbitrary Precision Arithmetic878027 -Node: Computer Arithmetic879443 -Ref: table-numeric-ranges883042 -Ref: Computer Arithmetic-Footnote-1883566 -Node: Math Definitions883623 -Ref: table-ieee-formats886918 -Ref: Math Definitions-Footnote-1887522 -Node: MPFR features887627 -Node: FP Math Caution889298 -Ref: FP Math Caution-Footnote-1890348 -Node: Inexactness of computations890717 -Node: Inexact representation891676 -Node: Comparing FP Values893034 -Node: Errors accumulate894116 -Node: Getting Accuracy895548 -Node: Try To Round898252 -Node: Setting precision899151 -Ref: table-predefined-precision-strings899835 -Node: Setting the rounding mode901664 -Ref: table-gawk-rounding-modes902028 -Ref: Setting the rounding mode-Footnote-1905480 -Node: Arbitrary Precision Integers905659 -Ref: Arbitrary Precision Integers-Footnote-1910557 -Node: POSIX Floating Point Problems910706 -Ref: POSIX Floating Point Problems-Footnote-1914585 -Node: Floating point summary914623 -Node: Dynamic Extensions916810 -Node: Extension Intro918362 -Node: Plugin License919627 -Node: Extension Mechanism Outline920424 -Ref: figure-load-extension920852 -Ref: figure-register-new-function922332 -Ref: figure-call-new-function923336 -Node: Extension API Description925323 -Node: Extension API Functions Introduction926773 -Node: General Data Types931594 -Ref: General Data Types-Footnote-1937494 -Node: Memory Allocation Functions937793 -Ref: Memory Allocation Functions-Footnote-1940632 -Node: Constructor Functions940731 -Node: Registration Functions942470 -Node: Extension Functions943155 -Node: Exit Callback Functions945452 -Node: Extension Version String946700 -Node: Input Parsers947363 -Node: Output Wrappers957238 -Node: Two-way processors961751 -Node: Printing Messages964014 -Ref: Printing Messages-Footnote-1965090 -Node: Updating `ERRNO'965242 -Node: Requesting Values965982 -Ref: table-value-types-returned966709 -Node: Accessing Parameters967666 -Node: Symbol Table Access968900 -Node: Symbol table by name969414 -Node: Symbol table by cookie971434 -Ref: Symbol table by cookie-Footnote-1975579 -Node: Cached values975642 -Ref: Cached values-Footnote-1979138 -Node: Array Manipulation979229 -Ref: Array Manipulation-Footnote-1980327 -Node: Array Data Types980364 -Ref: Array Data Types-Footnote-1983019 -Node: Array Functions983111 -Node: Flattening Arrays986970 -Node: Creating Arrays993872 -Node: Extension API Variables998643 -Node: Extension Versioning999279 -Node: Extension API Informational Variables1001170 -Node: Extension API Boilerplate1002235 -Node: Finding Extensions1006044 -Node: Extension Example1006604 -Node: Internal File Description1007376 -Node: Internal File Ops1011443 -Ref: Internal File Ops-Footnote-11023194 -Node: Using Internal File Ops1023334 -Ref: Using Internal File Ops-Footnote-11025717 -Node: Extension Samples1025990 -Node: Extension Sample File Functions1027518 -Node: Extension Sample Fnmatch1035199 -Node: Extension Sample Fork1036687 -Node: Extension Sample Inplace1037902 -Node: Extension Sample Ord1039578 -Node: Extension Sample Readdir1040414 -Ref: table-readdir-file-types1041291 -Node: Extension Sample Revout1042102 -Node: Extension Sample Rev2way1042691 -Node: Extension Sample Read write array1043431 -Node: Extension Sample Readfile1045371 -Node: Extension Sample Time1046466 -Node: Extension Sample API Tests1047814 -Node: gawkextlib1048305 -Node: Extension summary1050983 -Node: Extension Exercises1054672 -Node: Language History1055394 -Node: V7/SVR3.11057050 -Node: SVR41059203 -Node: POSIX1060637 -Node: BTL1062018 -Node: POSIX/GNU1062749 -Node: Feature History1068494 -Node: Common Extensions1082220 -Node: Ranges and Locales1083592 -Ref: Ranges and Locales-Footnote-11088211 -Ref: Ranges and Locales-Footnote-21088238 -Ref: Ranges and Locales-Footnote-31088473 -Node: Contributors1088694 -Node: History summary1094234 -Node: Installation1095613 -Node: Gawk Distribution1096559 -Node: Getting1097043 -Node: Extracting1097866 -Node: Distribution contents1099503 -Node: Unix Installation1105605 -Node: Quick Installation1106288 -Node: Shell Startup Files1108699 -Node: Additional Configuration Options1109778 -Node: Configuration Philosophy1111582 -Node: Non-Unix Installation1113951 -Node: PC Installation1114409 -Node: PC Binary Installation1115729 -Node: PC Compiling1117577 -Ref: PC Compiling-Footnote-11120598 -Node: PC Testing1120707 -Node: PC Using1121883 -Node: Cygwin1125998 -Node: MSYS1126768 -Node: VMS Installation1127269 -Node: VMS Compilation1128061 -Ref: VMS Compilation-Footnote-11129290 -Node: VMS Dynamic Extensions1129348 -Node: VMS Installation Details1131032 -Node: VMS Running1133283 -Node: VMS GNV1136123 -Node: VMS Old Gawk1136858 -Node: Bugs1137328 -Node: Other Versions1141217 -Node: Installation summary1147651 -Node: Notes1148710 -Node: Compatibility Mode1149575 -Node: Additions1150357 -Node: Accessing The Source1151282 -Node: Adding Code1152717 -Node: New Ports1158874 -Node: Derived Files1163356 -Ref: Derived Files-Footnote-11168831 -Ref: Derived Files-Footnote-21168865 -Ref: Derived Files-Footnote-31169461 -Node: Future Extensions1169575 -Node: Implementation Limitations1170181 -Node: Extension Design1171429 -Node: Old Extension Problems1172583 -Ref: Old Extension Problems-Footnote-11174100 -Node: Extension New Mechanism Goals1174157 -Ref: Extension New Mechanism Goals-Footnote-11177517 -Node: Extension Other Design Decisions1177706 -Node: Extension Future Growth1179814 -Node: Old Extension Mechanism1180650 -Node: Notes summary1182412 -Node: Basic Concepts1183598 -Node: Basic High Level1184279 -Ref: figure-general-flow1184551 -Ref: figure-process-flow1185150 -Ref: Basic High Level-Footnote-11188379 -Node: Basic Data Typing1188564 -Node: Glossary1191892 -Node: Copying1223821 -Node: GNU Free Documentation License1261377 -Node: Index1286513 +Node: Foreword342291 +Node: Foreword446735 +Node: Preface48266 +Ref: Preface-Footnote-151137 +Ref: Preface-Footnote-251244 +Ref: Preface-Footnote-351477 +Node: History51619 +Node: Names53970 +Ref: Names-Footnote-155064 +Node: This Manual55210 +Ref: This Manual-Footnote-161710 +Node: Conventions61810 +Node: Manual History64147 +Ref: Manual History-Footnote-167140 +Ref: Manual History-Footnote-267181 +Node: How To Contribute67255 +Node: Acknowledgments68384 +Node: Getting Started73250 +Node: Running gawk75689 +Node: One-shot76879 +Node: Read Terminal78143 +Node: Long80174 +Node: Executable Scripts81687 +Ref: Executable Scripts-Footnote-184476 +Node: Comments84579 +Node: Quoting87061 +Node: DOS Quoting92579 +Node: Sample Data Files93254 +Node: Very Simple95849 +Node: Two Rules100748 +Node: More Complex102634 +Node: Statements/Lines105496 +Ref: Statements/Lines-Footnote-1109951 +Node: Other Features110216 +Node: When111152 +Ref: When-Footnote-1112906 +Node: Intro Summary112971 +Node: Invoking Gawk113855 +Node: Command Line115369 +Node: Options116167 +Ref: Options-Footnote-1131962 +Ref: Options-Footnote-2132191 +Node: Other Arguments132216 +Node: Naming Standard Input135164 +Node: Environment Variables136257 +Node: AWKPATH Variable136815 +Ref: AWKPATH Variable-Footnote-1140222 +Ref: AWKPATH Variable-Footnote-2140267 +Node: AWKLIBPATH Variable140527 +Node: Other Environment Variables141783 +Node: Exit Status145414 +Node: Include Files146090 +Node: Loading Shared Libraries149679 +Node: Obsolete151106 +Node: Undocumented151798 +Node: Invoking Summary152065 +Node: Regexp153728 +Node: Regexp Usage155182 +Node: Escape Sequences157219 +Node: Regexp Operators163448 +Ref: Regexp Operators-Footnote-1170858 +Ref: Regexp Operators-Footnote-2171005 +Node: Bracket Expressions171103 +Ref: table-char-classes173118 +Node: Leftmost Longest176060 +Node: Computed Regexps177362 +Node: GNU Regexp Operators180791 +Node: Case-sensitivity184463 +Ref: Case-sensitivity-Footnote-1187348 +Ref: Case-sensitivity-Footnote-2187583 +Node: Regexp Summary187691 +Node: Reading Files189158 +Node: Records191251 +Node: awk split records191984 +Node: gawk split records196913 +Ref: gawk split records-Footnote-1201452 +Node: Fields201489 +Ref: Fields-Footnote-1204267 +Node: Nonconstant Fields204353 +Ref: Nonconstant Fields-Footnote-1206591 +Node: Changing Fields206794 +Node: Field Separators212725 +Node: Default Field Splitting215429 +Node: Regexp Field Splitting216546 +Node: Single Character Fields219896 +Node: Command Line Field Separator220955 +Node: Full Line Fields224172 +Ref: Full Line Fields-Footnote-1225693 +Ref: Full Line Fields-Footnote-2225739 +Node: Field Splitting Summary225840 +Node: Constant Size227914 +Node: Splitting By Content232497 +Ref: Splitting By Content-Footnote-1236462 +Node: Multiple Line236625 +Ref: Multiple Line-Footnote-1242506 +Node: Getline242685 +Node: Plain Getline244892 +Node: Getline/Variable247532 +Node: Getline/File248681 +Node: Getline/Variable/File250066 +Ref: Getline/Variable/File-Footnote-1251669 +Node: Getline/Pipe251756 +Node: Getline/Variable/Pipe254434 +Node: Getline/Coprocess255565 +Node: Getline/Variable/Coprocess256829 +Node: Getline Notes257568 +Node: Getline Summary260362 +Ref: table-getline-variants260774 +Node: Read Timeout261603 +Ref: Read Timeout-Footnote-1265440 +Node: Command-line directories265498 +Node: Input Summary266403 +Node: Input Exercises269788 +Node: Printing270516 +Node: Print272351 +Node: Print Examples273808 +Node: Output Separators276587 +Node: OFMT278605 +Node: Printf279960 +Node: Basic Printf280745 +Node: Control Letters282317 +Node: Format Modifiers286302 +Node: Printf Examples292308 +Node: Redirection294794 +Node: Special FD301632 +Ref: Special FD-Footnote-1304798 +Node: Special Files304872 +Node: Other Inherited Files305489 +Node: Special Network306489 +Node: Special Caveats307351 +Node: Close Files And Pipes308300 +Ref: Close Files And Pipes-Footnote-1315485 +Ref: Close Files And Pipes-Footnote-2315633 +Node: Nonfatal315783 +Node: Output Summary318108 +Node: Output Exercises319329 +Node: Expressions320009 +Node: Values321198 +Node: Constants321875 +Node: Scalar Constants322566 +Ref: Scalar Constants-Footnote-1323428 +Node: Nondecimal-numbers323678 +Node: Regexp Constants326688 +Node: Using Constant Regexps327214 +Node: Variables330377 +Node: Using Variables331034 +Node: Assignment Options332945 +Node: Conversion334820 +Node: Strings And Numbers335344 +Ref: Strings And Numbers-Footnote-1338409 +Node: Locale influences conversions338518 +Ref: table-locale-affects341264 +Node: All Operators341856 +Node: Arithmetic Ops342485 +Node: Concatenation344990 +Ref: Concatenation-Footnote-1347809 +Node: Assignment Ops347916 +Ref: table-assign-ops352895 +Node: Increment Ops354205 +Node: Truth Values and Conditions357636 +Node: Truth Values358719 +Node: Typing and Comparison359768 +Node: Variable Typing360584 +Node: Comparison Operators364251 +Ref: table-relational-ops364661 +Node: POSIX String Comparison368156 +Ref: POSIX String Comparison-Footnote-1369228 +Node: Boolean Ops369367 +Ref: Boolean Ops-Footnote-1373845 +Node: Conditional Exp373936 +Node: Function Calls375674 +Node: Precedence379554 +Node: Locales383214 +Node: Expressions Summary384846 +Node: Patterns and Actions387417 +Node: Pattern Overview388537 +Node: Regexp Patterns390216 +Node: Expression Patterns390759 +Node: Ranges394539 +Node: BEGIN/END397646 +Node: Using BEGIN/END398407 +Ref: Using BEGIN/END-Footnote-1401143 +Node: I/O And BEGIN/END401249 +Node: BEGINFILE/ENDFILE403564 +Node: Empty406461 +Node: Using Shell Variables406778 +Node: Action Overview409051 +Node: Statements411377 +Node: If Statement413225 +Node: While Statement414720 +Node: Do Statement416748 +Node: For Statement417896 +Node: Switch Statement421054 +Node: Break Statement423436 +Node: Continue Statement425529 +Node: Next Statement427356 +Node: Nextfile Statement429737 +Node: Exit Statement432365 +Node: Built-in Variables434776 +Node: User-modified435909 +Ref: User-modified-Footnote-1443543 +Node: Auto-set443605 +Ref: Auto-set-Footnote-1457314 +Ref: Auto-set-Footnote-2457519 +Node: ARGC and ARGV457575 +Node: Pattern Action Summary461793 +Node: Arrays464226 +Node: Array Basics465555 +Node: Array Intro466399 +Ref: figure-array-elements468333 +Ref: Array Intro-Footnote-1470953 +Node: Reference to Elements471081 +Node: Assigning Elements473543 +Node: Array Example474034 +Node: Scanning an Array475793 +Node: Controlling Scanning478813 +Ref: Controlling Scanning-Footnote-1484207 +Node: Numeric Array Subscripts484523 +Node: Uninitialized Subscripts486708 +Node: Delete488325 +Ref: Delete-Footnote-1491074 +Node: Multidimensional491131 +Node: Multiscanning494228 +Node: Arrays of Arrays495817 +Node: Arrays Summary500571 +Node: Functions502662 +Node: Built-in503701 +Node: Calling Built-in504779 +Node: Numeric Functions506774 +Ref: Numeric Functions-Footnote-1511592 +Ref: Numeric Functions-Footnote-2511949 +Ref: Numeric Functions-Footnote-3511997 +Node: String Functions512269 +Ref: String Functions-Footnote-1535770 +Ref: String Functions-Footnote-2535899 +Ref: String Functions-Footnote-3536147 +Node: Gory Details536234 +Ref: table-sub-escapes538015 +Ref: table-sub-proposed539530 +Ref: table-posix-sub540892 +Ref: table-gensub-escapes542429 +Ref: Gory Details-Footnote-1543262 +Node: I/O Functions543413 +Ref: I/O Functions-Footnote-1550649 +Node: Time Functions550796 +Ref: Time Functions-Footnote-1561305 +Ref: Time Functions-Footnote-2561373 +Ref: Time Functions-Footnote-3561531 +Ref: Time Functions-Footnote-4561642 +Ref: Time Functions-Footnote-5561754 +Ref: Time Functions-Footnote-6561981 +Node: Bitwise Functions562247 +Ref: table-bitwise-ops562809 +Ref: Bitwise Functions-Footnote-1567137 +Node: Type Functions567309 +Node: I18N Functions568461 +Node: User-defined570108 +Node: Definition Syntax570913 +Ref: Definition Syntax-Footnote-1576572 +Node: Function Example576643 +Ref: Function Example-Footnote-1579564 +Node: Function Caveats579586 +Node: Calling A Function580104 +Node: Variable Scope581062 +Node: Pass By Value/Reference584055 +Node: Return Statement587552 +Node: Dynamic Typing590531 +Node: Indirect Calls591460 +Ref: Indirect Calls-Footnote-1601325 +Node: Functions Summary601453 +Node: Library Functions604155 +Ref: Library Functions-Footnote-1607763 +Ref: Library Functions-Footnote-2607906 +Node: Library Names608077 +Ref: Library Names-Footnote-1611535 +Ref: Library Names-Footnote-2611758 +Node: General Functions611844 +Node: Strtonum Function612947 +Node: Assert Function615969 +Node: Round Function619293 +Node: Cliff Random Function620834 +Node: Ordinal Functions621850 +Ref: Ordinal Functions-Footnote-1624913 +Ref: Ordinal Functions-Footnote-2625165 +Node: Join Function625376 +Ref: Join Function-Footnote-1627146 +Node: Getlocaltime Function627346 +Node: Readfile Function631090 +Node: Shell Quoting633062 +Node: Data File Management634463 +Node: Filetrans Function635095 +Node: Rewind Function639191 +Node: File Checking640577 +Ref: File Checking-Footnote-1641910 +Node: Empty Files642111 +Node: Ignoring Assigns644090 +Node: Getopt Function645640 +Ref: Getopt Function-Footnote-1657104 +Node: Passwd Functions657304 +Ref: Passwd Functions-Footnote-1666144 +Node: Group Functions666232 +Ref: Group Functions-Footnote-1674129 +Node: Walking Arrays674334 +Node: Library Functions Summary677340 +Node: Library Exercises678742 +Node: Sample Programs680022 +Node: Running Examples680792 +Node: Clones681520 +Node: Cut Program682744 +Node: Egrep Program692464 +Ref: Egrep Program-Footnote-1699967 +Node: Id Program700077 +Node: Split Program703753 +Ref: Split Program-Footnote-1707207 +Node: Tee Program707335 +Node: Uniq Program710124 +Node: Wc Program717543 +Ref: Wc Program-Footnote-1721793 +Node: Miscellaneous Programs721887 +Node: Dupword Program723100 +Node: Alarm Program725131 +Node: Translate Program729936 +Ref: Translate Program-Footnote-1734499 +Node: Labels Program734769 +Ref: Labels Program-Footnote-1738120 +Node: Word Sorting738204 +Node: History Sorting742274 +Node: Extract Program744109 +Node: Simple Sed751633 +Node: Igawk Program754703 +Ref: Igawk Program-Footnote-1769029 +Ref: Igawk Program-Footnote-2769230 +Ref: Igawk Program-Footnote-3769352 +Node: Anagram Program769467 +Node: Signature Program772528 +Node: Programs Summary773775 +Node: Programs Exercises774996 +Ref: Programs Exercises-Footnote-1779127 +Node: Advanced Features779218 +Node: Nondecimal Data781200 +Node: Array Sorting782790 +Node: Controlling Array Traversal783490 +Ref: Controlling Array Traversal-Footnote-1791856 +Node: Array Sorting Functions791974 +Ref: Array Sorting Functions-Footnote-1795860 +Node: Two-way I/O796056 +Ref: Two-way I/O-Footnote-1801001 +Ref: Two-way I/O-Footnote-2801187 +Node: TCP/IP Networking801269 +Node: Profiling804141 +Node: Advanced Features Summary812412 +Node: Internationalization814345 +Node: I18N and L10N815825 +Node: Explaining gettext816511 +Ref: Explaining gettext-Footnote-1821536 +Ref: Explaining gettext-Footnote-2821720 +Node: Programmer i18n821885 +Ref: Programmer i18n-Footnote-1826761 +Node: Translator i18n826810 +Node: String Extraction827604 +Ref: String Extraction-Footnote-1828735 +Node: Printf Ordering828821 +Ref: Printf Ordering-Footnote-1831607 +Node: I18N Portability831671 +Ref: I18N Portability-Footnote-1834127 +Node: I18N Example834190 +Ref: I18N Example-Footnote-1836993 +Node: Gawk I18N837065 +Node: I18N Summary837709 +Node: Debugger839049 +Node: Debugging840071 +Node: Debugging Concepts840512 +Node: Debugging Terms842322 +Node: Awk Debugging844894 +Node: Sample Debugging Session845800 +Node: Debugger Invocation846334 +Node: Finding The Bug847719 +Node: List of Debugger Commands854198 +Node: Breakpoint Control855530 +Node: Debugger Execution Control859207 +Node: Viewing And Changing Data862566 +Node: Execution Stack865942 +Node: Debugger Info867577 +Node: Miscellaneous Debugger Commands871622 +Node: Readline Support876623 +Node: Limitations877517 +Node: Debugging Summary879632 +Node: Arbitrary Precision Arithmetic880806 +Node: Computer Arithmetic882222 +Ref: table-numeric-ranges885821 +Ref: Computer Arithmetic-Footnote-1886345 +Node: Math Definitions886402 +Ref: table-ieee-formats889697 +Ref: Math Definitions-Footnote-1890301 +Node: MPFR features890406 +Node: FP Math Caution892077 +Ref: FP Math Caution-Footnote-1893127 +Node: Inexactness of computations893496 +Node: Inexact representation894455 +Node: Comparing FP Values895813 +Node: Errors accumulate896895 +Node: Getting Accuracy898327 +Node: Try To Round901031 +Node: Setting precision901930 +Ref: table-predefined-precision-strings902614 +Node: Setting the rounding mode904443 +Ref: table-gawk-rounding-modes904807 +Ref: Setting the rounding mode-Footnote-1908259 +Node: Arbitrary Precision Integers908438 +Ref: Arbitrary Precision Integers-Footnote-1913336 +Node: POSIX Floating Point Problems913485 +Ref: POSIX Floating Point Problems-Footnote-1917364 +Node: Floating point summary917402 +Node: Dynamic Extensions919589 +Node: Extension Intro921141 +Node: Plugin License922406 +Node: Extension Mechanism Outline923203 +Ref: figure-load-extension923631 +Ref: figure-register-new-function925111 +Ref: figure-call-new-function926115 +Node: Extension API Description928102 +Node: Extension API Functions Introduction929552 +Node: General Data Types934373 +Ref: General Data Types-Footnote-1940273 +Node: Memory Allocation Functions940572 +Ref: Memory Allocation Functions-Footnote-1943411 +Node: Constructor Functions943510 +Node: Registration Functions945249 +Node: Extension Functions945934 +Node: Exit Callback Functions948231 +Node: Extension Version String949479 +Node: Input Parsers950142 +Node: Output Wrappers960017 +Node: Two-way processors964530 +Node: Printing Messages966793 +Ref: Printing Messages-Footnote-1967869 +Node: Updating `ERRNO'968021 +Node: Requesting Values968761 +Ref: table-value-types-returned969488 +Node: Accessing Parameters970445 +Node: Symbol Table Access971679 +Node: Symbol table by name972193 +Node: Symbol table by cookie974213 +Ref: Symbol table by cookie-Footnote-1978358 +Node: Cached values978421 +Ref: Cached values-Footnote-1981917 +Node: Array Manipulation982008 +Ref: Array Manipulation-Footnote-1983106 +Node: Array Data Types983143 +Ref: Array Data Types-Footnote-1985798 +Node: Array Functions985890 +Node: Flattening Arrays989749 +Node: Creating Arrays996651 +Node: Extension API Variables1001422 +Node: Extension Versioning1002058 +Node: Extension API Informational Variables1003949 +Node: Extension API Boilerplate1005014 +Node: Finding Extensions1008823 +Node: Extension Example1009383 +Node: Internal File Description1010155 +Node: Internal File Ops1014222 +Ref: Internal File Ops-Footnote-11025973 +Node: Using Internal File Ops1026113 +Ref: Using Internal File Ops-Footnote-11028496 +Node: Extension Samples1028769 +Node: Extension Sample File Functions1030297 +Node: Extension Sample Fnmatch1037978 +Node: Extension Sample Fork1039466 +Node: Extension Sample Inplace1040681 +Node: Extension Sample Ord1042357 +Node: Extension Sample Readdir1043193 +Ref: table-readdir-file-types1044070 +Node: Extension Sample Revout1044881 +Node: Extension Sample Rev2way1045470 +Node: Extension Sample Read write array1046210 +Node: Extension Sample Readfile1048150 +Node: Extension Sample Time1049245 +Node: Extension Sample API Tests1050593 +Node: gawkextlib1051084 +Node: Extension summary1053762 +Node: Extension Exercises1057451 +Node: Language History1058173 +Node: V7/SVR3.11059829 +Node: SVR41061982 +Node: POSIX1063416 +Node: BTL1064797 +Node: POSIX/GNU1065528 +Node: Feature History1071364 +Node: Common Extensions1085158 +Node: Ranges and Locales1086530 +Ref: Ranges and Locales-Footnote-11091149 +Ref: Ranges and Locales-Footnote-21091176 +Ref: Ranges and Locales-Footnote-31091411 +Node: Contributors1091632 +Node: History summary1097172 +Node: Installation1098551 +Node: Gawk Distribution1099497 +Node: Getting1099981 +Node: Extracting1100804 +Node: Distribution contents1102441 +Node: Unix Installation1108543 +Node: Quick Installation1109226 +Node: Shell Startup Files1111637 +Node: Additional Configuration Options1112716 +Node: Configuration Philosophy1114520 +Node: Non-Unix Installation1116889 +Node: PC Installation1117347 +Node: PC Binary Installation1118667 +Node: PC Compiling1120515 +Ref: PC Compiling-Footnote-11123536 +Node: PC Testing1123645 +Node: PC Using1124821 +Node: Cygwin1128936 +Node: MSYS1129706 +Node: VMS Installation1130207 +Node: VMS Compilation1130999 +Ref: VMS Compilation-Footnote-11132228 +Node: VMS Dynamic Extensions1132286 +Node: VMS Installation Details1133970 +Node: VMS Running1136221 +Node: VMS GNV1139061 +Node: VMS Old Gawk1139796 +Node: Bugs1140266 +Node: Other Versions1144155 +Node: Installation summary1150589 +Node: Notes1151648 +Node: Compatibility Mode1152513 +Node: Additions1153295 +Node: Accessing The Source1154220 +Node: Adding Code1155655 +Node: New Ports1161812 +Node: Derived Files1166294 +Ref: Derived Files-Footnote-11171769 +Ref: Derived Files-Footnote-21171803 +Ref: Derived Files-Footnote-31172399 +Node: Future Extensions1172513 +Node: Implementation Limitations1173119 +Node: Extension Design1174367 +Node: Old Extension Problems1175521 +Ref: Old Extension Problems-Footnote-11177038 +Node: Extension New Mechanism Goals1177095 +Ref: Extension New Mechanism Goals-Footnote-11180455 +Node: Extension Other Design Decisions1180644 +Node: Extension Future Growth1182752 +Node: Old Extension Mechanism1183588 +Node: Notes summary1185350 +Node: Basic Concepts1186536 +Node: Basic High Level1187217 +Ref: figure-general-flow1187489 +Ref: figure-process-flow1188088 +Ref: Basic High Level-Footnote-11191317 +Node: Basic Data Typing1191502 +Node: Glossary1194830 +Node: Copying1226759 +Node: GNU Free Documentation License1264315 +Node: Index1289451 End Tag Table diff --git a/doc/gawk.texi b/doc/gawk.texi index 2b49c245..615330d1 100644 --- a/doc/gawk.texi +++ b/doc/gawk.texi @@ -633,6 +633,7 @@ particular records in a file and perform operations upon them. * Special Caveats:: Things to watch out for. * Close Files And Pipes:: Closing Input and Output Files and Pipes. +* Nonfatal:: Enabling Nonfatal Output. * Output Summary:: Output summary. * Output Exercises:: Exercises. * Values:: Constants, Variables, and Regular @@ -4549,6 +4550,8 @@ wait for input before returning with an error. Controls the number of times @command{gawk} attempts to retry a two-way TCP/IP (socket) connection before giving up. @xref{TCP/IP Networking}. +Note that when nonfatal I/O is enabled (@pxref{Nonfatal}), +@command{gawk} only tries to open a TCP/IP socket once. @item POSIXLY_CORRECT Causes @command{gawk} to switch to POSIX-compatibility @@ -8935,6 +8938,7 @@ and discusses the @code{close()} built-in function. @command{gawk} allows access to inherited file descriptors. * Close Files And Pipes:: Closing Input and Output Files and Pipes. +* Nonfatal:: Enabling Nonfatal Output. * Output Summary:: Output summary. * Output Exercises:: Exercises. @end menu @@ -10441,6 +10445,71 @@ when closing a pipe. @end ifnotdocbook +@node Nonfatal +@section Enabling Nonfatal Output + +This @value{SECTION} describes a @command{gawk}-specific feature. + +In standard @command{awk}, output with @code{print} or @code{printf} +to a nonexistent file, or some other I/O error (such as filling up the +disk) is a fatal error. + +@example +$ @kbd{gawk 'BEGIN @{ print "hi" > "/no/such/file" @}'} +@error{} gawk: cmd. line:1: fatal: can't redirect to `/no/such/file' (No such file or directory) +@end example + +@command{gawk} makes it possible to detect that an error has +occurred, allowing you to possibly recover from the error, or +at least print an error message of your choosing before exiting. +You can do this in one of two ways: + +@itemize @bullet +@item +For all output files, by assigning any value to @code{PROCINFO["NONFATAL"]}. + +@item +On a per-file basis, by assigning any value to +@code{PROCINFO[@var{filename}, "NONFATAL"]}. +Here, @var{filename} is the name of the file to which +you wish output to be nonfatal. +@end itemize + +Once you have enabled nonfatal output, you must check @code{ERRNO} +after every relevant @code{print} or @code{printf} statement to +see if something went wrong. It is also a good idea to initialize +@code{ERRNO} to zero before attempting the output. For example: + +@example +$ @kbd{gawk '} +> @kbd{BEGIN @{} +> @kbd{ PROCINFO["NONFATAL"] = 1} +> @kbd{ ERRNO = 0} +> @kbd{ print "hi" > "/no/such/file"} +> @kbd{ if (ERRNO) @{} +> @kbd{ print("Output failed:", ERRNO) > "/dev/stderr"} +> @kbd{ exit 1} +> @kbd{ @}} +> @kbd{@}'} +@error{} Output failed: No such file or directory +@end example + +Here, @command{gawk} did not produce a fatal error; instead +it let the @command{awk} program code detect the problem and handle it. + +This mechanism works also for standard output and standard error. +For standard output, you may use @code{PROCINFO["-", "NONFATAL"]} +or @code{PROCINFO["/dev/stdout", "NONFATAL"]}. For standard error, use +@code{PROCINFO["/dev/stderr", "NONFATAL"]}. + +When attempting to open a TCP/IP socket (@pxref{TCP/IP Networking}), +@command{gawk} tries multiple times. The @env{GAWK_SOCK_RETRIES} +environment variable (@pxref{Other Environment Variables}) allows you to +override @command{gawk}'s builtin default number of attempts. However, +once nonfatal I/O is enabled for a given socket, @command{gawk} only +retries once, relying on @command{awk}-level code to notice that there +was a problem. + @node Output Summary @section Summary @@ -10469,6 +10538,12 @@ Use @code{close()} to close open file, pipe, and coprocess redirections. For coprocesses, it is possible to close only one direction of the communications. +@item +Normally errors with @code{print} or @code{printf} are fatal. +@command{gawk} lets you make output errors be nonfatal either for +all files or on a per-file basis. You must then check for errors +after every relevant output statement. + @end itemize @c EXCLUDE START @@ -35703,6 +35778,10 @@ Indirect function calls @item Directories on the command line produce a warning and are skipped (@pxref{Command-line directories}) + +@item +Output with @code{print} and @code{printf} need not be fatal +(@pxref{Nonfatal}) @end itemize @item @@ -36582,6 +36661,10 @@ is now two. @xref{Escape Sequences}. @item +Nonfatal output with @code{print} and @code{printf}. +@xref{Nonfatal}. + +@item Support for MirBSD was removed. @end itemize diff --git a/doc/gawktexi.in b/doc/gawktexi.in index 713f354f..8612876e 100644 --- a/doc/gawktexi.in +++ b/doc/gawktexi.in @@ -628,6 +628,7 @@ particular records in a file and perform operations upon them. * Special Caveats:: Things to watch out for. * Close Files And Pipes:: Closing Input and Output Files and Pipes. +* Nonfatal:: Enabling Nonfatal Output. * Output Summary:: Output summary. * Output Exercises:: Exercises. * Values:: Constants, Variables, and Regular @@ -4460,6 +4461,8 @@ wait for input before returning with an error. Controls the number of times @command{gawk} attempts to retry a two-way TCP/IP (socket) connection before giving up. @xref{TCP/IP Networking}. +Note that when nonfatal I/O is enabled (@pxref{Nonfatal}), +@command{gawk} only tries to open a TCP/IP socket once. @item POSIXLY_CORRECT Causes @command{gawk} to switch to POSIX-compatibility @@ -8535,6 +8538,7 @@ and discusses the @code{close()} built-in function. @command{gawk} allows access to inherited file descriptors. * Close Files And Pipes:: Closing Input and Output Files and Pipes. +* Nonfatal:: Enabling Nonfatal Output. * Output Summary:: Output summary. * Output Exercises:: Exercises. @end menu @@ -9937,6 +9941,71 @@ when closing a pipe. @end sidebar +@node Nonfatal +@section Enabling Nonfatal Output + +This @value{SECTION} describes a @command{gawk}-specific feature. + +In standard @command{awk}, output with @code{print} or @code{printf} +to a nonexistent file, or some other I/O error (such as filling up the +disk) is a fatal error. + +@example +$ @kbd{gawk 'BEGIN @{ print "hi" > "/no/such/file" @}'} +@error{} gawk: cmd. line:1: fatal: can't redirect to `/no/such/file' (No such file or directory) +@end example + +@command{gawk} makes it possible to detect that an error has +occurred, allowing you to possibly recover from the error, or +at least print an error message of your choosing before exiting. +You can do this in one of two ways: + +@itemize @bullet +@item +For all output files, by assigning any value to @code{PROCINFO["NONFATAL"]}. + +@item +On a per-file basis, by assigning any value to +@code{PROCINFO[@var{filename}, "NONFATAL"]}. +Here, @var{filename} is the name of the file to which +you wish output to be nonfatal. +@end itemize + +Once you have enabled nonfatal output, you must check @code{ERRNO} +after every relevant @code{print} or @code{printf} statement to +see if something went wrong. It is also a good idea to initialize +@code{ERRNO} to zero before attempting the output. For example: + +@example +$ @kbd{gawk '} +> @kbd{BEGIN @{} +> @kbd{ PROCINFO["NONFATAL"] = 1} +> @kbd{ ERRNO = 0} +> @kbd{ print "hi" > "/no/such/file"} +> @kbd{ if (ERRNO) @{} +> @kbd{ print("Output failed:", ERRNO) > "/dev/stderr"} +> @kbd{ exit 1} +> @kbd{ @}} +> @kbd{@}'} +@error{} Output failed: No such file or directory +@end example + +Here, @command{gawk} did not produce a fatal error; instead +it let the @command{awk} program code detect the problem and handle it. + +This mechanism works also for standard output and standard error. +For standard output, you may use @code{PROCINFO["-", "NONFATAL"]} +or @code{PROCINFO["/dev/stdout", "NONFATAL"]}. For standard error, use +@code{PROCINFO["/dev/stderr", "NONFATAL"]}. + +When attempting to open a TCP/IP socket (@pxref{TCP/IP Networking}), +@command{gawk} tries multiple times. The @env{GAWK_SOCK_RETRIES} +environment variable (@pxref{Other Environment Variables}) allows you to +override @command{gawk}'s builtin default number of attempts. However, +once nonfatal I/O is enabled for a given socket, @command{gawk} only +retries once, relying on @command{awk}-level code to notice that there +was a problem. + @node Output Summary @section Summary @@ -9965,6 +10034,12 @@ Use @code{close()} to close open file, pipe, and coprocess redirections. For coprocesses, it is possible to close only one direction of the communications. +@item +Normally errors with @code{print} or @code{printf} are fatal. +@command{gawk} lets you make output errors be nonfatal either for +all files or on a per-file basis. You must then check for errors +after every relevant output statement. + @end itemize @c EXCLUDE START @@ -34794,6 +34869,10 @@ Indirect function calls @item Directories on the command line produce a warning and are skipped (@pxref{Command-line directories}) + +@item +Output with @code{print} and @code{printf} need not be fatal +(@pxref{Nonfatal}) @end itemize @item @@ -35673,6 +35752,10 @@ is now two. @xref{Escape Sequences}. @item +Nonfatal output with @code{print} and @code{printf}. +@xref{Nonfatal}. + +@item Support for MirBSD was removed. @end itemize @@ -261,7 +261,6 @@ struct recmatch { static int iop_close(IOBUF *iop); -struct redirect *redirect(NODE *redir_exp, int redirtype, int *errflg); static void close_one(void); static int close_redir(struct redirect *rp, bool exitwarn, two_way_close_type how); #ifndef PIPES_SIMULATED @@ -727,7 +726,7 @@ redflags2str(int flags) /* redirect --- Redirection for printf and print commands */ struct redirect * -redirect(NODE *redir_exp, int redirtype, int *errflg) +redirect(NODE *redir_exp, int redirtype, int *errflg, bool failure_fatal) { struct redirect *rp; char *str; @@ -892,6 +891,12 @@ redirect(NODE *redir_exp, int redirtype, int *errflg) (void) flush_io(); os_restore_mode(fileno(stdin)); + /* + * Don't check failure_fatal; see input pipe below. + * Note that the failure happens upon failure to fork, + * using a non-existant program will still succeed the + * popen(). + */ if ((rp->output.fp = popen(str, binmode("w"))) == NULL) fatal(_("can't open pipe `%s' for output (%s)"), str, strerror(errno)); @@ -927,13 +932,11 @@ redirect(NODE *redir_exp, int redirtype, int *errflg) case redirect_twoway: direction = "to/from"; if (! two_way_open(str, rp)) { -#ifdef HAVE_SOCKETS - if (inetfile(str, NULL)) { + if (! failure_fatal || is_non_fatal_redirect(str)) { *errflg = errno; /* do not free rp, saving it for reuse (save_rp = rp) */ return NULL; } else -#endif fatal(_("can't open two way pipe `%s' for input/output (%s)"), str, strerror(errno)); } @@ -1009,11 +1012,14 @@ redirect(NODE *redir_exp, int redirtype, int *errflg) * can return -1. For output to file, * complain. The shell will complain on * a bad command to a pipe. + * + * 12/2014: Take nonfatal settings in PROCINFO into account. */ if (errflg != NULL) *errflg = errno; - if ( redirtype == redirect_output - || redirtype == redirect_append) { + if (failure_fatal && ! is_non_fatal_redirect(str) && + (redirtype == redirect_output + || redirtype == redirect_append)) { /* multiple messages make life easier for translators */ if (*direction == 'f') fatal(_("can't redirect from `%s' (%s)"), @@ -1058,6 +1064,36 @@ getredirect(const char *str, int len) return NULL; } +/* is_non_fatal_std --- return true if fp is stdout/stderr and nonfatal */ + +bool +is_non_fatal_std(FILE *fp) +{ + static const char nonfatal[] = "NONFATAL"; + + if (in_PROCINFO(nonfatal, NULL, NULL)) + return true; + + /* yucky logic. sigh. */ + if (fp == stdout) { + return ( in_PROCINFO("-", nonfatal, NULL) != NULL + || in_PROCINFO("/dev/stdout", nonfatal, NULL) != NULL); + } else if (fp == stderr) { + return (in_PROCINFO("/dev/stderr", nonfatal, NULL) != NULL); + } + + return false; +} + +/* is_non_fatal_redirect --- return true if redirected I/O should be nonfatal */ + +bool +is_non_fatal_redirect(const char *str) +{ + return in_PROCINFO("NONFATAL", NULL, NULL) != NULL + || in_PROCINFO(str, "NONFATAL", NULL) != NULL; +} + /* close_one --- temporarily close an open file to re-use the fd */ static void @@ -1430,7 +1466,7 @@ str2mode(const char *mode) static int socketopen(int family, int type, const char *localpname, - const char *remotepname, const char *remotehostname) + const char *remotepname, const char *remotehostname, bool *hard_error) { struct addrinfo *lres, *lres0; struct addrinfo lhints; @@ -1449,8 +1485,11 @@ socketopen(int family, int type, const char *localpname, lerror = getaddrinfo(NULL, localpname, & lhints, & lres); if (lerror) { - if (strcmp(localpname, "0") != 0) - fatal(_("local port %s invalid in `/inet'"), localpname); + if (strcmp(localpname, "0") != 0) { + warning(_("local port %s invalid in `/inet'"), localpname); + *hard_error = true; + return INVALID_HANDLE; + } lres0 = NULL; lres = & lhints; } else @@ -1468,7 +1507,9 @@ socketopen(int family, int type, const char *localpname, if (rerror) { if (lres0 != NULL) freeaddrinfo(lres0); - fatal(_("remote host and port information (%s, %s) invalid"), remotehostname, remotepname); + warning(_("remote host and port information (%s, %s) invalid"), remotehostname, remotepname); + *hard_error = true; + return INVALID_HANDLE; } rres0 = rres; socket_fd = INVALID_HANDLE; @@ -1577,6 +1618,7 @@ devopen(const char *name, const char *mode) char *ptr; int flag = 0; struct inet_socket_info isi; + int save_errno = 0; if (strcmp(name, "-") == 0) return fileno(stdin); @@ -1619,6 +1661,14 @@ devopen(const char *name, const char *mode) goto strictopen; } else if (inetfile(name, & isi)) { #ifdef HAVE_SOCKETS +#define DEFAULT_RETRIES 20 + static unsigned long def_retries = DEFAULT_RETRIES; + static bool first_time = true; + unsigned long retries = 0; + static long msleep = 1000; + bool hard_error = false; + bool non_fatal = is_non_fatal_redirect(name); + cp = (char *) name; /* socketopen requires NUL-terminated strings */ @@ -1626,13 +1676,6 @@ devopen(const char *name, const char *mode) cp[isi.remotehost.offset+isi.remotehost.len] = '\0'; /* remoteport comes last, so already NUL-terminated */ - { -#define DEFAULT_RETRIES 20 - static unsigned long def_retries = DEFAULT_RETRIES; - static bool first_time = true; - unsigned long retries = 0; - static long msleep = 1000; - if (first_time) { char *cp, *end; unsigned long count = 0; @@ -1658,25 +1701,41 @@ devopen(const char *name, const char *mode) msleep *= 1000; } } - retries = def_retries; + /* + * PROCINFO["NONFATAL"] or PROCINFO[name, "NONFATAL"] overrrides + * GAWK_SOCK_RETRIES. The explicit code in the program carries + * a bigger stick than the environment variable does. + */ + retries = non_fatal ? 1 : def_retries; + errno = 0; do { - openfd = socketopen(isi.family, isi.protocol, name+isi.localport.offset, name+isi.remoteport.offset, name+isi.remotehost.offset); + openfd = socketopen(isi.family, isi.protocol, name+isi.localport.offset, + name+isi.remoteport.offset, name+isi.remotehost.offset, + & hard_error); retries--; - } while (openfd == INVALID_HANDLE && retries > 0 && usleep(msleep) == 0); - } + } while (openfd == INVALID_HANDLE && ! hard_error && retries > 0 && usleep(msleep) == 0); + save_errno = errno; - /* restore original name string */ - cp[isi.localport.offset+isi.localport.len] = '/'; - cp[isi.remotehost.offset+isi.remotehost.len] = '/'; + /* restore original name string */ + cp[isi.localport.offset+isi.localport.len] = '/'; + cp[isi.remotehost.offset+isi.remotehost.len] = '/'; #else /* ! HAVE_SOCKETS */ - fatal(_("TCP/IP communications are not supported")); + fatal(_("TCP/IP communications are not supported")); #endif /* HAVE_SOCKETS */ } strictopen: - if (openfd == INVALID_HANDLE) + if (openfd == INVALID_HANDLE) { openfd = open(name, flag, 0666); + /* + * ENOENT means there is no such name in the filesystem. + * Therefore it's ok to propagate up the error from + * getaddrinfo() that's in save_errno. + */ + if (openfd == INVALID_HANDLE && errno == ENOENT && save_errno) + errno = save_errno; + } #if defined(__EMX__) || defined(__MINGW32__) if (openfd == INVALID_HANDLE && errno == EACCES) { /* On OS/2 and Windows directory access via open() is @@ -2421,7 +2480,7 @@ do_getline_redir(int into_variable, enum redirval redirtype) assert(redirtype != redirect_none); redir_exp = TOP(); - rp = redirect(redir_exp, redirtype, & redir_error); + rp = redirect(redir_exp, redirtype, & redir_error, false); DEREF(redir_exp); decr_sp(); if (rp == NULL) { @@ -3656,8 +3715,10 @@ pty_vs_pipe(const char *command) #ifdef HAVE_TERMIOS_H NODE *val; - if (PROCINFO_node == NULL) - return false; + /* + * N.B. No need to check for NULL PROCINFO_node, since the + * in_PROCINFO function now checks that for us. + */ val = in_PROCINFO(command, "pty", NULL); if (val) { if ((val->flags & MAYBE_NUM) != 0) @@ -3799,12 +3860,21 @@ in_PROCINFO(const char *pidx1, const char *pidx2, NODE **full_idx) NODE *r, *sub = NULL; NODE *subsep = SUBSEP_node->var_value; + if (PROCINFO_node == NULL || (pidx1 == NULL && pidx2 == NULL)) + return NULL; + /* full_idx is in+out parameter */ if (full_idx) sub = *full_idx; - str_len = strlen(pidx1) + subsep->stlen + strlen(pidx2); + if (pidx1 != NULL && pidx2 == NULL) + str_len = strlen(pidx1); + else if (pidx1 == NULL && pidx2 != NULL) + str_len = strlen(pidx2); + else + str_len = strlen(pidx1) + subsep->stlen + strlen(pidx2); + if (sub == NULL) { emalloc(str, char *, str_len + 1, "in_PROCINFO"); sub = make_str_node(str, str_len, ALREADY_MALLOCED); @@ -3818,8 +3888,14 @@ in_PROCINFO(const char *pidx1, const char *pidx2, NODE **full_idx) sub->stlen = str_len; } - sprintf(sub->stptr, "%s%.*s%s", pidx1, (int)subsep->stlen, - subsep->stptr, pidx2); + if (pidx1 != NULL && pidx2 == NULL) + strcpy(sub->stptr, pidx1); + else if (pidx1 == NULL && pidx2 != NULL) + strcpy(sub->stptr, pidx2); + else + sprintf(sub->stptr, "%s%.*s%s", pidx1, (int)subsep->stlen, + subsep->stptr, pidx2); + r = in_array(PROCINFO_node, sub); if (! full_idx) unref(sub); diff --git a/missing_d/ChangeLog b/missing_d/ChangeLog index 70fbde64..89dbdb4d 100644 --- a/missing_d/ChangeLog +++ b/missing_d/ChangeLog @@ -1,3 +1,9 @@ +2015-02-27 Arnold D. Robbins <arnold@skeeve.com> + + * getaddrinfo.h (gai_strerror): Add declaration. + * getaddrinfo.c (gai_strerror): New function. + (getaddrinfo): Return errno values instead of just -1. + 2014-04-08 Arnold D. Robbins <arnold@skeeve.com> * 4.1.1: Release tar ball made. diff --git a/missing_d/getaddrinfo.c b/missing_d/getaddrinfo.c index 677f27d0..f24ac598 100644 --- a/missing_d/getaddrinfo.c +++ b/missing_d/getaddrinfo.c @@ -12,6 +12,8 @@ #ifdef HAVE_ARPA_INET_H #include <arpa/inet.h> #endif +#include <errno.h> +#include <string.h> /* strerror */ #include "getaddrinfo.h" @@ -29,12 +31,12 @@ getaddrinfo(const char *hostname, const char *portname, { struct addrinfo *out; if (res == NULL) - return -1; + return EINVAL; out = (struct addrinfo *) malloc(sizeof(*out)); if (out == NULL) { *res = NULL; - return -1; + return ENOMEM; } memset(out, '\0', sizeof(*out)); @@ -42,7 +44,7 @@ getaddrinfo(const char *hostname, const char *portname, if (out->ai_addr == NULL) { free(out); *res = NULL; - return -1; + return ENOMEM; } out->ai_socktype = SOCK_STREAM; @@ -78,7 +80,7 @@ getaddrinfo(const char *hostname, const char *portname, = ((struct in_addr *)he->h_addr_list[0])->s_addr; } else { freeaddrinfo(out); - return -1; + return EADDRNOTAVAIL; } } else { if (!(out->ai_flags & AI_PASSIVE)) @@ -109,4 +111,10 @@ getaddrinfo(const char *hostname, const char *portname, return 0; } + +const char * +gai_strerror(int errcode) +{ + return strerror(errcode); +} #endif diff --git a/missing_d/getaddrinfo.h b/missing_d/getaddrinfo.h index 3d816c93..873d67df 100644 --- a/missing_d/getaddrinfo.h +++ b/missing_d/getaddrinfo.h @@ -29,3 +29,5 @@ void freeaddrinfo(struct xaddrinfo * res); int getaddrinfo(const char * hostname, const char * portname, struct xaddrinfo * hints, struct xaddrinfo ** res); + +const char *gai_strerror(int errcode); diff --git a/test/ChangeLog b/test/ChangeLog index a5c77c69..2652429f 100644 --- a/test/ChangeLog +++ b/test/ChangeLog @@ -3,6 +3,27 @@ * charasbytes.awk, ofs1.awk, range1.awk, sortglos.awk, sortglos.in: Remove execute permission. +2015-03-02 Andrew J. Schorr <aschorr@telemetry-investments.com> + + * nonfatal1.awk: Do not print ERRNO, since the value appears to be + platform-dependent. Instead, print (ERRNO != ""). + * nonfatal1.ok: Update. + +2015-02-28 Andrew J. Schorr <aschorr@telemetry-investments.com> + + * Makefile.am (EXTRA_DIST): Add nonfatal3.{awk,ok}. + (GAWK_EXT_TESTS): Add nonfatal3. + * nonfatal1.awk: Replace "ti10/357" with "local:host/25", since + "local:host" should be a universally bad hostname due to the + invalid ":" character. + * nonfatal1.ok: Update. + * nonfatal3.{awk,ok}: New test for connecting to a TCP port where + nobody is listening. + +2015-02-27 Arnold D. Robbins <arnold@skeeve.com> + + * nonfatal1.ok: Update after code changes. + 2015-02-26 Arnold D. Robbins <arnold@skeeve.com> * Makefile.am (EXTRA_DIST): Add profile0.in which got forgotten @@ -18,6 +39,16 @@ * Makefile.am (profile0): New test. * profile0.awk, profile0.in, profile0.ok: New files. +2015-02-08 Arnold D. Robbins <arnold@skeeve.com> + + * nonfatal1.awk, nonfatal2.awk: String is now "NONFATAL". + +2015-02-06 Arnold D. Robbins <arnold@skeeve.com> + + * Makefile.am (nonfatal1, nonfatal2): New tests. + * nonfatal1.awk, nonfatal1.ok: New files. + * nonfatal2.awk, nonfatal2.ok: New files. + 2015-02-01 Arnold D. Robbins <arnold@skeeve.com> * Makefile.am (paramasfunc1, paramasfunc2): Now need --posix. diff --git a/test/Makefile.am b/test/Makefile.am index e752865a..15656ce6 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -599,6 +599,12 @@ EXTRA_DIST = \ nondec.ok \ nondec2.awk \ nondec2.ok \ + nonfatal1.awk \ + nonfatal1.ok \ + nonfatal2.awk \ + nonfatal2.ok \ + nonfatal3.awk \ + nonfatal3.ok \ nonl.awk \ nonl.ok \ noparms.awk \ @@ -1047,6 +1053,7 @@ GAWK_EXT_TESTS = \ lint lintold lintwarn \ manyfiles match1 match2 match3 mbstr1 \ nastyparm next nondec nondec2 \ + nonfatal1 nonfatal2 nonfatal3 \ patsplit posix printfbad1 printfbad2 printfbad3 printfbad4 printhuge procinfs \ profile0 profile1 profile2 profile3 profile4 profile5 profile6 profile7 \ profile8 pty1 \ diff --git a/test/Makefile.in b/test/Makefile.in index 0c00973c..87f9bf56 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -856,6 +856,12 @@ EXTRA_DIST = \ nondec.ok \ nondec2.awk \ nondec2.ok \ + nonfatal1.awk \ + nonfatal1.ok \ + nonfatal2.awk \ + nonfatal2.ok \ + nonfatal3.awk \ + nonfatal3.ok \ nonl.awk \ nonl.ok \ noparms.awk \ @@ -1303,6 +1309,7 @@ GAWK_EXT_TESTS = \ lint lintold lintwarn \ manyfiles match1 match2 match3 mbstr1 \ nastyparm next nondec nondec2 \ + nonfatal1 nonfatal2 nonfatal3 \ patsplit posix printfbad1 printfbad2 printfbad3 printfbad4 printhuge procinfs \ profile0 profile1 profile2 profile3 profile4 profile5 profile6 profile7 \ profile8 pty1 \ @@ -3636,6 +3643,21 @@ nondec: @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ +nonfatal1: + @echo $@ + @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ + +nonfatal2: + @echo $@ + @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ + +nonfatal3: + @echo $@ + @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ + patsplit: @echo $@ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ diff --git a/test/Maketests b/test/Maketests index adf95cc5..a2937451 100644 --- a/test/Maketests +++ b/test/Maketests @@ -1152,6 +1152,21 @@ nondec: @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ +nonfatal1: + @echo $@ + @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ + +nonfatal2: + @echo $@ + @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ + +nonfatal3: + @echo $@ + @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ + @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@ + patsplit: @echo $@ @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@ diff --git a/test/nonfatal1.awk b/test/nonfatal1.awk new file mode 100644 index 00000000..a9228f3a --- /dev/null +++ b/test/nonfatal1.awk @@ -0,0 +1,6 @@ +BEGIN { + PROCINFO["NONFATAL"] + # note that ":" is not a valid hostname character + print |& "/inet/tcp/0/local:host/25" + print (ERRNO != "") +} diff --git a/test/nonfatal1.ok b/test/nonfatal1.ok new file mode 100644 index 00000000..51583f2c --- /dev/null +++ b/test/nonfatal1.ok @@ -0,0 +1,2 @@ +gawk: nonfatal1.awk:4: warning: remote host and port information (local:host, 25) invalid +1 diff --git a/test/nonfatal2.awk b/test/nonfatal2.awk new file mode 100644 index 00000000..fedbba43 --- /dev/null +++ b/test/nonfatal2.awk @@ -0,0 +1,5 @@ +BEGIN { + PROCINFO["NONFATAL"] = 1 + print > "/dev/no/such/file" + print ERRNO +} diff --git a/test/nonfatal2.ok b/test/nonfatal2.ok new file mode 100644 index 00000000..ddc88691 --- /dev/null +++ b/test/nonfatal2.ok @@ -0,0 +1 @@ +No such file or directory diff --git a/test/nonfatal3.awk b/test/nonfatal3.awk new file mode 100644 index 00000000..eace9aec --- /dev/null +++ b/test/nonfatal3.awk @@ -0,0 +1,6 @@ +BEGIN { + PROCINFO["NONFATAL"] + # valid host but bogus port + print |& "/inet/tcp/0/localhost/0" + print ERRNO +} diff --git a/test/nonfatal3.ok b/test/nonfatal3.ok new file mode 100644 index 00000000..5d5be35a --- /dev/null +++ b/test/nonfatal3.ok @@ -0,0 +1 @@ +Connection refused |