• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 LTP_ATTRIBUTE_UNUSED,siginfo_t * info,void * context LTP_ATTRIBUTE_UNUSED)34 void handler(int signo LTP_ATTRIBUTE_UNUSED, siginfo_t *info,
35 	void *context LTP_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 		/* child */
56 		/* wait forever, or until we are
57 		   interrupted by a signal */
58 		select(0, NULL, NULL, NULL, NULL);
59 		return 0;
60 	} else {
61 		/* parent */
62 		int s;
63 		int i;
64 
65 		for (i = 0; i < NUMSTOPS; i++) {
66 			printf("--> Sending SIGSTOP\n");
67 			kill(pid, SIGSTOP);
68 
69 			/*
70 			   If we send a bunch of SIGSTOP/SIGCONT
71 			   signals one after the other then it is
72 			   perfectly OK for the OS to not send
73 			   the SIGSTOP/SIGCONT combination as an
74 			   optimization.
75 
76 			   I can't think of any POSIX method to determine
77 			   if a process has been stopped, so I'm
78 			   going to punt with a one second sleep and
79 			   assume the child process gets put to sleep
80 			   within that time period.  This will be problem
81 			   when this test is run on a really stressed
82 			   system. (Although since we are sending multiple
83 			   SIGSTOP's then maybe in practice this will
84 			   cause any problems.)
85 			 */
86 			tv.tv_sec = 1;
87 			tv.tv_usec = 0;
88 			select(0, NULL, NULL, NULL, &tv);
89 
90 			printf("--> Sending SIGCONT\n");
91 			kill(pid, SIGCONT);
92 		}
93 
94 		kill(pid, SIGKILL);
95 		waitpid(pid, &s, 0);
96 	}
97 
98 	if (child_stopped == 0) {
99 		printf("Test PASSED\n");
100 		return 0;
101 	}
102 
103 	printf("Test FAILED\n");
104 	return -1;
105 }
106