diff options
author | Andrew J. Schorr <aschorr@telemetry-investments.com> | 2014-11-06 14:18:37 -0500 |
---|---|---|
committer | Andrew J. Schorr <aschorr@telemetry-investments.com> | 2014-11-06 14:18:37 -0500 |
commit | e3f20c041c078eacf648af94d9f012e4906359bb (patch) | |
tree | 0561839b7fcd51fbd2be8995edfcfa164747068b /extension | |
parent | c483c50817e8accd0d5052d41d00869330193175 (diff) | |
download | egawk-e3f20c041c078eacf648af94d9f012e4906359bb.tar.gz egawk-e3f20c041c078eacf648af94d9f012e4906359bb.tar.bz2 egawk-e3f20c041c078eacf648af94d9f012e4906359bb.zip |
Enhance get_file API to return info about input and output and to enable extensions to create already-opened files or sockets.
Diffstat (limited to 'extension')
-rw-r--r-- | extension/ChangeLog | 12 | ||||
-rw-r--r-- | extension/errno.c | 2 | ||||
-rw-r--r-- | extension/select.c | 41 | ||||
-rw-r--r-- | extension/testext.c | 60 |
4 files changed, 104 insertions, 11 deletions
diff --git a/extension/ChangeLog b/extension/ChangeLog index 5d278f6c..b8e68674 100644 --- a/extension/ChangeLog +++ b/extension/ChangeLog @@ -1,3 +1,15 @@ +2014-11-06 Andrew J. Schorr <aschorr@telemetry-investments.com> + + * errno.c (do_errno2name, do_name2errno): Remove unused variable 'str'. + * select.c (do_signal): Remove unused variable 'override'. + (grabfd): New helper function to map a gawk file to the appropriate + fd for use in the arguments to selectd. + (do_select): get_file has 3 new arguments and returns info about both + the input and output buf. + (do_set_non_blocking): Support changes to get_file API. + * testext.c (test_get_file): New test function to check that extension + file creation via the get_file API is working. + 2014-11-05 Andrew J. Schorr <aschorr@telemetry-investments.com> * select.c (set_retry): New function to set PROCINFO[<name>, "RETRY"]. diff --git a/extension/errno.c b/extension/errno.c index 2eafa437..5dc15d79 100644 --- a/extension/errno.c +++ b/extension/errno.c @@ -86,7 +86,6 @@ static awk_value_t * do_errno2name(int nargs, awk_value_t *result) { awk_value_t errnum; - const char *str; if (do_lint && nargs > 1) lintwarn(ext_id, _("errno2name: called with too many arguments")); @@ -112,7 +111,6 @@ static awk_value_t * do_name2errno(int nargs, awk_value_t *result) { awk_value_t err; - const char *str; if (do_lint && nargs > 1) lintwarn(ext_id, _("name2errno: called with too many arguments")); diff --git a/extension/select.c b/extension/select.c index 1752ee34..597b3a6b 100644 --- a/extension/select.c +++ b/extension/select.c @@ -223,7 +223,6 @@ do_signal(int nargs, awk_value_t *result) #ifdef HAVE_SIGACTION { - awk_value_t override; struct sigaction sa, prev; sa.sa_handler = func; sigfillset(& sa.sa_mask); /* block all signals in handler */ @@ -307,6 +306,27 @@ do_kill(int nargs, awk_value_t *result) #endif } +static int +grabfd(int i, const awk_input_buf_t *ibuf, const awk_output_buf_t *obuf, const char *fnm, const char *ftp) +{ + switch (i) { + case 0: /* read */ + return ibuf ? ibuf->fd : -1; + case 1: /* write */ + return obuf ? fileno(obuf->fp) : -1; + case 2: /* except */ + if (ibuf) { + if (obuf && ibuf->fd != fileno(obuf->fp)) + warning(ext_id, _("select: `%s', `%s' in `except' array has clashing fds, using input %d, not output %d"), fnm, ftp, ibuf->fd, fileno(obuf->fp)); + return ibuf->fd; + } + if (obuf) + return fileno(obuf->fp); + break; + } + return -1; +} + /* do_select --- I/O multiplexing */ static awk_value_t * @@ -362,9 +382,11 @@ do_select(int nargs, awk_value_t *result) if (((EL.value.val_type == AWK_UNDEFINED) || ((EL.value.val_type == AWK_STRING) && ! EL.value.str_value.len)) && (integer_string(EL.index.str_value.str, &x) == 0) && (x >= 0)) fds[i].array2fd[j] = x; else if (EL.value.val_type == AWK_STRING) { - const awk_input_buf_t *buf; - if ((buf = get_file(EL.index.str_value.str, EL.index.str_value.len, EL.value.str_value.str, EL.value.str_value.len)) != NULL) - fds[i].array2fd[j] = buf->fd; + const awk_input_buf_t *ibuf; + const awk_output_buf_t *obuf; + int fd; + if (get_file(EL.index.str_value.str, EL.index.str_value.len, EL.value.str_value.str, EL.value.str_value.len, -1, &ibuf, &obuf) && ((fd = grabfd(i, ibuf, obuf, EL.index.str_value.str, EL.value.str_value.str)) >= 0)) + fds[i].array2fd[j] = fd; else warning(ext_id, _("select: get_file(`%s', `%s') failed in `%s' array"), EL.index.str_value.str, EL.value.str_value.str, argname[i]); } @@ -566,11 +588,12 @@ do_set_non_blocking(int nargs, awk_value_t *result) else if (get_argument(0, AWK_STRING, & cmd) && (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) { - int rc = set_non_blocking(buf->fd); - if (rc == 0) - set_retry(buf->name); + 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)) { + int rc = set_non_blocking(ibuf ? ibuf->fd : fileno(obuf->fp)); + if (rc == 0 && ibuf) + set_retry(ibuf->name); return make_number(rc, result); } warning(ext_id, _("set_non_blocking: get_file(`%s', `%s') failed"), cmd.str_value.str, cmdtype.str_value.str); diff --git a/extension/testext.c b/extension/testext.c index 7462265b..3ac1f124 100644 --- a/extension/testext.c +++ b/extension/testext.c @@ -37,6 +37,7 @@ #include <sys/types.h> #include <sys/stat.h> +#include <fcntl.h> #include "gawkapi.h" @@ -710,6 +711,7 @@ BEGIN { ret = test_indirect_vars() # should get correct value of NR printf("test_indirect_var() return %d\n", ret) delete ARGV[1] + print "" } */ @@ -742,6 +744,63 @@ out: return result; } +/* +BEGIN { + outfile = "testexttmp.txt" + alias = ".test.alias" + print "line 1" > outfile + print "line 2" > outfile + print "line 3" > outfile + close(outfile) + ret = test_get_file(outfile, alias) + printf "test_get_file returned %d\n", ret + nr = 0 + while ((getline < alias) > 0) + printf "File [%s] nr [%s]: %s\n", alias, ++nr, $0 + close(alias) + system("rm " outfile) + print "" +} +*/ + +/* test_get_file --- test that we can create a file */ + +static awk_value_t * +test_get_file(int nargs, awk_value_t *result) +{ + awk_value_t filename, alias; + int fd; + const awk_input_buf_t *ibuf; + const awk_output_buf_t *obuf; + + if (nargs != 2) { + printf("%s: nargs not right (%d should be 2)\n", __func__, nargs); + return make_number(-1.0, result); + } + + if (! get_argument(0, AWK_STRING, & filename)) { + printf("%s: cannot get first arg\n", __func__); + return make_number(-1.0, result); + } + if (! get_argument(1, AWK_STRING, & alias)) { + printf("%s: cannot get first arg\n", __func__); + 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); + 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); + 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); + return make_number(-1.0, result); + } + return make_number(0.0, result); +} + /* fill_in_array --- fill in a new array */ static void @@ -837,6 +896,7 @@ static awk_ext_func_t func_table[] = { { "test_scalar", test_scalar, 1 }, { "test_scalar_reserved", test_scalar_reserved, 0 }, { "test_indirect_vars", test_indirect_vars, 0 }, + { "test_get_file", test_get_file, 2 }, }; /* init_testext --- additional initialization function */ |