1/* 2* Copyright (c) 2004, Bull S.A.. All rights reserved. 3* Created by: Sebastien Decugis 4 5* This program is free software; you can redistribute it and/or modify it 6* under the terms of version 2 of the GNU General Public License as 7* published by the Free Software Foundation. 8* 9* This program is distributed in the hope that it would be useful, but 10* WITHOUT ANY WARRANTY; without even the implied warranty of 11* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12* 13* You should have received a copy of the GNU General Public License along 14* with this program; if not, write the Free Software Foundation, Inc., 15* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 17* This sample test aims to check the following assertion: 18* 19* The child process is created with no pending signal 20 21* The steps are: 22* -> block SIGUSR1 and SIGUSR2 23* -> send those signals and wait they are pending 24* -> fork 25* -> check the signals are blocked but not pending in the new process. 26 27* The test fails if the signals are pending or if 28* they are not blocked (this counters assertion 2). 29 30*/ 31 32/* We are testing conformance to IEEE Std 1003.1, 2003 Edition */ 33#define _POSIX_C_SOURCE 200112L 34 35#include <pthread.h> 36#include <stdarg.h> 37#include <stdio.h> 38#include <stdlib.h> 39#include <string.h> 40#include <unistd.h> 41 42#include <sys/wait.h> 43#include <errno.h> 44 45#include <signal.h> 46 47#include "../testfrmw/testfrmw.h" 48#include "../testfrmw/testfrmw.c" 49 50#ifndef VERBOSE 51#define VERBOSE 1 52#endif 53 54int main(void) 55{ 56 int ret, status; 57 pid_t child, ctl; 58 59 sigset_t mask, pending; 60 61 output_init(); 62 63 /* block SIGUSR1 and SIGUSR2 */ 64 ret = sigemptyset(&mask); 65 66 if (ret != 0) { 67 UNRESOLVED(errno, "Failed to initialize signal set"); 68 } 69 70 ret = sigaddset(&mask, SIGUSR1); 71 72 if (ret != 0) { 73 UNRESOLVED(errno, "Failed to add SIGUSR1 to signal set"); 74 } 75 76 ret = sigaddset(&mask, SIGUSR2); 77 78 if (ret != 0) { 79 UNRESOLVED(errno, "Failed to add SIGUSR2 to signal set"); 80 } 81 82 ret = sigprocmask(SIG_BLOCK, &mask, NULL); 83 84 if (ret != 0) { 85 UNRESOLVED(errno, "Sigprocmask failed"); 86 } 87 88 /* Make the signals pending */ 89 ret = kill(getpid(), SIGUSR1); 90 91 if (ret != 0) { 92 UNRESOLVED(errno, "failed to kill with SIGUSR1"); 93 } 94 95 ret = kill(getpid(), SIGUSR2); 96 97 if (ret != 0) { 98 UNRESOLVED(errno, "failed to kill with SIGUSR2"); 99 } 100 101 do { 102 ret = sigpending(&pending); 103 104 if (ret != 0) { 105 UNRESOLVED(errno, 106 "failed to examine pending signal set"); 107 } 108 109 ret = sigismember(&pending, SIGUSR1); 110 111 if (ret < 0) { 112 UNRESOLVED(errno, 113 "Unable to check signal USR1 presence"); 114 } 115 116 if (ret == 1) { 117 ret = sigismember(&pending, SIGUSR2); 118 119 if (ret < 0) { 120 UNRESOLVED(errno, 121 "Unable to check signal USR2 presence"); 122 } 123 } 124 } 125 while (ret != 1); 126 127#if VERBOSE > 0 128 129 output("SIGUSR1 and SIGUSR2 are pending, we can fork\n"); 130 131#endif 132 133 /* Create the child */ 134 child = fork(); 135 136 if (child == -1) { 137 UNRESOLVED(errno, "Failed to fork"); 138 } 139 140 /* child */ 141 if (child == 0) { 142 /* Examine the current blocked signal set. USR1 & USR2 shall be present */ 143 ret = sigprocmask(0, NULL, &mask); 144 145 if (ret != 0) { 146 UNRESOLVED(errno, "Sigprocmask failed in child"); 147 } 148 149 ret = sigismember(&mask, SIGUSR1); 150 151 if (ret < 0) { 152 UNRESOLVED(errno, 153 "Unable to check signal USR1 presence"); 154 } 155 156 if (ret == 0) { 157 FAILED 158 ("The new process does not mask SIGUSR1 as its parent"); 159 } 160 161 ret = sigismember(&mask, SIGUSR2); 162 163 if (ret < 0) { 164 UNRESOLVED(errno, 165 "Unable to check signal USR2 presence"); 166 } 167 168 if (ret == 0) { 169 FAILED 170 ("The new process does not mask SIGUSR2 as its parent"); 171 } 172#if VERBOSE > 0 173 output("SIGUSR1 and SIGUSR2 are blocked in child\n"); 174 175#endif 176 177 /* Examine pending signals */ 178 ret = sigpending(&pending); 179 180 if (ret != 0) { 181 UNRESOLVED(errno, 182 "failed to examine pending signal set in child"); 183 } 184 185 ret = sigismember(&pending, SIGUSR1); 186 187 if (ret < 0) { 188 UNRESOLVED(errno, 189 "Unable to check signal USR1 presence"); 190 } 191 192 if (ret != 0) { 193 FAILED 194 ("The new process was created with SIGUSR1 pending"); 195 } 196 197 ret = sigismember(&pending, SIGUSR2); 198 199 if (ret < 0) { 200 UNRESOLVED(errno, 201 "Unable to check signal USR2 presence"); 202 } 203 204 if (ret != 0) { 205 FAILED 206 ("The new process was created with SIGUSR2 pending"); 207 } 208#if VERBOSE > 0 209 output("SIGUSR1 and SIGUSR2 are not pending in child\n"); 210 211#endif 212 213 /* We're done */ 214 exit(PTS_PASS); 215 } 216 217 /* Parent joins the child */ 218 ctl = waitpid(child, &status, 0); 219 220 if (ctl != child) { 221 UNRESOLVED(errno, "Waitpid returned the wrong PID"); 222 } 223 224 if (!WIFEXITED(status) || (WEXITSTATUS(status) != PTS_PASS)) { 225 FAILED("Child exited abnormally"); 226 } 227 228#if VERBOSE > 0 229 230 output("Test passed\n"); 231 232#endif 233 234 PASSED; 235} 236