summaryrefslogtreecommitdiff
path: root/jim-signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'jim-signal.c')
-rw-r--r--jim-signal.c99
1 files changed, 63 insertions, 36 deletions
diff --git a/jim-signal.c b/jim-signal.c
index b760ede..7d02e68 100644
--- a/jim-signal.c
+++ b/jim-signal.c
@@ -16,13 +16,13 @@
#define MAX_SIGNALS_WIDE (sizeof(jim_wide) * 8)
#if defined(NSIG)
- #define MAX_SIGNALS ((NSIG < MAX_SIGNALS_WIDE) ? NSIG : MAX_SIGNALS_WIDE)
+ #define MAX_SIGNALS (int)((NSIG < MAX_SIGNALS_WIDE) ? NSIG : MAX_SIGNALS_WIDE)
#else
- #define MAX_SIGNALS MAX_SIGNALS_WIDE
+ #define MAX_SIGNALS (int)MAX_SIGNALS_WIDE
#endif
static jim_wide *sigloc;
-static jim_wide sigsblocked;
+static jim_wide sigsignored;
static struct sigaction *sa_old;
static struct {
int status;
@@ -34,16 +34,16 @@ static struct {
static void signal_handler(int sig)
{
- /* We just remember which signals occurred. Jim_Eval() will
- * notice this as soon as it can and throw an error
+ /* Remember which signals occurred and store in *sigloc.
+ * Jim_Eval() will notice this as soon as it can and throw an error
*/
*sigloc |= sig_to_bit(sig);
}
static void signal_ignorer(int sig)
{
- /* We just remember which signals occurred */
- sigsblocked |= sig_to_bit(sig);
+ /* Remember which signals occurred for access by 'signal check' */
+ sigsignored |= sig_to_bit(sig);
}
static void signal_init_names(void)
@@ -128,16 +128,6 @@ const char *Jim_SignalId(int sig)
return "unknown signal";
}
-const char *Jim_SignalName(int sig)
-{
-#ifdef HAVE_SYS_SIGLIST
- if (sig >= 0 && sig < NSIG) {
- return sys_siglist[sig];
- }
-#endif
- return Jim_SignalId(sig);
-}
-
/**
* Given the name of a signal, returns the signal value if found,
* or returns -1 (and sets an error) if not found.
@@ -179,6 +169,7 @@ static int find_signal_by_name(Jim_Interp *interp, const char *name)
#define SIGNAL_ACTION_HANDLE 1
#define SIGNAL_ACTION_IGNORE -1
+#define SIGNAL_ACTION_BLOCK -2
#define SIGNAL_ACTION_DEFAULT 0
static int do_signal_cmd(Jim_Interp *interp, int action, int argc, Jim_Obj *const *argv)
@@ -204,9 +195,13 @@ static int do_signal_cmd(Jim_Interp *interp, int action, int argc, Jim_Obj *cons
if (action == SIGNAL_ACTION_HANDLE) {
sa.sa_handler = signal_handler;
}
- else {
+ else if (action == SIGNAL_ACTION_IGNORE) {
sa.sa_handler = signal_ignorer;
}
+ else {
+ /* SIGNAL_ACTION_BLOCK */
+ sa.sa_handler = SIG_IGN;
+ }
}
/* Iterate through the provided signals */
@@ -219,6 +214,7 @@ static int do_signal_cmd(Jim_Interp *interp, int action, int argc, Jim_Obj *cons
if (action != siginfo[sig].status) {
/* Need to change the action for this signal */
switch (action) {
+ case SIGNAL_ACTION_BLOCK:
case SIGNAL_ACTION_HANDLE:
case SIGNAL_ACTION_IGNORE:
if (siginfo[sig].status == SIGNAL_ACTION_DEFAULT) {
@@ -256,6 +252,11 @@ static int signal_cmd_ignore(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
return do_signal_cmd(interp, SIGNAL_ACTION_IGNORE, argc, argv);
}
+static int signal_cmd_block(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+ return do_signal_cmd(interp, SIGNAL_ACTION_BLOCK, argc, argv);
+}
+
static int signal_cmd_default(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
return do_signal_cmd(interp, SIGNAL_ACTION_DEFAULT, argc, argv);
@@ -279,7 +280,7 @@ static int signal_cmd_check(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
int clear = 0;
jim_wide mask = 0;
- jim_wide blocked;
+ jim_wide ignored;
if (argc > 0 && Jim_CompareStringImmediate(interp, argv[0], "-clear")) {
clear++;
@@ -302,17 +303,13 @@ static int signal_cmd_check(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
mask = ~mask;
}
- if ((sigsblocked & mask) == 0) {
- /* No matching signals, so empty result and nothing to do */
- return JIM_OK;
- }
/* Be careful we don't have a race condition where signals are cleared but not returned */
- blocked = sigsblocked & mask;
+ ignored = sigsignored & mask;
if (clear) {
- sigsblocked &= ~blocked;
+ sigsignored &= ~ignored;
}
/* Set the result */
- signal_set_sigmask_result(interp, blocked);
+ signal_set_sigmask_result(interp, ignored);
return JIM_OK;
}
@@ -326,9 +323,9 @@ static int signal_cmd_throw(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
}
}
- /* If the signal is ignored (blocked) ... */
+ /* If the signal is ignored ... */
if (siginfo[sig].status == SIGNAL_ACTION_IGNORE) {
- sigsblocked |= sig_to_bit(sig);
+ sigsignored |= sig_to_bit(sig);
return JIM_OK;
}
@@ -380,6 +377,13 @@ static const jim_subcmd_type signal_command_table[] = {
-1,
/* Description: Lists ignored signals, or adds to ignored signals */
},
+ { "block",
+ "?signals ...?",
+ signal_cmd_block,
+ 0,
+ -1,
+ /* Description: Lists blocked signals, or adds to blocked signals */
+ },
{ "default",
"?signals ...?",
signal_cmd_default,
@@ -404,6 +408,25 @@ static const jim_subcmd_type signal_command_table[] = {
{ NULL }
};
+/**
+ * Restore default signal handling.
+ */
+static void JimSignalCmdDelete(Jim_Interp *interp, void *privData)
+{
+ int i;
+ if (sa_old) {
+ for (i = 1; i < MAX_SIGNALS; i++) {
+ if (siginfo[i].status != SIGNAL_ACTION_DEFAULT) {
+ sigaction(i, &sa_old[i], 0);
+ siginfo[i].status = SIGNAL_ACTION_DEFAULT;
+ }
+ }
+ }
+ Jim_Free(sa_old);
+ sa_old = NULL;
+ sigloc = NULL;
+}
+
static int Jim_AlarmCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
int ret;
@@ -510,19 +533,23 @@ int Jim_signalInit(Jim_Interp *interp)
if (Jim_PackageProvide(interp, "signal", "1.0", JIM_ERRMSG))
return JIM_ERR;
- signal_init_names();
+ Jim_CreateCommand(interp, "alarm", Jim_AlarmCmd, 0, 0);
+ Jim_CreateCommand(interp, "kill", Jim_KillCmd, 0, 0);
+ /* Sleep is slightly dubious here */
+ Jim_CreateCommand(interp, "sleep", Jim_SleepCmd, 0, 0);
/* Teach the jim core how to set a result from a sigmask */
interp->signal_set_result = signal_set_sigmask_result;
- /* Make sure we know where to store the signals which occur */
- sigloc = &interp->sigmask;
+ /* Currently only the top level interp supports signals */
+ if (!sigloc) {
+ signal_init_names();
- Jim_CreateCommand(interp, "signal", Jim_SubCmdProc, (void *)signal_command_table, NULL);
- Jim_CreateCommand(interp, "alarm", Jim_AlarmCmd, 0, 0);
- Jim_CreateCommand(interp, "kill", Jim_KillCmd, 0, 0);
+ /* Make sure we know where to store the signals which occur */
+ sigloc = &interp->sigmask;
+
+ Jim_CreateCommand(interp, "signal", Jim_SubCmdProc, (void *)signal_command_table, JimSignalCmdDelete);
+ }
- /* Sleep is slightly dubious here */
- Jim_CreateCommand(interp, "sleep", Jim_SleepCmd, 0, 0);
return JIM_OK;
}