diff options
-rw-r--r-- | extension/ChangeLog | 10 | ||||
-rw-r--r-- | extension/Makefile.am | 8 | ||||
-rw-r--r-- | extension/Makefile.in | 23 | ||||
-rw-r--r-- | extension/configh.in | 15 | ||||
-rwxr-xr-x | extension/configure | 7 | ||||
-rw-r--r-- | extension/configure.ac | 7 | ||||
-rw-r--r-- | extension/select.c | 681 | ||||
-rw-r--r-- | extension/siglist.h | 76 |
8 files changed, 20 insertions, 807 deletions
diff --git a/extension/ChangeLog b/extension/ChangeLog index 053ba50b..e8fa12fd 100644 --- a/extension/ChangeLog +++ b/extension/ChangeLog @@ -1,3 +1,13 @@ +2015-01-02 Andrew J. Schorr <aschorr@telemetry-investments.com> + + Remove the select extension, since it will be part of gawkextlib. + * select.c, siglist.h: Deleted. + * Makefile.am (pkgextension_LTLIBRARIES): Remove select.la. + (select_la_SOURCES, select_la_LDFLAGS, select_la_LIBADD): Remove. + (EXTRA_DIST): Remove siglist.h. + * configure.ac (AC_CHECK_HEADERS): Remove signal.h. + (AC_CHECK_FUNCS): Remove fcntl, kill, sigaction, and sigprocmask. + 2014-12-14 Andrew J. Schorr <aschorr@telemetry-investments.com> Remove the errno extension, since it is now part of gawkextlib. diff --git a/extension/Makefile.am b/extension/Makefile.am index 5c0df894..b9dabfe2 100644 --- a/extension/Makefile.am +++ b/extension/Makefile.am @@ -45,7 +45,6 @@ pkgextension_LTLIBRARIES = \ revoutput.la \ revtwoway.la \ rwarray.la \ - select.la \ testext.la \ time.la @@ -94,10 +93,6 @@ rwarray_la_SOURCES = rwarray.c rwarray_la_LDFLAGS = $(MY_MODULE_FLAGS) rwarray_la_LIBADD = $(MY_LIBS) -select_la_SOURCES = select.c -select_la_LDFLAGS = $(MY_MODULE_FLAGS) -select_la_LIBADD = $(MY_LIBS) - time_la_SOURCES = time.c time_la_LDFLAGS = $(MY_MODULE_FLAGS) time_la_LIBADD = $(MY_LIBS) @@ -124,8 +119,7 @@ EXTRA_DIST = build-aux/config.rpath \ ChangeLog \ ChangeLog.0 \ fts.3 \ - README.fts \ - siglist.h + README.fts dist_man_MANS = \ filefuncs.3am fnmatch.3am fork.3am inplace.3am \ diff --git a/extension/Makefile.in b/extension/Makefile.in index 015bc118..2596d282 100644 --- a/extension/Makefile.in +++ b/extension/Makefile.in @@ -231,12 +231,6 @@ rwarray_la_OBJECTS = $(am_rwarray_la_OBJECTS) rwarray_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(rwarray_la_LDFLAGS) $(LDFLAGS) -o $@ -select_la_DEPENDENCIES = $(am__DEPENDENCIES_2) -am_select_la_OBJECTS = select.lo -select_la_OBJECTS = $(am_select_la_OBJECTS) -select_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(select_la_LDFLAGS) $(LDFLAGS) -o $@ testext_la_DEPENDENCIES = $(am__DEPENDENCIES_2) am_testext_la_OBJECTS = testext.lo testext_la_OBJECTS = $(am_testext_la_OBJECTS) @@ -287,14 +281,12 @@ SOURCES = $(filefuncs_la_SOURCES) $(fnmatch_la_SOURCES) \ $(fork_la_SOURCES) $(inplace_la_SOURCES) $(ordchr_la_SOURCES) \ $(readdir_la_SOURCES) $(readfile_la_SOURCES) \ $(revoutput_la_SOURCES) $(revtwoway_la_SOURCES) \ - $(rwarray_la_SOURCES) $(select_la_SOURCES) \ - $(testext_la_SOURCES) $(time_la_SOURCES) + $(rwarray_la_SOURCES) $(testext_la_SOURCES) $(time_la_SOURCES) DIST_SOURCES = $(filefuncs_la_SOURCES) $(fnmatch_la_SOURCES) \ $(fork_la_SOURCES) $(inplace_la_SOURCES) $(ordchr_la_SOURCES) \ $(readdir_la_SOURCES) $(readfile_la_SOURCES) \ $(revoutput_la_SOURCES) $(revtwoway_la_SOURCES) \ - $(rwarray_la_SOURCES) $(select_la_SOURCES) \ - $(testext_la_SOURCES) $(time_la_SOURCES) + $(rwarray_la_SOURCES) $(testext_la_SOURCES) $(time_la_SOURCES) RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ @@ -536,7 +528,6 @@ pkgextension_LTLIBRARIES = \ revoutput.la \ revtwoway.la \ rwarray.la \ - select.la \ testext.la \ time.la @@ -575,9 +566,6 @@ revtwoway_la_LIBADD = $(MY_LIBS) rwarray_la_SOURCES = rwarray.c rwarray_la_LDFLAGS = $(MY_MODULE_FLAGS) rwarray_la_LIBADD = $(MY_LIBS) -select_la_SOURCES = select.c -select_la_LDFLAGS = $(MY_MODULE_FLAGS) -select_la_LIBADD = $(MY_LIBS) time_la_SOURCES = time.c time_la_LDFLAGS = $(MY_MODULE_FLAGS) time_la_LIBADD = $(MY_LIBS) @@ -588,8 +576,7 @@ EXTRA_DIST = build-aux/config.rpath \ ChangeLog \ ChangeLog.0 \ fts.3 \ - README.fts \ - siglist.h + README.fts dist_man_MANS = \ filefuncs.3am fnmatch.3am fork.3am inplace.3am \ @@ -719,9 +706,6 @@ revtwoway.la: $(revtwoway_la_OBJECTS) $(revtwoway_la_DEPENDENCIES) $(EXTRA_revtw rwarray.la: $(rwarray_la_OBJECTS) $(rwarray_la_DEPENDENCIES) $(EXTRA_rwarray_la_DEPENDENCIES) $(AM_V_CCLD)$(rwarray_la_LINK) -rpath $(pkgextensiondir) $(rwarray_la_OBJECTS) $(rwarray_la_LIBADD) $(LIBS) -select.la: $(select_la_OBJECTS) $(select_la_DEPENDENCIES) $(EXTRA_select_la_DEPENDENCIES) - $(AM_V_CCLD)$(select_la_LINK) -rpath $(pkgextensiondir) $(select_la_OBJECTS) $(select_la_LIBADD) $(LIBS) - testext.la: $(testext_la_OBJECTS) $(testext_la_DEPENDENCIES) $(EXTRA_testext_la_DEPENDENCIES) $(AM_V_CCLD)$(testext_la_LINK) -rpath $(pkgextensiondir) $(testext_la_OBJECTS) $(testext_la_LIBADD) $(LIBS) @@ -745,7 +729,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/revoutput.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/revtwoway.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rwarray.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/select.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stack.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testext.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/time.Plo@am__quote@ diff --git a/extension/configh.in b/extension/configh.in index 57c9ec3e..5842f2f4 100644 --- a/extension/configh.in +++ b/extension/configh.in @@ -40,9 +40,6 @@ /* Define to 1 if you have the <dlfcn.h> header file. */ #undef HAVE_DLFCN_H -/* Define to 1 if you have the `fcntl' function. */ -#undef HAVE_FCNTL - /* Define to 1 if you have the `fdopendir' function. */ #undef HAVE_FDOPENDIR @@ -70,9 +67,6 @@ /* Define to 1 if you have the <inttypes.h> header file. */ #undef HAVE_INTTYPES_H -/* Define to 1 if you have the `kill' function. */ -#undef HAVE_KILL - /* Define to 1 if you have the <limits.h> header file. */ #undef HAVE_LIMITS_H @@ -88,15 +82,6 @@ /* Define to 1 if you have the `select' function. */ #undef HAVE_SELECT -/* Define to 1 if you have the `sigaction' function. */ -#undef HAVE_SIGACTION - -/* Define to 1 if you have the <signal.h> header file. */ -#undef HAVE_SIGNAL_H - -/* Define to 1 if you have the `sigprocmask' function. */ -#undef HAVE_SIGPROCMASK - /* Define to 1 if you have the <stdint.h> header file. */ #undef HAVE_STDINT_H diff --git a/extension/configure b/extension/configure index 4bd1d940..7ee9c0df 100755 --- a/extension/configure +++ b/extension/configure @@ -14233,7 +14233,7 @@ else $as_echo "no" >&6; } fi -for ac_header in fnmatch.h limits.h sys/time.h sys/select.h sys/param.h signal.h +for ac_header in fnmatch.h limits.h sys/time.h sys/select.h sys/param.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" @@ -14490,9 +14490,8 @@ $as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h fi -for ac_func in fcntl fdopendir fnmatch gettimeofday \ - getdtablesize kill nanosleep select sigaction sigprocmask \ - GetSystemTimeAsFileTime +for ac_func in fdopendir fnmatch gettimeofday \ + getdtablesize nanosleep select GetSystemTimeAsFileTime do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" diff --git a/extension/configure.ac b/extension/configure.ac index 37e306f3..1f876a0e 100644 --- a/extension/configure.ac +++ b/extension/configure.ac @@ -66,14 +66,13 @@ else AC_MSG_RESULT([no]) fi -AC_CHECK_HEADERS(fnmatch.h limits.h sys/time.h sys/select.h sys/param.h signal.h) +AC_CHECK_HEADERS(fnmatch.h limits.h sys/time.h sys/select.h sys/param.h) AC_HEADER_DIRENT AC_HEADER_MAJOR AC_HEADER_TIME -AC_CHECK_FUNCS(fcntl fdopendir fnmatch gettimeofday \ - getdtablesize kill nanosleep select sigaction sigprocmask \ - GetSystemTimeAsFileTime) +AC_CHECK_FUNCS(fdopendir fnmatch gettimeofday \ + getdtablesize nanosleep select GetSystemTimeAsFileTime) GAWK_FUNC_DIRFD GAWK_PREREQ_DIRFD diff --git a/extension/select.c b/extension/select.c deleted file mode 100644 index b2105b75..00000000 --- a/extension/select.c +++ /dev/null @@ -1,681 +0,0 @@ -/* - * select.c - Builtin functions to provide select I/O multiplexing. - */ - -/* - * Copyright (C) 2013 the Free Software Foundation, Inc. - * - * This file is part of GAWK, the GNU implementation of the - * AWK Programming Language. - * - * GAWK is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * GAWK is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <assert.h> -#include <errno.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <fcntl.h> - -#include <sys/types.h> -#include <sys/stat.h> - -#include "gawkapi.h" - -#include "gettext.h" -#define _(msgid) gettext(msgid) -#define N_(msgid) msgid - -static const gawk_api_t *api; /* for convenience macros to work */ -static awk_ext_id_t *ext_id; -static const char *ext_version = "select extension: version 1.0"; -static awk_bool_t (*init_func)(void) = NULL; - -int plugin_is_GPL_compatible; - -#if defined(HAVE_SELECT) && defined(HAVE_SYS_SELECT_H) -#include <sys/select.h> -#endif - -#ifdef HAVE_SIGNAL_H -#include <signal.h> -#endif - -static const char *const signum2name[] = { -#define init_sig(A, B, C) [A] = B, -#include "siglist.h" -#undef init_sig -}; -#define NUMSIG sizeof(signum2name)/sizeof(signum2name[0]) - -#define MIN_VALID_SIGNAL 1 /* 0 is not allowed! */ -/* - * We would like to use NSIG, but I think this seems to be a BSD'ism that is not - * POSIX-compliant. It is used internally by glibc, but not always - * available. We add a buffer to the maximum number in the provided mapping - * in case the list is not comprehensive: - */ -#define MAX_VALID_SIGNAL (NUMSIG+100) -#define IS_VALID_SIGNAL(X) \ - (((X) >= MIN_VALID_SIGNAL) && ((X) <= MAX_VALID_SIGNAL)) - -static int -signame2num(const char *name) -{ - size_t i; - - if (strncasecmp(name, "sig", 3) == 0) - /* skip "sig" prefix */ - name += 3; - for (i = MIN_VALID_SIGNAL; i < NUMSIG; i++) { - if (signum2name[i] && ! strcasecmp(signum2name[i], name)) - return i; - } - return -1; -} - -static volatile struct { - int flag; - sigset_t mask; -} caught; - -static void -signal_handler(int signum) -{ - /* - * All signals should be blocked, so we do not have to worry about - * whether sigaddset is thread-safe. It is documented to be - * async-signal-safe. - */ - sigaddset(& caught.mask, signum); - caught.flag = 1; -#ifndef HAVE_SIGACTION - /* - * On platforms without sigaction, we do not know how the legacy - * signal API will behave. There does not appear to be an autoconf - * test for whether the signal handler is reset to default each time - * a signal is trapped, so we do this to be safe. - */ - signal(signum, signal_handler); -#endif -} - -static int -integer_string(const char *s, long *x) -{ - char *endptr; - - *x = strtol(s, & endptr, 10); - return ((endptr != s) && (*endptr == '\0')) ? 0 : -1; -} - -static int -get_signal_number(awk_value_t signame) -{ - int x; - - switch (signame.val_type) { - case AWK_NUMBER: - x = signame.num_value; - if ((x != signame.num_value) || ! IS_VALID_SIGNAL(x)) { - update_ERRNO_string(_("invalid signal number")); - return -1; - } - return x; - case AWK_STRING: - if ((x = signame2num(signame.str_value.str)) >= 0) - return x; - { - long z; - if ((integer_string(signame.str_value.str, &z) == 0) && IS_VALID_SIGNAL(z)) - return z; - } - update_ERRNO_string(_("invalid signal name")); - return -1; - default: - update_ERRNO_string(_("signal name argument must be string or numeric")); - return -1; - } -} - -static awk_value_t * -signal_result(awk_value_t *result, void (*func)(int)) -{ - awk_value_t override; - - if (func == SIG_DFL) - return make_const_string("default", 7, result); - if (func == SIG_IGN) - return make_const_string("ignore", 6, result); - if (func == signal_handler) - return make_const_string("trap", 4, result); - if (get_argument(2, AWK_NUMBER, & override) && override.num_value) - return make_const_string("unknown", 7, result); - /* need to roll it back! */ - update_ERRNO_string(_("select_signal: override not requested for unknown signal handler")); - make_null_string(result); - return NULL; -} - -/* do_signal --- trap signals */ - -static awk_value_t * -do_signal(int nargs, awk_value_t *result) -{ - awk_value_t signame, disposition; - int signum; - void (*func)(int); - - if (do_lint && nargs > 3) - lintwarn(ext_id, _("select_signal: called with too many arguments")); - if (! get_argument(0, AWK_UNDEFINED, & signame)) { - update_ERRNO_string(_("select_signal: missing required signal name argument")); - return make_null_string(result); - } - if ((signum = get_signal_number(signame)) < 0) - return make_null_string(result); - if (! get_argument(1, AWK_STRING, & disposition)) { - update_ERRNO_string(_("select_signal: missing required signal disposition argument")); - return make_null_string(result); - } - if (strcasecmp(disposition.str_value.str, "default") == 0) - func = SIG_DFL; - else if (strcasecmp(disposition.str_value.str, "ignore") == 0) - func = SIG_IGN; - else if (strcasecmp(disposition.str_value.str, "trap") == 0) - func = signal_handler; - else { - update_ERRNO_string(_("select_signal: invalid disposition argument")); - return make_null_string(result); - } - -#ifdef HAVE_SIGPROCMASK -/* Temporarily block this signal in case we need to roll back the handler! */ -#define PROTECT \ - sigset_t set, oldset; \ - sigemptyset(& set); \ - sigaddset(& set, signum); \ - sigprocmask(SIG_BLOCK, &set, &oldset); -#define RELEASE sigprocmask(SIG_SETMASK, &oldset, NULL); -#else -/* Brain-damaged platform, so we will have to live with the race condition. */ -#define PROTECT -#define RELEASE -#endif - -#ifdef HAVE_SIGACTION - { - struct sigaction sa, prev; - sa.sa_handler = func; - sigfillset(& sa.sa_mask); /* block all signals in handler */ - sa.sa_flags = SA_RESTART; - { - PROTECT - if (sigaction(signum, &sa, &prev) < 0) { - update_ERRNO_int(errno); - RELEASE - return make_null_string(result); - } - if (signal_result(result, prev.sa_handler)) { - RELEASE - return result; - } - /* roll it back! */ - sigaction(signum, &prev, NULL); - RELEASE - return result; - } - } -#else - /* - * Fall back to signal; this is available on all platforms. We can - * only hope that it does the right thing. - */ - { - void (*prev)(int); - PROTECT - if ((prev = signal(signum, func)) == SIG_ERR) { - update_ERRNO_int(errno); - RELEASE - return make_null_string(result); - } - if (signal_result(result, prev)) { - RELEASE - return result; - } - /* roll it back! */ - signal(signum, prev); - RELEASE - return result; - } -#endif -} - -/* do_kill --- send a signal */ - -static awk_value_t * -do_kill(int nargs, awk_value_t *result) -{ -#ifdef HAVE_KILL - awk_value_t pidarg, signame; - pid_t pid; - int signum; - int rc; - - if (do_lint && nargs > 2) - lintwarn(ext_id, _("kill: called with too many arguments")); - if (! get_argument(0, AWK_NUMBER, & pidarg)) { - update_ERRNO_string(_("kill: missing required pid argument")); - return make_number(-1, result); - } - pid = pidarg.num_value; - if (pid != pidarg.num_value) { - update_ERRNO_string(_("kill: pid argument must be an integer")); - return make_number(-1, result); - } - if (! get_argument(1, AWK_UNDEFINED, & signame)) { - update_ERRNO_string(_("kill: missing required signal name argument")); - return make_number(-1, result); - } - if ((signum = get_signal_number(signame)) < 0) - return make_number(-1, result); - if ((rc = kill(pid, signum)) < 0) - update_ERRNO_int(errno); - return make_number(rc, result); -#else - update_ERRNO_string(_("kill: not supported on this platform")); - return make_number(-1, 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 * -do_select(int nargs, awk_value_t *result) -{ - static const char *argname[] = { "read", "write", "except" }; - struct { - awk_value_t array; - awk_flat_array_t *flat; - fd_set bits; - int *array2fd; - } fds[3]; - awk_value_t timeout_arg; - int i; - struct timeval maxwait; - struct timeval *timeout; - int nfds = 0; - int rc; - awk_value_t sigarr; - int dosig = 0; - - if (do_lint && nargs > 5) - lintwarn(ext_id, _("select: called with too many arguments")); - -#define EL fds[i].flat->elements[j] - if (nargs == 5) { - dosig = 1; - if (! get_argument(4, AWK_ARRAY, &sigarr)) { - warning(ext_id, _("select: the signal argument must be an array")); - update_ERRNO_string(_("select: bad signal parameter")); - return make_number(-1, result); - } - clear_array(sigarr.array_cookie); - } - - for (i = 0; i < sizeof(fds)/sizeof(fds[0]); i++) { - size_t j; - - if (! get_argument(i, AWK_ARRAY, & fds[i].array)) { - warning(ext_id, _("select: bad array parameter `%s'"), argname[i]); - update_ERRNO_string(_("select: bad array parameter")); - return make_number(-1, result); - } - /* N.B. flatten_array fails for empty arrays, so that's OK */ - FD_ZERO(&fds[i].bits); - if (flatten_array(fds[i].array.array_cookie, &fds[i].flat)) { - emalloc(fds[i].array2fd, int *, fds[i].flat->count*sizeof(int), "select"); - for (j = 0; j < fds[i].flat->count; j++) { - long x; - fds[i].array2fd[j] = -1; - /* note: the index is always delivered as a string */ - - 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 *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]); - } - else - warning(ext_id, _("select: command type should be a string for `%s' in `%s' array"), EL.index.str_value.str, argname[i]); - if (fds[i].array2fd[j] < 0) { - update_ERRNO_string(_("select: get_file failed")); - if (! release_flattened_array(fds[i].array.array_cookie, fds[i].flat)) - warning(ext_id, _("select: release_flattened_array failed")); - free(fds[i].array2fd); - return make_number(-1, result); - } - FD_SET(fds[i].array2fd[j], &fds[i].bits); - if (nfds <= fds[i].array2fd[j]) - nfds = fds[i].array2fd[j]+1; - } - } - else - fds[i].flat = NULL; - } - if (dosig && caught.flag) { - /* take a quick poll, but do not block, since signals have been trapped */ - maxwait.tv_sec = maxwait.tv_usec = 0; - timeout = &maxwait; - } - else if (get_argument(3, AWK_NUMBER, &timeout_arg)) { - double secs = timeout_arg.num_value; - if (secs < 0) { - warning(ext_id, _("select: treating negative timeout as zero")); - secs = 0; - } - maxwait.tv_sec = secs; - maxwait.tv_usec = (secs-(double)maxwait.tv_sec)*1000000.0; - timeout = &maxwait; - } else - timeout = NULL; - - if ((rc = select(nfds, &fds[0].bits, &fds[1].bits, &fds[2].bits, timeout)) < 0) - update_ERRNO_int(errno); - - if (dosig && caught.flag) { - int i; - sigset_t trapped; -#ifdef HAVE_SIGPROCMASK - /* - * Block signals while we copy and reset the mask to eliminate - * a race condition whereby a signal could be missed. - */ - sigset_t set, oldset; - sigfillset(& set); - sigprocmask(SIG_SETMASK, &set, &oldset); -#endif - /* - * Reset flag to 0 first. If we don't have sigprocmask, - * that may reduce the chance of missing a signal. - */ - caught.flag = 0; - trapped = caught.mask; - sigemptyset(& caught.mask); -#ifdef HAVE_SIGPROCMASK - sigprocmask(SIG_SETMASK, &oldset, NULL); -#endif - /* populate sigarr with trapped signals */ - /* - * XXX this is very inefficient! Note that get_signal_number - * ensures that we trap only signals between MIN_VALID_SIGNAL - * and MAX_VALID_SIGNAL. - */ - for (i = MIN_VALID_SIGNAL; i <= MAX_VALID_SIGNAL; i++) { - if (sigismember(& trapped, i) > 0) { - awk_value_t idx, val; - if ((i < NUMSIG) && signum2name[i]) - set_array_element(sigarr.array_cookie, make_number(i, &idx), make_const_string(signum2name[i], strlen(signum2name[i]), &val)); - else - set_array_element(sigarr.array_cookie, make_number(i, &idx), make_null_string(&val)); - } - } - } - - if (rc < 0) { - /* bit masks are undefined, so delete all array entries */ - for (i = 0; i < sizeof(fds)/sizeof(fds[0]); i++) { - if (fds[i].flat) { - size_t j; - for (j = 0; j < fds[i].flat->count; j++) - EL.flags |= AWK_ELEMENT_DELETE; - if (! release_flattened_array(fds[i].array.array_cookie, fds[i].flat)) - warning(ext_id, _("select: release_flattened_array failed")); - free(fds[i].array2fd); - } - } - return make_number(rc, result); - } - - for (i = 0; i < sizeof(fds)/sizeof(fds[0]); i++) { - if (fds[i].flat) { - size_t j; - /* remove array elements not set in the bit mask */ - for (j = 0; j < fds[i].flat->count; j++) { - if (! FD_ISSET(fds[i].array2fd[j], &fds[i].bits)) - EL.flags |= AWK_ELEMENT_DELETE; - } - if (! release_flattened_array(fds[i].array.array_cookie, fds[i].flat)) - warning(ext_id, _("select: release_flattened_array failed")); - free(fds[i].array2fd); - } - } -#undef EL - - /* Set the return value */ - return make_number(rc, result); -} - -static int -set_non_blocking(int fd) -{ -#if defined(HAVE_FCNTL) && defined(O_NONBLOCK) - int flags; - - if (((flags = fcntl(fd, F_GETFL)) == -1) || - (fcntl(fd, F_SETFL, (flags|O_NONBLOCK)) == -1)) { - update_ERRNO_int(errno); - return -1; - } - return 0; -#else - update_ERRNO_string(_("set_non_blocking: not supported on this platform")); - return -1; -#endif -} - -static void -set_retry(const char *name) -{ - static const char suffix[] = "RETRY"; - static awk_array_t procinfo; - static char *subsep; - static size_t subsep_len; - awk_value_t idx, val; - char *s; - size_t len; - - if (!subsep) { - /* initialize cached values for PROCINFO and SUBSEP */ - awk_value_t res; - - if (! sym_lookup("PROCINFO", AWK_ARRAY, & res)) { - procinfo = create_array(); - res.val_type = AWK_ARRAY; - res.array_cookie = procinfo; - if (! sym_update("PROCINFO", & res)) { - warning(ext_id, _("set_non_blocking: could not install PROCINFO array; unable to configure PROCINFO RETRY for `%s'"), name); - return; - } - /* must retrieve it after installing it! */ - if (! sym_lookup("PROCINFO", AWK_ARRAY, & res)) { - warning(ext_id, _("set_non_blocking: sym_lookup(`%s') failed; unable to configure PROCINFO RETRY for `%s'"), "PROCINFO", name); - return; - } - } - procinfo = res.array_cookie; - - if (! sym_lookup("SUBSEP", AWK_STRING, & res)) { - warning(ext_id, _("set_non_blocking: sym_lookup(`%s') failed; unable to configure PROCINFO RETRY for `%s'"), "SUBSEP", name); - return; - } - subsep = strdup(res.str_value.str); - subsep_len = res.str_value.len; - } - - len = strlen(name)+subsep_len+sizeof(suffix)-1; - emalloc(s, char *, len+2, "set_non_blocking"); - sprintf(s, "%s%s%s", name, subsep, suffix); - - if (! set_array_element(procinfo, make_malloced_string(s, len, &idx), make_null_string(&val))) - warning(ext_id, _("set_non_blocking: unable to configure PROCINFO RETRY for `%s'"), name); -} - -/* do_set_non_blocking --- Set a file to be non-blocking */ - -static awk_value_t * -do_set_non_blocking(int nargs, awk_value_t *result) -{ - awk_value_t cmd, cmdtype; - int fd; - - 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) || - (! 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)) { - 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); - } else if (do_lint) { - if (nargs < 2) - lintwarn(ext_id, _("set_non_blocking: called with too few arguments")); - else - lintwarn(ext_id, _("set_non_blocking: called with inappropriate argument(s)")); - } - 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 */ - -dl_load_func(func_table, select, "") diff --git a/extension/siglist.h b/extension/siglist.h deleted file mode 100644 index 7ecb8ab1..00000000 --- a/extension/siglist.h +++ /dev/null @@ -1,76 +0,0 @@ -/* Canonical list of all signal names. - Copyright (C) 1996-2012 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ - -/* This file should be usable for any platform, since it just associates - the SIG* macros with text names and descriptions. The actual values - come from <bits/signum.h> (via <signal.h>). For any signal macros do not - exist on every platform, we can use #ifdef tests here and still use - this single common file for all platforms. */ - -/* This file is included multiple times. */ - -/* Standard signals */ - init_sig (SIGHUP, "HUP", N_("Hangup")) - init_sig (SIGINT, "INT", N_("Interrupt")) - init_sig (SIGQUIT, "QUIT", N_("Quit")) - init_sig (SIGILL, "ILL", N_("Illegal instruction")) - init_sig (SIGTRAP, "TRAP", N_("Trace/breakpoint trap")) - init_sig (SIGABRT, "ABRT", N_("Aborted")) - init_sig (SIGFPE, "FPE", N_("Floating point exception")) - init_sig (SIGKILL, "KILL", N_("Killed")) - init_sig (SIGBUS, "BUS", N_("Bus error")) - init_sig (SIGSEGV, "SEGV", N_("Segmentation fault")) - init_sig (SIGPIPE, "PIPE", N_("Broken pipe")) - init_sig (SIGALRM, "ALRM", N_("Alarm clock")) - init_sig (SIGTERM, "TERM", N_("Terminated")) - init_sig (SIGURG, "URG", N_("Urgent I/O condition")) - init_sig (SIGSTOP, "STOP", N_("Stopped (signal)")) - init_sig (SIGTSTP, "TSTP", N_("Stopped")) - init_sig (SIGCONT, "CONT", N_("Continued")) - init_sig (SIGCHLD, "CHLD", N_("Child exited")) - init_sig (SIGTTIN, "TTIN", N_("Stopped (tty input)")) - init_sig (SIGTTOU, "TTOU", N_("Stopped (tty output)")) - init_sig (SIGIO, "IO", N_("I/O possible")) - init_sig (SIGXCPU, "XCPU", N_("CPU time limit exceeded")) - init_sig (SIGXFSZ, "XFSZ", N_("File size limit exceeded")) - init_sig (SIGVTALRM, "VTALRM", N_("Virtual timer expired")) - init_sig (SIGPROF, "PROF", N_("Profiling timer expired")) - init_sig (SIGUSR1, "USR1", N_("User defined signal 1")) - init_sig (SIGUSR2, "USR2", N_("User defined signal 2")) - -/* Variations */ -#ifdef SIGEMT - init_sig (SIGEMT, "EMT", N_("EMT trap")) -#endif -#ifdef SIGSYS - init_sig (SIGSYS, "SYS", N_("Bad system call")) -#endif -#ifdef SIGSTKFLT - init_sig (SIGSTKFLT, "STKFLT", N_("Stack fault")) -#endif -#ifdef SIGINFO - init_sig (SIGINFO, "INFO", N_("Information request")) -#elif defined(SIGPWR) && (!defined(SIGLOST) || (SIGPWR != SIGLOST)) - init_sig (SIGPWR, "PWR", N_("Power failure")) -#endif -#ifdef SIGLOST - init_sig (SIGLOST, "LOST", N_("Resource lost")) -#endif -#ifdef SIGWINCH - init_sig (SIGWINCH, "WINCH", N_("Window changed")) -#endif |