1 /* 2 * Copyright (c) 2003, Intel Corporation. All rights reserved. 3 * Created by: salwan.searty REMOVE-THIS AT intel DOT com 4 * This file is licensed under the GPL license. For the full content 5 * of this license, see the COPYING file at the top level of this 6 * source tree. 7 8 Assumption: The test assumes that this program is run under normal conditions, 9 and not when the processor and other resources are too stressed. 10 11 Steps: 12 1. Fork() a child process. In the child, add SIGUSR1 to the process's signal mask. 13 This is its original signal mask. Now suspend the child, passing sigsuspend another 14 signal mask. One that doesn't contain SIGUSR1, but contains SIGUSR2. 15 2. From the parent, send the child a SIGUSR1 signal so that the child returns from 16 suspension. 17 3. Once the sigsuspend returns, have the child probe the signal mask using the is_changed() 18 function which basically verifies that the signal mask is restored to what it was originally 19 before the call to sigsuspend. I.e. SIGUSR1 in the mask and SIGUSR2 not in the mask. Have 20 the child return to the parent process with: 21 - a return value of 1 if the original signal mask was not restored, or 22 - a return value of 0 if the original signal mask was successfully restored. 23 4. Finally from the parent, return a PTS_PASS if received the return value of the child was not 24 a 1. 25 26 */ 27 28 #include <signal.h> 29 #include <sys/types.h> 30 #include <sys/wait.h> 31 #include <stdio.h> 32 #include <stdlib.h> 33 #include <unistd.h> 34 #include "posixtest.h" 35 36 #define NUMSIGNALS (sizeof(siglist) / sizeof(siglist[0])) 37 38 void handler(int signo) 39 { 40 } 41 42 int is_changed(sigset_t set, int sig) 43 { 44 45 int i; 46 int siglist[] = { SIGABRT, SIGALRM, SIGBUS, SIGCHLD, 47 SIGCONT, SIGFPE, SIGHUP, SIGILL, SIGINT, 48 SIGPIPE, SIGQUIT, SIGSEGV, 49 SIGTERM, SIGTSTP, SIGTTIN, SIGTTOU, 50 SIGUSR1, SIGUSR2, 51 #ifdef SIGPOLL 52 SIGPOLL, 53 #endif 54 #ifdef SIGPROF 55 SIGPROF, 56 #endif 57 SIGSYS, 58 SIGTRAP, SIGURG, SIGVTALRM, SIGXCPU, SIGXFSZ 59 }; 60 61 if (sigismember(&set, sig) != 1) { 62 return 1; 63 } 64 for (i = 0; i < NUMSIGNALS; i++) { 65 if ((siglist[i] != sig)) { 66 if (sigismember(&set, siglist[i]) != 0) { 67 return 1; 68 } 69 } 70 } 71 return 0; 72 } 73 74 int main(void) 75 { 76 pid_t pid; 77 pid = fork(); 78 79 if (pid == 0) { 80 /* child */ 81 82 sigset_t tempmask, originalmask, currentmask; 83 84 struct sigaction act; 85 86 act.sa_handler = handler; 87 act.sa_flags = 0; 88 sigemptyset(&act.sa_mask); 89 90 sigemptyset(&tempmask); 91 sigaddset(&tempmask, SIGUSR2); 92 93 if (sigaction(SIGUSR1, &act, 0) == -1) { 94 perror 95 ("Unexpected error while attempting to pre-conditions"); 96 return PTS_UNRESOLVED; 97 } 98 99 sigemptyset(&originalmask); 100 sigaddset(&originalmask, SIGUSR1); 101 sigprocmask(SIG_SETMASK, &originalmask, NULL); 102 103 printf("suspending child\n"); 104 if (sigsuspend(&tempmask) != -1) 105 perror("sigsuspend error"); 106 107 printf("returned from suspend\n"); 108 109 sigprocmask(SIG_SETMASK, NULL, ¤tmask); 110 111 if (is_changed(currentmask, SIGUSR1) != 0) { 112 printf 113 ("signal mask was not restored properly after sigsuspend returned\n"); 114 return 1; 115 } 116 return 0; 117 118 } else { 119 int s; 120 int exit_status; 121 122 /* parent */ 123 sleep(1); 124 125 printf("parent sending child a SIGUSR1 signal\n"); 126 kill(pid, SIGUSR1); 127 128 if (wait(&s) == -1) { 129 perror("Unexpected error while setting up test " 130 "pre-conditions"); 131 return PTS_UNRESOLVED; 132 } 133 134 if (!WIFEXITED(s)) { 135 printf("Test FAILED: Did not exit normally\n"); 136 return PTS_FAIL; 137 } 138 139 exit_status = WEXITSTATUS(s); 140 141 printf("Exit status from child is %d\n", exit_status); 142 143 if (exit_status == 1) { 144 return PTS_FAIL; 145 } 146 147 printf("Test PASSED\n"); 148 return PTS_PASS; 149 } 150 } 151