1 /* 2 * Copyright (c) 2002-2003, Intel Corporation. All rights reserved. 3 * Created by: Rusty.Lnch 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 Test assertion #9 by verifying that SIGCHLD signals are not sent when 9 the parent has setup a SIGCHLD signal handler with the SA_NOCLDSTOP flag set 10 * 12/18/02 - Adding in include of sys/time.h per 11 * rodrigc REMOVE-THIS AT attbi DOT com input that it needs 12 * to be included whenever the timeval struct is used. 13 * 14 */ 15 16 /* 17 * adam.li (at) intel.com: 2004-05-26: select should block child 18 */ 19 20 #include <signal.h> 21 #include <stdio.h> 22 #include <stdlib.h> 23 #include <sys/select.h> 24 #include <sys/wait.h> 25 #include <sys/time.h> 26 #include <sys/types.h> 27 #include <unistd.h> 28 29 #define NUMSTOPS 10 30 31 volatile int child_stopped = 0; 32 33 void handler(int signo, siginfo_t * info, void *context) 34 { 35 if (info && info->si_code == CLD_STOPPED) { 36 printf("Child has been stopped\n"); 37 child_stopped++; 38 } 39 } 40 41 int main(void) 42 { 43 pid_t pid; 44 struct sigaction act; 45 struct timeval tv; 46 47 act.sa_sigaction = handler; 48 act.sa_flags = SA_SIGINFO | SA_NOCLDSTOP; 49 sigemptyset(&act.sa_mask); 50 sigaction(SIGCHLD, &act, 0); 51 52 if ((pid = fork()) == 0) { 53 /* child */ 54 /* wait forever, or until we are 55 interrupted by a signal */ 56 select(0, NULL, NULL, NULL, NULL); 57 return 0; 58 } else { 59 /* parent */ 60 int s; 61 int i; 62 63 for (i = 0; i < NUMSTOPS; i++) { 64 printf("--> Sending SIGSTOP\n"); 65 kill(pid, SIGSTOP); 66 67 /* 68 If we send a bunch of SIGSTOP/SIGCONT 69 signals one after the other then it is 70 perfectly OK for the OS to not send 71 the SIGSTOP/SIGCONT combination as an 72 optimization. 73 74 I can't think of any POSIX method to determine 75 if a process has been stopped, so I'm 76 going to punt with a one second sleep and 77 assume the child process gets put to sleep 78 within that time period. This will be problem 79 when this test is run on a really stressed 80 system. (Although since we are sending multiple 81 SIGSTOP's then maybe in practice this will 82 cause any problems.) 83 */ 84 tv.tv_sec = 1; 85 tv.tv_usec = 0; 86 select(0, NULL, NULL, NULL, &tv); 87 88 printf("--> Sending SIGCONT\n"); 89 kill(pid, SIGCONT); 90 } 91 92 kill(pid, SIGKILL); 93 waitpid(pid, &s, 0); 94 } 95 96 if (child_stopped == 0) { 97 printf("Test PASSED\n"); 98 return 0; 99 } 100 101 printf("Test FAILED\n"); 102 return -1; 103 } 104