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 42 43int main() 44{ 45 pid_t pid; 46 struct sigaction act; 47 struct timeval tv; 48 49 act.sa_sigaction = handler; 50 act.sa_flags = SA_SIGINFO; 51 sigemptyset(&act.sa_mask); 52 sigaction(SIGCHLD, &act, 0); 53 54 if ((pid = fork()) == 0) { 55 /* child */ 56 while(1) { 57 /* wait forever, or until we are 58 interrupted by a signal */ 59 tv.tv_sec = 0; 60 tv.tv_usec = 0; 61 select(0, NULL, NULL, NULL, &tv); 62 } 63 return 0; 64 } else { 65 /* parent */ 66 int s; 67 int i; 68 69 /* delay to allow child to get into select call */ 70 tv.tv_sec = 1; 71 tv.tv_usec = 0; 72 select(0, NULL, NULL, NULL, &tv); 73 74 for (i = 0; i < NUMSTOPS; i++) { 75 struct timeval tv; 76 printf("--> Sending SIGSTOP\n"); 77 kill(pid, SIGSTOP); 78 79 /* 80 Don't let the kernel optimize away queued 81 SIGSTOP/SIGCONT signals. 82 */ 83 tv.tv_sec = 1; 84 tv.tv_usec = 0; 85 select(0, NULL, NULL, NULL, &tv); 86 87 printf("--> Sending SIGCONT\n"); 88 waiting = 1; 89 kill(pid, SIGCONT); 90 while (waiting) { 91 tv.tv_sec = 1; 92 tv.tv_usec = 0; 93 if (!select(0, NULL, NULL, NULL, &tv)) 94 break; 95 } 96 97 } 98 99 /* POSIX specifies default action to be abnormal termination */ 100 kill(pid, SIGHUP); 101 waitpid(pid, &s, 0); 102 } 103 104 if (child_continued == NUMSTOPS) { 105 printf("Test PASSED\n"); 106 printf("In the section of the POSIX spec that describes the SA_NOCLDSTOP flag in the sigaction() interface " 107 "it is specified that if the SA_NOCLDSTOP flag is not set in sa_flags, then a SIGCHLD and a SIGCHLD " 108 "signal **MAY** be generated for the calling process whenever any of its stopped child processes are continued. " 109 "Because of that, this test will PASS either way, but note that the signals implementation you are currently " 110 "run this test on DOES choose to send a SIGCHLD signal whenever any of its stopped child processes are " 111 "continued. Again, this is not a bug because of the existence of the word *MAY* in the spec.\n"); 112 return PTS_PASS; 113 } 114 115 printf("Test PASSED\n"); 116 117 printf("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 126