Home | History | Annotate | Download | only in killpg
      1 /*
      2  * Copyright (c) 2002-2003, Intel Corporation. All rights reserved.
      3  * Created by:  salwan.searty 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  *   Steps:
      9  *  1) Fork a child process.
     10  *  2) In the parent process, call killpg with signal SIGTOTEST for the
     11  *     process group id of the child. Have the parent ignore such a signal
     12  *     incase the process group id of the parent is the same as process
     13  *     group id of the child.
     14  *  In the child,
     15  *    3) Wait for signal SIGTOTEST.
     16  *    4) Return 1 if SIGTOTEST is found.  Return 0 otherwise.
     17  *  5) In the parent, return success if 1 was returned from child.
     18  *
     19  */
     20 
     21 #define _XOPEN_SOURCE 600
     22 #define SIGTOTEST SIGUSR1
     23 
     24 #include <signal.h>
     25 #include <stdio.h>
     26 #include <stdlib.h>
     27 #include <unistd.h>
     28 #include <sys/wait.h>
     29 #include "posixtest.h"
     30 
     31 void myhandler(int signo)
     32 {
     33 	(void) signo;
     34 	_exit(1);
     35 }
     36 
     37 int main(void)
     38 {
     39 	int child_pid, child_pgid;
     40 
     41 	if ((child_pid = fork()) == 0) {
     42 		/* child here */
     43 		struct sigaction act;
     44 		act.sa_handler = myhandler;
     45 		act.sa_flags = 0;
     46 		sigemptyset(&act.sa_mask);
     47 		sigaction(SIGTOTEST, &act, 0);
     48 
     49 		/* change child's process group id */
     50 
     51 		/*
     52 		 * XXX: POSIX 1003.1-2001 added setpgrp(2) to BASE, but
     53 		 * unfortunately BSD has had their own implementations for
     54 		 * ages for compatibility reasons.
     55 		 */
     56 #if __FreeBSD__ || __NetBSD__ || __OpenBSD__
     57 		setpgrp(0, 0);
     58 #else
     59 		setpgrp();
     60 #endif
     61 
     62 		sigpause(SIGABRT);
     63 
     64 		return 0;
     65 	} else {
     66 		/* parent here */
     67 		int i;
     68 		sigignore(SIGTOTEST);
     69 
     70 		sleep(1);
     71 		if ((child_pgid = getpgid(child_pid)) == -1) {
     72 			printf("Could not get pgid of child\n");
     73 			return PTS_UNRESOLVED;
     74 		}
     75 
     76 		if (killpg(child_pgid, SIGTOTEST) != 0) {
     77 			printf("Could not raise signal being tested\n");
     78 			return PTS_UNRESOLVED;
     79 		}
     80 
     81 		if (wait(&i) == -1) {
     82 			perror("Error waiting for child to exit\n");
     83 			return PTS_UNRESOLVED;
     84 		}
     85 
     86 		if (WEXITSTATUS(i)) {
     87 			printf("Child exited normally\n");
     88 			printf("Test PASSED\n");
     89 			return PTS_PASS;
     90 		} else {
     91 			printf("Child did not exit normally.\n");
     92 			printf("Test FAILED\n");
     93 			return PTS_FAIL;
     94 		}
     95 	}
     96 
     97 	printf("Should have exited from parent\n");
     98 	printf("Test FAILED\n");
     99 	return PTS_FAIL;
    100 }
    101