1/* 2 * Copyright (c) 2002-2003, Intel Corporation. All rights reserved. 3 * Created by: Rusty.Lynch 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 #11 by verifying that SIGCHLD signals are sent to a parent 9 when their children are continued after being stopped. 10 11 NOTE: This is only required to work if the XSI options are implemented. 12 * 12/18/02 - Adding in include of sys/time.h per 13 * rodrigc REMOVE-THIS AT attbi DOT com input that it needs 14 * to be included whenever the timeval struct is used. 15 * 16*/ 17 18#include <signal.h> 19#include <stdio.h> 20#include <stdlib.h> 21#include <sys/select.h> 22#include <sys/wait.h> 23#include <sys/time.h> 24#include <sys/types.h> 25#include <unistd.h> 26#include "posixtest.h" 27 28#define NUMSTOPS 2 29 30int child_continued = 0; 31int waiting = 1; 32 33void handler(int signo, siginfo_t * info, void *context) 34{ 35 if (info && info->si_code == CLD_CONTINUED) { 36 printf("Child has been stopped\n"); 37 waiting = 0; 38 child_continued++; 39 } 40} 41 42int main(void) 43{ 44 pid_t pid; 45 struct sigaction act; 46 struct timeval tv; 47 48 act.sa_sigaction = handler; 49 act.sa_flags = SA_SIGINFO; 50 sigemptyset(&act.sa_mask); 51 sigaction(SIGCHLD, &act, 0); 52 53 if ((pid = fork()) == 0) { 54 /* child */ 55 while (1) { 56 /* wait forever, or until we are 57 interrupted by a signal */ 58 tv.tv_sec = 0; 59 tv.tv_usec = 0; 60 select(0, NULL, NULL, NULL, &tv); 61 } 62 return 0; 63 } else { 64 /* parent */ 65 int s; 66 int i; 67 68 /* delay to allow child to get into select call */ 69 tv.tv_sec = 1; 70 tv.tv_usec = 0; 71 select(0, NULL, NULL, NULL, &tv); 72 73 for (i = 0; i < NUMSTOPS; i++) { 74 struct timeval tv; 75 printf("--> Sending SIGSTOP\n"); 76 kill(pid, SIGSTOP); 77 78 /* 79 Don't let the kernel optimize away queued 80 SIGSTOP/SIGCONT signals. 81 */ 82 tv.tv_sec = 1; 83 tv.tv_usec = 0; 84 select(0, NULL, NULL, NULL, &tv); 85 86 printf("--> Sending SIGCONT\n"); 87 waiting = 1; 88 kill(pid, SIGCONT); 89 while (waiting) { 90 tv.tv_sec = 1; 91 tv.tv_usec = 0; 92 if (!select(0, NULL, NULL, NULL, &tv)) 93 break; 94 } 95 96 } 97 98 kill(pid, SIGKILL); 99 waitpid(pid, &s, 0); 100 } 101 102 if (child_continued == NUMSTOPS) { 103 printf("Test PASSED\n"); 104 printf 105 ("In the section of the POSIX spec that describes the SA_NOCLDSTOP flag in the sigaction() interface " 106 "it is specified that if the SA_NOCLDSTOP flag is not set in sa_flags, then a SIGCHLD and a SIGCHLD " 107 "signal **MAY** be generated for the calling process whenever any of its stopped child processes are continued. " 108 "Because of that, this test will PASS either way, but note that the signals implementation you are currently " 109 "run this test on DOES choose to send a SIGCHLD signal whenever any of its stopped child processes are " 110 "continued. Again, this is not a bug because of the existence of the word *MAY* in the spec.\n"); 111 return PTS_PASS; 112 } 113 114 printf("Test PASSED\n"); 115 116 printf 117 ("In the section of the POSIX spec that describes the SA_NOCLDSTOP flag in the sigaction() interface " 118 "it is specified that if the SA_NOCLDSTOP flag is not set in sa_flags, then a SIGCHLD and a SIGCHLD " 119 "signal **MAY** be generated for the calling process whenever any of its stopped child processes are continued. " 120 "Because of that, this test will PASS either way, but note that the signals implementation you are currently " 121 "run this test on chooses NOT TO send a SIGCHLD signal whenever any of its stopped child processes are " 122 "continued. Again, this is not a bug because of the existence of the word *MAY* in the spec.\n"); 123 return PTS_PASS; 124} 125