[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gawk-diffs] [SCM] gawk branch, select, updated. gawk-4.1.0-69-g88b8c03
From: |
Andrew J. Schorr |
Subject: |
[gawk-diffs] [SCM] gawk branch, select, updated. gawk-4.1.0-69-g88b8c03 |
Date: |
Sat, 06 Jul 2013 01:41:37 +0000 |
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "gawk".
The branch, select has been updated
via 88b8c03a11e229b29cd985cabe51cb2ed3c24b55 (commit)
from 633bbb9f481cd72edb7c419941a366d0efbf88b6 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://git.sv.gnu.org/cgit/gawk.git/commit/?id=88b8c03a11e229b29cd985cabe51cb2ed3c24b55
commit 88b8c03a11e229b29cd985cabe51cb2ed3c24b55
Author: Andrew J. Schorr <address@hidden>
Date: Fri Jul 5 21:41:07 2013 -0400
Enhance select signal function to return info about previous handler and
decide whether to override when it is unknown.
diff --git a/extension/ChangeLog b/extension/ChangeLog
index 68ba6fe..4bfc64d 100644
--- a/extension/ChangeLog
+++ b/extension/ChangeLog
@@ -1,5 +1,15 @@
2013-07-05 Andrew J. Schorr <address@hidden>
+ * select.c (signal_result): New function to set result string from
+ signal function and detect when we need to roll back.
+ (do_signal): Now takes an optional 3rd override argument. Instead
+ of returning -1 or 0, we now return information about the previously
+ installed signal handler: default, ignore, trap, or unknown. An
+ empty string is returned on error. If it is an unknown handler,
+ and override is not non-zero, we roll back the handler and return "".
+
+2013-07-05 Andrew J. Schorr <address@hidden>
+
* select.c (set_non_blocking): Do not attempt F_SETFL if F_GETFL fails.
(do_set_non_blocking): Add support for case when called with a single
"" argument.
diff --git a/extension/select.c b/extension/select.c
index 4d28457..3bcef16 100644
--- a/extension/select.c
+++ b/extension/select.c
@@ -147,6 +147,25 @@ get_signal_number(awk_value_t signame)
}
}
+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 *
@@ -156,17 +175,17 @@ do_signal(int nargs, awk_value_t *result)
int signum;
void (*func)(int);
- if (do_lint && nargs > 2)
+ 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_number(-1, result);
+ return make_null_string(result);
}
if ((signum = get_signal_number(signame)) < 0)
- return make_number(-1, result);
+ return make_null_string(result);
if (! get_argument(1, AWK_STRING, & disposition)) {
update_ERRNO_string(_("select_signal: missing required signal
disposition argument"));
- return make_number(-1, result);
+ return make_null_string(result);
}
if (strcasecmp(disposition.str_value.str, "default") == 0)
func = SIG_DFL;
@@ -176,29 +195,69 @@ do_signal(int nargs, awk_value_t *result)
func = signal_handler;
else {
update_ERRNO_string(_("select_signal: invalid disposition
argument"));
- return make_number(-1, result);
+ 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
{
- int rc;
- struct sigaction sa;
+ awk_value_t override;
+ struct sigaction sa, prev;
sa.sa_handler = func;
sigfillset(& sa.sa_mask); /* block all signals in handler */
sa.sa_flags = SA_RESTART;
- if ((rc = sigaction(signum, &sa, NULL)) < 0)
- update_ERRNO_int(errno);
- return make_number(rc, result);
+ {
+ 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.
*/
- if (signal(signum, func) == SIG_ERR) {
- update_ERRNO_int(errno);
- return make_number(-1, result);
+ {
+ 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;
}
- return make_number(0, result);
#endif
}
@@ -461,7 +520,7 @@ do_set_non_blocking(int nargs, awk_value_t *result)
static awk_ext_func_t func_table[] = {
{ "select", do_select, 5 },
- { "select_signal", do_signal, 2 },
+ { "select_signal", do_signal, 3 },
{ "set_non_blocking", do_set_non_blocking, 2 },
{ "kill", do_kill, 2 },
};
-----------------------------------------------------------------------
Summary of changes:
extension/ChangeLog | 10 ++++++
extension/select.c | 89 ++++++++++++++++++++++++++++++++++++++++++--------
2 files changed, 84 insertions(+), 15 deletions(-)
hooks/post-receive
--
gawk
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [gawk-diffs] [SCM] gawk branch, select, updated. gawk-4.1.0-69-g88b8c03,
Andrew J. Schorr <=