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@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 #include "posixtest.h"
29
30 #define NUMSTOPS 10
31
32 static volatile int child_stopped;
33
handler(int signo PTS_ATTRIBUTE_UNUSED,siginfo_t * info,void * context PTS_ATTRIBUTE_UNUSED)34 static void handler(int signo PTS_ATTRIBUTE_UNUSED, siginfo_t *info,
35 void *context PTS_ATTRIBUTE_UNUSED)
36 {
37 if (info && info->si_code == CLD_STOPPED) {
38 printf("Child has been stopped\n");
39 child_stopped++;
40 }
41 }
42
main(void)43 int main(void)
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 | SA_NOCLDSTOP;
51 sigemptyset(&act.sa_mask);
52 sigaction(SIGCHLD, &act, 0);
53
54 if ((pid = fork()) < 0) {
55 printf("fork() did not return success\n");
56 return PTS_UNRESOLVED;
57 } else if (pid == 0) {
58 /* child */
59 /* wait forever, or until we are
60 interrupted by a signal */
61 select(0, NULL, NULL, NULL, NULL);
62 return 0;
63 } else {
64 /* parent */
65 int s;
66 int i;
67
68 for (i = 0; i < NUMSTOPS; i++) {
69 printf("--> Sending SIGSTOP\n");
70 kill(pid, SIGSTOP);
71
72 /*
73 If we send a bunch of SIGSTOP/SIGCONT
74 signals one after the other then it is
75 perfectly OK for the OS to not send
76 the SIGSTOP/SIGCONT combination as an
77 optimization.
78
79 I can't think of any POSIX method to determine
80 if a process has been stopped, so I'm
81 going to punt with a one second sleep and
82 assume the child process gets put to sleep
83 within that time period. This will be problem
84 when this test is run on a really stressed
85 system. (Although since we are sending multiple
86 SIGSTOP's then maybe in practice this will
87 cause any problems.)
88 */
89 tv.tv_sec = 1;
90 tv.tv_usec = 0;
91 select(0, NULL, NULL, NULL, &tv);
92
93 printf("--> Sending SIGCONT\n");
94 kill(pid, SIGCONT);
95 }
96
97 kill(pid, SIGKILL);
98 waitpid(pid, &s, 0);
99 }
100
101 if (child_stopped == 0) {
102 printf("Test PASSED\n");
103 return 0;
104 }
105
106 printf("Test FAILED\n");
107 return -1;
108 }
109