Sunday, February 20, 2022

[SOLVED] How to print all pending signals using a SYSCALL in UNIX?

Issue

I've been attempting to create a custom syscall that prints various information about a process. Of that information is the pending signals. I understand that under task_struct is another struct called sigpending, which is defined as follows:

struct sigpending {
                 struct list_head list;
                 sigset_t signal;   };

So I originally attempted using list_for_each_entry but that requires knowing the name of the member in the struct that stores the pending signals which I can't seem to find.

So how would I go about printing them?


Solution

One idea is checking [pending] sigset_t bits and print signals as numbers, or strings, or a mix. Easily adapted to a kernel version, this example is shown as working user code:

#include <stdio.h>
#include <signal.h>
#include <string.h>

// partial list for printing as strings:
static char *sigstrs[_NSIG] = {
    [SIGHUP] = "HUP",
    [SIGSEGV] = "SEGV",
};

static void show_pending(char *str, sigset_t *ssetp)
{
    int signo;

    printf(str);
    for (signo = 1; signo < _NSIG; signo++) {
        if (sigismember(ssetp, signo) == 0)
            continue;
        else if (sigstrs[signo])
            printf(" SIG%s", sigstrs[signo]);
        else
            printf(" %d", signo);
    }
    printf("\n");
}

int main(void)
{
    // user simulation, &taskp->pending.signal;
    sigset_t pending;
    memset(&pending, 0, sizeof (pending));
    sigaddset(&pending, SIGHUP);
    sigaddset(&pending, SIGSEGV);

    show_pending("pending:", &pending);
    return (0);
}

Output:
pending: SIGHUP SIGSEGV



Answered By - Milag
Answer Checked By - Clifford M. (WPSolving Volunteer)