• Al Viro's avatar
    alpha: unb0rk sigsuspend() and rt_sigsuspend() · 392fb6e3
    Al Viro authored
    Old code used to set regs->r0 and regs->r19 to force the right
    return value.  Leaving that after switch to ERESTARTNOHAND
    was a Bad Idea(tm), since now that screws the restart - if we
    hit the case when get_signal_to_deliver() returns 0, we will
    step back to syscall insn, with v0 set to EINTR and a3 to 1.
    The latter won't matter, since EINTR is 4, aka __NR_write.
    
    Testcase:
    
    	#include <signal.h>
    	#define _GNU_SOURCE
    	#include <unistd.h>
    	#include <sys/syscall.h>
    
    	main()
    	{
    		sigset_t mask;
    		sigemptyset(&mask);
    		sigaddset(&mask, SIGCONT);
    		sigprocmask(SIG_SETMASK, &mask, NULL);
    		kill(0, SIGCONT);
    		syscall(__NR_sigsuspend, 1, "b0rken\n", 7);
    	}
    
    results on alpha in immediate message to stdout...
    
    Fix is obvious; moreover, since we don't need regs anymore, we can
    switch to normal prototypes for these guys and lose the wrappers.
    Even better, rt_sigsuspend() is identical to generic version in
    kernel/signal.c now.
    Tested-by: default avatarMichael Cree <mcree@orcon.net.nz>
    Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
    Signed-off-by: default avatarMatt Turner <mattst88@gmail.com>
    392fb6e3
unistd.h 15.1 KB