signal.7: Clarify that siginfo_t isn't changed on coalescing

Confirmed by experiment by mtk:

$ cat siginfo_nonqueuing.c

                        } while (0)

static void
grimReaper(int sig, siginfo_t *si, void *ucontext)
{
    printf("caught signal %d\n", sig);

    printf("    si_pid=%ld, si_uid=%ld, si_status=%d\n",
            (long) si->si_pid, (long) si->si_uid, si->si_status);
}

static void
child(int sleepTime, uid_t uid, int status)
{
    switch (fork()) {
    case -1:
        errExit("fork");
    case 0:
        sleep(sleepTime);
        if (geteuid() == 0)
            setuid(uid);

        printf("Child %ld with UID %ld exiting with status %d\n",
                (long) getpid(),(long) getuid(), status);
        exit(status);
    default:
        return;
    }
}

int
main(int argc, char *argv[])
{
    struct sigaction sa;
    sigset_t blocking;

    sa.sa_sigaction = grimReaper;
    sa.sa_flags = SA_SIGINFO;
    sigemptyset(&sa.sa_mask);

    if (sigaction(SIGCHLD, &sa, NULL) == -1)
        errExit("sigaction");

    sigemptyset(&blocking);
    sigaddset(&blocking, SIGCHLD);
    if (sigprocmask(SIG_BLOCK, &blocking, NULL) == -1)
        errExit("sigprocmask");

    child(2, 20000, 20);
    child(3, 30000, 30);
    child(1, 10000, 10);

    sleep(5);

    if (sigprocmask(SIG_UNBLOCK, &blocking, NULL) == -1)
        errExit("sigprocmask");

    exit(EXIT_SUCCESS);
}
$ ./siginfo_nonqueuing
Child 4042 with UID 1000 exiting with status 10
Child 4040 with UID 1000 exiting with status 20
Child 4041 with UID 1000 exiting with status 30
caught signal 17
    si_pid=4042, si_uid=1000, si_status=10

Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Lennart Poettering <lennart@poettering.net>

Acked-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Michal Sekletar <msekleta@redhat.com>
Signed-off-by: Michael Kerrisk <mtk.manpages@gmail.com>
This commit is contained in:
Michal Sekletar 2019-07-11 14:53:24 +02:00 committed by Michael Kerrisk
parent c7871135df
commit e447e5bad3
1 changed files with 5 additions and 0 deletions

View File

@ -436,6 +436,11 @@ Real-time signals are distinguished by the following:
Multiple instances of real-time signals can be queued.
By contrast, if multiple instances of a standard signal are delivered
while that signal is currently blocked, then only one instance is queued.
Note that the
.I siginfo_t
structure associated with the signal already in queue is not overwritten
on arrival of subsequent instances of the same signal hence the process would
receive metadata associated with the first instance of the signal.
.IP 2. 4
If the signal is sent using
.BR sigqueue (3),