aboutsummaryrefslogtreecommitdiffstats
path: root/extension
diff options
context:
space:
mode:
authorAndrew J. Schorr <aschorr@telemetry-investments.com>2014-11-06 14:18:37 -0500
committerAndrew J. Schorr <aschorr@telemetry-investments.com>2014-11-06 14:18:37 -0500
commite3f20c041c078eacf648af94d9f012e4906359bb (patch)
tree0561839b7fcd51fbd2be8995edfcfa164747068b /extension
parentc483c50817e8accd0d5052d41d00869330193175 (diff)
downloadegawk-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/ChangeLog12
-rw-r--r--extension/errno.c2
-rw-r--r--extension/select.c41
-rw-r--r--extension/testext.c60
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 */