aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew J. Schorr <aschorr@telemetry-investments.com>2014-11-09 09:09:57 -0500
committerAndrew J. Schorr <aschorr@telemetry-investments.com>2014-11-09 09:09:57 -0500
commitd0299eb46c0f4551d355591a58e88715fee139e7 (patch)
treecb547fc8fa25c42811622a29b4e43902ade05a9b
parente3f20c041c078eacf648af94d9f012e4906359bb (diff)
downloadegawk-d0299eb46c0f4551d355591a58e88715fee139e7.tar.gz
egawk-d0299eb46c0f4551d355591a58e88715fee139e7.tar.bz2
egawk-d0299eb46c0f4551d355591a58e88715fee139e7.zip
Add new functions input_fd and output_fd to the select extension.
-rw-r--r--extension/ChangeLog10
-rw-r--r--extension/select.c63
-rw-r--r--extension/testext.c12
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);