On Sun, May 8, 2011 at 8:19 AM, Peter Mazinger <[email protected]> wrote:
>> libc sigfillset() returns a full set: all 128 bits are set.  libpthread
>> sigfillset() sets only 126 bits: everything except SIGCANCEL/SIGSETXID.
>>
>> libpthread sigprocmask() has extra code to prevent the caller from
>> blocking
>> SIGCANCEL/SIGSETXID.  libc sigprocmask() does not.
>
> If you did your tests on mips, couldn't it be, that this is influenced by the 
> change of using kernel sigset_t size for mips on all "generic" syscall 
> implementations (see KERNEL_SIGSET_T_SIZE macro)?

While the vector is sized differently on MIPS, I ran my test program
on an x86/glibc PC and saw that sigfillset() was still clearing the
bits for SIGCANCEL and SIGSETXID:

$ ./sigaction-test
Not masked: 3
Not masked: 32
Not masked: 33
sending SIGINT
sending SIGQUIT
caught sig 3

On the Linux PC, this behavior is seen regardless of whether
libpthread is linked in.

(Interestingly, on the PC, __sigaction() is duplicated in libc and
libpthread, but sigprocmask() and sigfillset() are not.)

After applying Austin's patch and my patch to uClibc 0.9.32-rc3, I was
able to verify that the sigfillset() behavior on the uClibc MIPS
target matches the behavior on the glibc PC.  This seems like it would
be a good thing.

Before applying my patch, SIGCANCEL and SIGSETXID were not defined so
the special libpthread behavior was not compiled into libc.  I do not
think there is a MIPS dependency involved.

I guess it probably would make sense to check the sigprocmask()
behavior at some point, as well.

Test program:

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

void fn(int sig, siginfo_t *si, void *vctx)
{
        printf("caught sig %d\n", sig);
        exit(0);
}

int main(int argc, char **argv)
{
        sigset_t s, old;
        struct sigaction sa, sa_old;
        int i;

        sigfillset(&s);
        sigdelset(&s, SIGQUIT);
        sigprocmask(SIG_BLOCK, &s, &old);

        for (i = 1; i <= SIGRTMAX; i++)
                if (!sigismember(&s, i))
                        printf("Not masked: %d\n", i);

        memset(&sa, 0, sizeof(sa));
        sa.sa_sigaction = fn;
        sa.sa_flags = SA_SIGINFO;
        sigaction(SIGQUIT, &sa, &sa_old);

        printf("sending SIGINT\n");
        usleep(100000);
        kill(0, SIGINT);
        usleep(100000);

        printf("sending SIGQUIT\n");
        usleep(100000);
        kill(0, SIGQUIT);
        usleep(100000);

        printf("failed to catch SIGQUIT\n");
        exit(1);
}
_______________________________________________
uClibc mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/uclibc

Reply via email to