Exemplo n.º 1
0
static int signal_cmd_throw(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
    int sig = SIGINT;

    if (argc == 1) {
        if ((sig = find_signal_by_name(interp, Jim_String(argv[0]))) < 0) {
            return JIM_ERR;
        }
    }

    /* If the signal is ignored (blocked) ... */
    if (siginfo[sig].status == SIGNAL_ACTION_IGNORE) {
        sigsblocked |= sig_to_bit(sig);
        return JIM_OK;
    }

    /* Just set the signal */
    interp->sigmask |= sig_to_bit(sig);

    /* Set the canonical name of the signal as the result */
    Jim_SetResultString(interp, Jim_SignalId(sig), -1);

    /* And simply say we caught the signal */
    return JIM_SIGNAL;
}
Exemplo n.º 2
0
/**
 * Given the name of a signal, returns the signal value if found,
 * or returns -1 (and sets an error) if not found.
 * We accept -SIGINT, SIGINT, INT or any lowercase version or a number,
 * either positive or negative.
 */
static int find_signal_by_name(Jim_Interp *interp, const char *name)
{
    int i;
    const char *pt = name;

    /* Remove optional - and SIG from the front of the name */
    if (*pt == '-') {
        pt++;
    }
    if (strncasecmp(name, "sig", 3) == 0) {
        pt += 3;
    }
    if (isdigit(UCHAR(pt[0]))) {
        i = atoi(pt);
        if (i > 0 && i < MAX_SIGNALS) {
            return i;
        }
    }
    else {
        for (i = 1; i < MAX_SIGNALS; i++) {
            /* Jim_SignalId() returns names such as SIGINT, and
             * returns "unknown signal" if unknown, so this will work
             */
            if (strcasecmp(Jim_SignalId(i) + 3, pt) == 0) {
                return i;
            }
        }
    }
    Jim_SetResultFormatted(interp, "unknown signal %s", name);

    return -1;
}
Exemplo n.º 3
0
/*
 * Create error messages for unusual process exits.  An
 * extra newline gets appended to each error message, but
 * it gets removed below (in the same fashion that an
 * extra newline in the command's output is removed).
 */
static int JimCheckWaitStatus(Jim_Interp *interp, pidtype pid, int waitStatus)
{
    Jim_Obj *errorCode = Jim_NewListObj(interp, NULL, 0);
    int rc = JIM_ERR;

    if (WIFEXITED(waitStatus)) {
        if (WEXITSTATUS(waitStatus) == 0) {
            Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, "NONE", -1));
            rc = JIM_OK;
        }
        else {
            Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, "CHILDSTATUS", -1));
            Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, (long)pid));
            Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, WEXITSTATUS(waitStatus)));
        }
    }
    else {
        const char *type;
        const char *action;

        if (WIFSIGNALED(waitStatus)) {
            type = "CHILDKILLED";
            action = "killed";
        }
        else {
            type = "CHILDSUSP";
            action = "suspended";
        }

        Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, type, -1));

#ifdef jim_ext_signal
        Jim_SetResultFormatted(interp, "child %s by signal %s", action, Jim_SignalId(WTERMSIG(waitStatus)));
        Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, Jim_SignalId(WTERMSIG(waitStatus)), -1));
        Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, pid));
        Jim_ListAppendElement(interp, errorCode, Jim_NewStringObj(interp, Jim_SignalName(WTERMSIG(waitStatus)), -1));
#else
        Jim_SetResultFormatted(interp, "child %s by signal %d", action, WTERMSIG(waitStatus));
        Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, WTERMSIG(waitStatus)));
        Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, (long)pid));
        Jim_ListAppendElement(interp, errorCode, Jim_NewIntObj(interp, WTERMSIG(waitStatus)));
#endif
    }
    Jim_SetGlobalVariableStr(interp, "errorCode", errorCode);
    return rc;
}
Exemplo n.º 4
0
const char *Jim_SignalName(int sig)
{
#ifdef HAVE_SYS_SIGLIST
    if (sig >= 0 && sig < NSIG) {
        return sys_siglist[sig];
    }
#endif
    return Jim_SignalId(sig);
}
Exemplo n.º 5
0
static int signal_set_sigmask_result(Jim_Interp *interp, jim_wide sigmask)
{
    int i;
    Jim_Obj *listObj = Jim_NewListObj(interp, NULL, 0);

    for (i = 0; i < MAX_SIGNALS; i++) {
        if (sigmask & sig_to_bit(i)) {
            Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, Jim_SignalId(i), -1));
        }
    }
    Jim_SetResult(interp, listObj);
    return JIM_OK;
}
Exemplo n.º 6
0
static int do_signal_cmd(Jim_Interp *interp, int action, int argc, Jim_Obj *const *argv)
{
    struct sigaction sa;
    int i;

    if (argc == 0) {
        Jim_SetResult(interp, Jim_NewListObj(interp, NULL, 0));
        for (i = 1; i < MAX_SIGNALS; i++) {
            if (siginfo[i].status == action) {
                /* Add signal name to the list  */
                Jim_ListAppendElement(interp, Jim_GetResult(interp),
                    Jim_NewStringObj(interp, Jim_SignalId(i), -1));
            }
        }
        return JIM_OK;
    }

    /* Catch all the signals we care about */
    if (action != SIGNAL_ACTION_DEFAULT) {
        sa.sa_flags = 0;
        sigemptyset(&sa.sa_mask);
        if (action == SIGNAL_ACTION_HANDLE) {
            sa.sa_handler = signal_handler;
        }
        else {
            sa.sa_handler = signal_ignorer;
        }
    }

    /* Iterate through the provided signals */
    for (i = 0; i < argc; i++) {
        int sig = find_signal_by_name(interp, Jim_String(argv[i]));

        if (sig < 0) {
            return JIM_ERR;
        }
        if (action != siginfo[sig].status) {
            /* Need to change the action for this signal */
            switch (action) {
                case SIGNAL_ACTION_HANDLE:
                case SIGNAL_ACTION_IGNORE:
                    if (siginfo[sig].status == SIGNAL_ACTION_DEFAULT) {
                        if (!sa_old) {
                            /* Allocate the structure the first time through */
                            sa_old = Jim_Alloc(sizeof(*sa_old) * MAX_SIGNALS);
                        }
                        sigaction(sig, &sa, &sa_old[sig]);
                    }
                    else {
                        sigaction(sig, &sa, 0);
                    }
                    break;

                case SIGNAL_ACTION_DEFAULT:
                    /* Restore old handler */
                    if (sa_old) {
                        sigaction(sig, &sa_old[sig], 0);
                    }
            }
            siginfo[sig].status = action;
        }
    }

    return JIM_OK;
}