Home | History | Annotate | Download | only in sigaction
      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