diff options
-rw-r--r-- | extension/ChangeLog | 10 | ||||
-rw-r--r-- | extension/select.c | 63 | ||||
-rw-r--r-- | extension/testext.c | 12 |
3 files changed, 79 insertions, 6 deletions
diff --git a/extension/ChangeLog b/extension/ChangeLog index b8e68674..ba0d3bfa 100644 --- a/extension/ChangeLog +++ b/extension/ChangeLog @@ -1,3 +1,13 @@ +2014-11-09 Andrew J. Schorr <aschorr@telemetry-investments.com> + + * select.c (do_input_fd): New function to return the input file + descriptor associated with a file/command. + (do_output_fd): New function to return the output file descriptor + associated with a file/command. + (func_table): Add new functions "input_fd" and "output_fd". + * testext.c (test_get_file): Do not use __func__, since it is a C99 + feature, and gawk does not assume C99. + 2014-11-06 Andrew J. Schorr <aschorr@telemetry-investments.com> * errno.c (do_errno2name, do_name2errno): Remove unused variable 'str'. diff --git a/extension/select.c b/extension/select.c index 597b3a6b..b2105b75 100644 --- a/extension/select.c +++ b/extension/select.c @@ -606,11 +606,74 @@ do_set_non_blocking(int nargs, awk_value_t *result) return make_number(-1, result); } +/* do_input_fd --- Return command's input file descriptor */ + +static awk_value_t * +do_input_fd(int nargs, awk_value_t *result) +{ + awk_value_t cmd, cmdtype; + + if (do_lint && nargs > 2) + lintwarn(ext_id, _("input_fd: 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_STRING, & cmd) && + (get_argument(1, AWK_STRING, & cmdtype) || + (! cmd.str_value.len && (nargs == 1)))) { + const awk_input_buf_t *ibuf; + const awk_output_buf_t *obuf; + if (get_file(cmd.str_value.str, cmd.str_value.len, cmdtype.str_value.str, cmdtype.str_value.len, -1, &ibuf, &obuf) && ibuf) + return make_number(ibuf->fd, result); + warning(ext_id, _("input_fd: get_file(`%s', `%s') failed to return an input descriptor"), cmd.str_value.str, cmdtype.str_value.str); + } else if (do_lint) { + if (nargs < 2) + lintwarn(ext_id, _("input_fd: called with too few arguments")); + else + lintwarn(ext_id, _("input_fd: called with inappropriate argument(s)")); + } + return make_number(-1, result); +} + +/* do_output_fd --- Return command's output file descriptor */ + +static awk_value_t * +do_output_fd(int nargs, awk_value_t *result) +{ + awk_value_t cmd, cmdtype; + + if (do_lint && nargs > 2) + lintwarn(ext_id, _("output_fd: called with too many arguments")); + /* + * N.B. If called with a single "" arg, it will not work, since there + * is no output fd associated the current input file. + */ + if (get_argument(0, AWK_STRING, & cmd) && + get_argument(1, AWK_STRING, & cmdtype)) { + const awk_input_buf_t *ibuf; + const awk_output_buf_t *obuf; + if (get_file(cmd.str_value.str, cmd.str_value.len, cmdtype.str_value.str, cmdtype.str_value.len, -1, &ibuf, &obuf) && obuf) + return make_number(fileno(obuf->fp), result); + warning(ext_id, _("output_fd: get_file(`%s', `%s') failed to return an output descriptor"), cmd.str_value.str, cmdtype.str_value.str); + } else if (do_lint) { + if (nargs < 2) + lintwarn(ext_id, _("output_fd: called with too few arguments")); + else + lintwarn(ext_id, _("output_fd: called with inappropriate argument(s)")); + } + return make_number(-1, result); +} + static awk_ext_func_t func_table[] = { { "select", do_select, 5 }, { "select_signal", do_signal, 3 }, { "set_non_blocking", do_set_non_blocking, 2 }, { "kill", do_kill, 2 }, + { "input_fd", do_input_fd, 2 }, + { "output_fd", do_output_fd, 2 }, }; /* define the dl_load function using the boilerplate macro */ diff --git a/extension/testext.c b/extension/testext.c index 3ac1f124..f00ced7d 100644 --- a/extension/testext.c +++ b/extension/testext.c @@ -774,28 +774,28 @@ test_get_file(int nargs, awk_value_t *result) const awk_output_buf_t *obuf; if (nargs != 2) { - printf("%s: nargs not right (%d should be 2)\n", __func__, nargs); + printf("%s: nargs not right (%d should be 2)\n", "test_get_file", nargs); return make_number(-1.0, result); } if (! get_argument(0, AWK_STRING, & filename)) { - printf("%s: cannot get first arg\n", __func__); + printf("%s: cannot get first arg\n", "test_get_file"); return make_number(-1.0, result); } if (! get_argument(1, AWK_STRING, & alias)) { - printf("%s: cannot get first arg\n", __func__); + printf("%s: cannot get first arg\n", "test_get_file"); return make_number(-1.0, result); } if ((fd = open(filename.str_value.str, O_RDONLY)) < 0) { - printf("%s: open(%s) failed\n", __func__, filename.str_value.str); + printf("%s: open(%s) failed\n", "test_get_file", filename.str_value.str); return make_number(-1.0, result); } if (! get_file(alias.str_value.str, strlen(alias.str_value.str), "<", 1, fd, &ibuf, &obuf)) { - printf("%s: get_file(%s) failed\n", __func__, alias.str_value.str); + printf("%s: get_file(%s) failed\n", "test_get_file", alias.str_value.str); return make_number(-1.0, result); } if (! ibuf || ibuf->fd != fd) { - printf("%s: get_file(%s) returned fd %d instead of %d\n", __func__, alias.str_value.str, ibuf ? ibuf->fd : -1, fd); + printf("%s: get_file(%s) returned fd %d instead of %d\n", "test_get_file", alias.str_value.str, ibuf ? ibuf->fd : -1, fd); return make_number(-1.0, result); } return make_number(0.0, result); |