robbiew | 0dc0765 | 2005-06-03 16:29:48 +0000 | [diff] [blame] | 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 |
Garrett Cooper | 2c28215 | 2010-12-16 00:55:50 -0800 | [diff] [blame] | 5 | * of this license, see the COPYING file at the top level of this |
robbiew | 0dc0765 | 2005-06-03 16:29:48 +0000 | [diff] [blame] | 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. |
Garrett Cooper | 2c28215 | 2010-12-16 00:55:50 -0800 | [diff] [blame] | 15 | 2. From the parent, send the child a SIGUSR1 signal so that the child returns from |
robbiew | 0dc0765 | 2005-06-03 16:29:48 +0000 | [diff] [blame] | 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 recieved 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 | |
Garrett Cooper | a1a9207 | 2011-01-16 18:07:18 -0800 | [diff] [blame] | 36 | #define NUMSIGNALS (sizeof(siglist) / sizeof(siglist[0])) |
robbiew | 0dc0765 | 2005-06-03 16:29:48 +0000 | [diff] [blame] | 37 | |
| 38 | void handler(int signo) |
| 39 | { |
robbiew | 0dc0765 | 2005-06-03 16:29:48 +0000 | [diff] [blame] | 40 | } |
| 41 | |
| 42 | int is_changed(sigset_t set, int sig) { |
Garrett Cooper | 2c28215 | 2010-12-16 00:55:50 -0800 | [diff] [blame] | 43 | |
robbiew | 0dc0765 | 2005-06-03 16:29:48 +0000 | [diff] [blame] | 44 | int i; |
Garrett Cooper | 2c28215 | 2010-12-16 00:55:50 -0800 | [diff] [blame] | 45 | int siglist[] = {SIGABRT, SIGALRM, SIGBUS, SIGCHLD, |
| 46 | SIGCONT, SIGFPE, SIGHUP, SIGILL, SIGINT, |
| 47 | SIGPIPE, SIGQUIT, SIGSEGV, |
| 48 | SIGTERM, SIGTSTP, SIGTTIN, SIGTTOU, |
Garrett Cooper | d3df7e0 | 2011-01-16 17:55:25 -0800 | [diff] [blame] | 49 | SIGUSR1, SIGUSR2, |
| 50 | #ifdef SIGPOLL |
| 51 | SIGPOLL, |
| 52 | #endif |
| 53 | #ifdef SIGPROF |
| 54 | SIGPROF, |
| 55 | #endif |
| 56 | SIGSYS, |
robbiew | 0dc0765 | 2005-06-03 16:29:48 +0000 | [diff] [blame] | 57 | SIGTRAP, SIGURG, SIGVTALRM, SIGXCPU, SIGXFSZ }; |
| 58 | |
| 59 | if (sigismember(&set, sig) != 1) { |
| 60 | return 1; |
| 61 | } |
| 62 | for (i=0; i<NUMSIGNALS; i++) { |
| 63 | if ((siglist[i] != sig)) { |
| 64 | if (sigismember(&set, siglist[i]) != 0) { |
| 65 | return 1; |
| 66 | } |
| 67 | } |
| 68 | } |
| 69 | return 0; |
| 70 | } |
| 71 | |
| 72 | int main() |
| 73 | { |
| 74 | pid_t pid; |
| 75 | pid = fork(); |
| 76 | |
| 77 | if (pid == 0) { |
| 78 | /* child */ |
| 79 | |
| 80 | sigset_t tempmask, originalmask, currentmask; |
| 81 | |
| 82 | struct sigaction act; |
| 83 | |
| 84 | act.sa_handler = handler; |
| 85 | act.sa_flags=0; |
| 86 | sigemptyset(&act.sa_mask); |
| 87 | |
| 88 | sigemptyset(&tempmask); |
| 89 | sigaddset(&tempmask, SIGUSR2); |
| 90 | |
Garrett Cooper | a1a9207 | 2011-01-16 18:07:18 -0800 | [diff] [blame] | 91 | if (sigaction(SIGUSR1, &act, 0) == -1) { |
robbiew | 0dc0765 | 2005-06-03 16:29:48 +0000 | [diff] [blame] | 92 | perror("Unexpected error while attempting to pre-conditions"); |
| 93 | return PTS_UNRESOLVED; |
| 94 | } |
| 95 | |
| 96 | sigemptyset(&originalmask); |
| 97 | sigaddset(&originalmask, SIGUSR1); |
| 98 | sigprocmask(SIG_SETMASK, &originalmask, NULL); |
| 99 | |
| 100 | printf("suspending child\n"); |
| 101 | if (sigsuspend(&tempmask) != -1) |
| 102 | perror("sigsuspend error"); |
| 103 | |
| 104 | printf("returned from suspend\n"); |
| 105 | |
| 106 | sigprocmask(SIG_SETMASK, NULL, ¤tmask); |
| 107 | |
| 108 | if (is_changed(currentmask, SIGUSR1) != 0) { |
| 109 | printf("signal mask was not restored properly after sigsuspend returned\n"); |
| 110 | return 1; |
| 111 | } |
Garrett Cooper | 58c769b | 2010-12-19 17:40:59 -0800 | [diff] [blame] | 112 | return 0; |
robbiew | 0dc0765 | 2005-06-03 16:29:48 +0000 | [diff] [blame] | 113 | |
| 114 | } else { |
Garrett Cooper | 2c28215 | 2010-12-16 00:55:50 -0800 | [diff] [blame] | 115 | int s; |
robbiew | 0dc0765 | 2005-06-03 16:29:48 +0000 | [diff] [blame] | 116 | int exit_status; |
| 117 | |
| 118 | /* parent */ |
| 119 | sleep(1); |
| 120 | |
| 121 | printf("parent sending child a SIGUSR1 signal\n"); |
| 122 | kill (pid, SIGUSR1); |
| 123 | |
| 124 | if (wait(&s) == -1) { |
| 125 | perror("Unexpected error while setting up test " |
| 126 | "pre-conditions"); |
| 127 | return PTS_UNRESOLVED; |
| 128 | } |
| 129 | |
| 130 | if (!WIFEXITED(s)) { |
| 131 | printf("Test FAILED: Did not exit normally\n"); |
Garrett Cooper | 2c28215 | 2010-12-16 00:55:50 -0800 | [diff] [blame] | 132 | return PTS_FAIL; |
robbiew | 0dc0765 | 2005-06-03 16:29:48 +0000 | [diff] [blame] | 133 | } |
| 134 | |
| 135 | exit_status = WEXITSTATUS(s); |
| 136 | |
| 137 | printf("Exit status from child is %d\n", exit_status); |
| 138 | |
| 139 | if (exit_status == 1) { |
| 140 | return PTS_FAIL; |
| 141 | } |
| 142 | |
| 143 | printf("Test PASSED\n"); |
| 144 | return PTS_PASS; |
| 145 | } |
Garrett Cooper | d3df7e0 | 2011-01-16 17:55:25 -0800 | [diff] [blame] | 146 | } |