diff options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | extension/ChangeLog | 6 | ||||
-rw-r--r-- | extension/select.c | 20 | ||||
-rw-r--r-- | gawkapi.h | 4 |
4 files changed, 29 insertions, 6 deletions
@@ -1,3 +1,8 @@ +2013-07-05 Andrew J. Schorr <aschorr@telemetry-investments.com> + + * gawkapi.h (gawk_api): Document that the api_get_file function will not + access the file type and length arguments if the file name is empty. + 2013-07-04 Andrew J. Schorr <aschorr@telemetry-investments.com> * configure.ac (AC_CHECK_FUNCS): Add a check for waitpid. diff --git a/extension/ChangeLog b/extension/ChangeLog index 4108f74c..68ba6fe2 100644 --- a/extension/ChangeLog +++ b/extension/ChangeLog @@ -1,5 +1,11 @@ 2013-07-05 Andrew J. Schorr <aschorr@telemetry-investments.com> + * select.c (set_non_blocking): Do not attempt F_SETFL if F_GETFL fails. + (do_set_non_blocking): Add support for case when called with a single + "" argument. + +2013-07-05 Andrew J. Schorr <aschorr@telemetry-investments.com> + * select.c (do_signal): If sigaction is unavailable, fall back to signal and hope that it does the right thing. diff --git a/extension/select.c b/extension/select.c index 44b60d50..4d28457d 100644 --- a/extension/select.c +++ b/extension/select.c @@ -413,11 +413,14 @@ do_select(int nargs, awk_value_t *result) static int set_non_blocking(int fd) { - int flags = fcntl(fd, F_GETFL); - int rc = fcntl(fd, F_SETFL, (flags|O_NONBLOCK)); - if (rc < 0) + int flags; + + if (((flags = fcntl(fd, F_GETFL)) == -1) || + (fcntl(fd, F_SETFL, (flags|O_NONBLOCK)) == -1)) { update_ERRNO_int(errno); - return rc; + return -1; + } + return 0; } /* do_set_non_blocking --- Set a file to be non-blocking */ @@ -430,12 +433,19 @@ do_set_non_blocking(int nargs, awk_value_t *result) if (do_lint && nargs > 2) lintwarn(ext_id, _("set_non_blocking: called with too many arguments")); + /* + * N.B. If called with a single "" arg, we want it to work! In that + * case, the 1st arg is an empty string, and get_argument fails on the + * 2nd arg. Note that API get_file promises not to access the type + * argument if the name argument is an empty string. + */ if (get_argument(0, AWK_NUMBER, & cmd) && (cmd.num_value == (fd = cmd.num_value)) && ! get_argument(1, AWK_STRING, & cmdtype)) return make_number(set_non_blocking(fd), result); else if (get_argument(0, AWK_STRING, & cmd) && - get_argument(1, AWK_STRING, & cmdtype)) { + (get_argument(1, AWK_STRING, & cmdtype) || + (! cmd.str_value.len && (nargs == 1)))) { const awk_input_buf_t *buf; if ((buf = get_file(cmd.str_value.str, cmd.str_value.len, cmdtype.str_value.str, cmdtype.str_value.len)) != NULL) return make_number(set_non_blocking(buf->fd), result); @@ -668,7 +668,9 @@ typedef struct gawk_api { /* * Look up a file. If the name is NULL or name_len is 0, it returns - * data for the currently open input file corresponding to FILENAME. + * data for the currently open input file corresponding to FILENAME + * (and it will not access the filetype or typelen arguments, so those + * may be undefined). * If the file is not already open, it tries to open it. * The "filetype" argument should be one of: * ">", ">>", "<", "|>", "|<", and "|&" |