1cbdddcfb32883a37e873907602d34bac523e3eadsewardj/* 2cbdddcfb32883a37e873907602d34bac523e3eadsewardj Test pending signals 3cbdddcfb32883a37e873907602d34bac523e3eadsewardj 4cbdddcfb32883a37e873907602d34bac523e3eadsewardj 1. Signals should remain pending while blocked, and not delivered early 5cbdddcfb32883a37e873907602d34bac523e3eadsewardj 6cbdddcfb32883a37e873907602d34bac523e3eadsewardj 2. When unblocking the signal, the signal should have been delivered 7cbdddcfb32883a37e873907602d34bac523e3eadsewardj by the time sigprocmask syscall is complete. 8cbdddcfb32883a37e873907602d34bac523e3eadsewardj */ 9cbdddcfb32883a37e873907602d34bac523e3eadsewardj#include <signal.h> 10cbdddcfb32883a37e873907602d34bac523e3eadsewardj#include <stdio.h> 11cbdddcfb32883a37e873907602d34bac523e3eadsewardj#include <unistd.h> 12cbdddcfb32883a37e873907602d34bac523e3eadsewardj#include <stdlib.h> 136cc2247cdfab852131fd392fb041ed07cd9117c6njn#include "config.h" 14cbdddcfb32883a37e873907602d34bac523e3eadsewardj 15cbdddcfb32883a37e873907602d34bac523e3eadsewardjstatic volatile int gotsig = 0; 16cbdddcfb32883a37e873907602d34bac523e3eadsewardjstatic volatile int early = 1; 17cbdddcfb32883a37e873907602d34bac523e3eadsewardj 18cbdddcfb32883a37e873907602d34bac523e3eadsewardjstatic void handler(int sig) 19cbdddcfb32883a37e873907602d34bac523e3eadsewardj{ 206cc2247cdfab852131fd392fb041ed07cd9117c6njn printf("4: got signal %s\n", 216cc2247cdfab852131fd392fb041ed07cd9117c6njn ( sig == SIGUSR1 ? "SIGUSR1" : "unexpected signal" )); 22cbdddcfb32883a37e873907602d34bac523e3eadsewardj 23cbdddcfb32883a37e873907602d34bac523e3eadsewardj if (sig != SIGUSR1) { 24cbdddcfb32883a37e873907602d34bac523e3eadsewardj fprintf(stderr, "FAILED: got signal %d instead\n", sig); 25cbdddcfb32883a37e873907602d34bac523e3eadsewardj exit(1); 26cbdddcfb32883a37e873907602d34bac523e3eadsewardj } 27cbdddcfb32883a37e873907602d34bac523e3eadsewardj 28cbdddcfb32883a37e873907602d34bac523e3eadsewardj if (early) { 29cbdddcfb32883a37e873907602d34bac523e3eadsewardj fprintf(stderr, "FAILED: signal delivered early (in handler)\n"); 30cbdddcfb32883a37e873907602d34bac523e3eadsewardj exit(1); 31cbdddcfb32883a37e873907602d34bac523e3eadsewardj } 32cbdddcfb32883a37e873907602d34bac523e3eadsewardj 33cbdddcfb32883a37e873907602d34bac523e3eadsewardj gotsig = 1; 34cbdddcfb32883a37e873907602d34bac523e3eadsewardj} 35cbdddcfb32883a37e873907602d34bac523e3eadsewardj 36cbdddcfb32883a37e873907602d34bac523e3eadsewardjint main() 37cbdddcfb32883a37e873907602d34bac523e3eadsewardj{ 38cbdddcfb32883a37e873907602d34bac523e3eadsewardj sigset_t all; 39cbdddcfb32883a37e873907602d34bac523e3eadsewardj sigset_t sigusr1; 40cbdddcfb32883a37e873907602d34bac523e3eadsewardj 41cbdddcfb32883a37e873907602d34bac523e3eadsewardj sigfillset(&all); 42cbdddcfb32883a37e873907602d34bac523e3eadsewardj sigemptyset(&sigusr1); 43cbdddcfb32883a37e873907602d34bac523e3eadsewardj sigaddset(&sigusr1, SIGUSR1); 44cbdddcfb32883a37e873907602d34bac523e3eadsewardj 45cbdddcfb32883a37e873907602d34bac523e3eadsewardj sigprocmask(SIG_BLOCK, &all, NULL); 46cbdddcfb32883a37e873907602d34bac523e3eadsewardj 47cbdddcfb32883a37e873907602d34bac523e3eadsewardj signal(SIGUSR1, handler); 48cff47f6d07be8dcdc8e12d57f8248b5c1cef21f4njn signal(SIGHUP, handler); 49cbdddcfb32883a37e873907602d34bac523e3eadsewardj 50cbdddcfb32883a37e873907602d34bac523e3eadsewardj printf("1: sending signal\n"); 51cbdddcfb32883a37e873907602d34bac523e3eadsewardj kill(getpid(), SIGUSR1); 52cff47f6d07be8dcdc8e12d57f8248b5c1cef21f4njn kill(getpid(), SIGHUP); 53cbdddcfb32883a37e873907602d34bac523e3eadsewardj 54cbdddcfb32883a37e873907602d34bac523e3eadsewardj printf("2: sleeping\n"); 55cbdddcfb32883a37e873907602d34bac523e3eadsewardj sleep(1); 56cbdddcfb32883a37e873907602d34bac523e3eadsewardj 57cbdddcfb32883a37e873907602d34bac523e3eadsewardj if (gotsig) { 58cbdddcfb32883a37e873907602d34bac523e3eadsewardj fprintf(stderr, "FAILED: signal delivered too early\n"); 59cbdddcfb32883a37e873907602d34bac523e3eadsewardj return 1; 60cbdddcfb32883a37e873907602d34bac523e3eadsewardj } 61cbdddcfb32883a37e873907602d34bac523e3eadsewardj 62cbdddcfb32883a37e873907602d34bac523e3eadsewardj printf("3: unblocking\n"); 63cbdddcfb32883a37e873907602d34bac523e3eadsewardj early = 0; 64cbdddcfb32883a37e873907602d34bac523e3eadsewardj sigprocmask(SIG_UNBLOCK, &sigusr1, NULL); 65cbdddcfb32883a37e873907602d34bac523e3eadsewardj 66cbdddcfb32883a37e873907602d34bac523e3eadsewardj printf("5: unblocked...\n"); 67cbdddcfb32883a37e873907602d34bac523e3eadsewardj if (!gotsig) { 68cbdddcfb32883a37e873907602d34bac523e3eadsewardj fprintf(stderr, "FAILED: signal not delivered\n"); 69cbdddcfb32883a37e873907602d34bac523e3eadsewardj return 1; 70cbdddcfb32883a37e873907602d34bac523e3eadsewardj } 71cbdddcfb32883a37e873907602d34bac523e3eadsewardj 72cff47f6d07be8dcdc8e12d57f8248b5c1cef21f4njn printf("6: checking SIGHUP still pending...\n"); 736cc2247cdfab852131fd392fb041ed07cd9117c6njn# if HAVE_SIGWAITINFO 746cc2247cdfab852131fd392fb041ed07cd9117c6njn { 756cc2247cdfab852131fd392fb041ed07cd9117c6njn siginfo_t info; 766cc2247cdfab852131fd392fb041ed07cd9117c6njn if (sigwaitinfo(&all, &info) == -1) { 776cc2247cdfab852131fd392fb041ed07cd9117c6njn perror("FAILED: sigwaitinfo failed"); 786cc2247cdfab852131fd392fb041ed07cd9117c6njn return 1; 796cc2247cdfab852131fd392fb041ed07cd9117c6njn } 80cff47f6d07be8dcdc8e12d57f8248b5c1cef21f4njn if (info.si_signo != SIGHUP) { 81cff47f6d07be8dcdc8e12d57f8248b5c1cef21f4njn fprintf(stderr, "FAILED: SIGHUP not still pending; got signal %d\n", 826cc2247cdfab852131fd392fb041ed07cd9117c6njn info.si_signo); 836cc2247cdfab852131fd392fb041ed07cd9117c6njn return 1; 846cc2247cdfab852131fd392fb041ed07cd9117c6njn } 85cbdddcfb32883a37e873907602d34bac523e3eadsewardj } 866cc2247cdfab852131fd392fb041ed07cd9117c6njn# endif 87cbdddcfb32883a37e873907602d34bac523e3eadsewardj 88cbdddcfb32883a37e873907602d34bac523e3eadsewardj printf("OK\n"); 89cbdddcfb32883a37e873907602d34bac523e3eadsewardj return 0; 90cbdddcfb32883a37e873907602d34bac523e3eadsewardj} 91