• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2000 Silicon Graphics, Inc.  All Rights Reserved.
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of version 2 of the GNU General Public License as
6  * published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it would be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11  *
12  * Further, this software is distributed without any warranty that it is
13  * free of the rightful claim of any third person regarding infringement
14  * or the like.  Any license provided herein, whether implied or
15  * otherwise, applies only to this software file.  Patent licenses, if
16  * any, provided herein do not apply to combinations of this program with
17  * other software, or any other product whatsoever.
18  *
19  * You should have received a copy of the GNU General Public License along
20  * with this program; if not, write the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22  *
23  * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24  * Mountain View, CA  94043, or:
25  *
26  * http://www.sgi.com
27  *
28  * For further information regarding this notice, see:
29  *
30  * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
31  *
32  */
33 /* $Id: sigrelse01.c,v 1.14 2009/08/28 14:10:16 vapier Exp $ */
34 /*****************************************************************************
35  * OS Test - Silicon Graphics, Inc.  Eagan, Minnesota
36  *
37  * TEST IDENTIFIER : sigrelse01 Releasing held signals.
38  *
39  * PARENT DOCUMENT : sgrtds01  sigrelse system call
40  *
41  * AUTHOR          : Bob Clark
42  *		   : Rewrote 12/92 by Richard Logan
43  *
44  * CO-PILOT        : Dave Baumgartner
45  *
46  * DATE STARTED    : 10/08/86
47  *
48  * TEST ITEMS
49  *
50  * 	1. sigrelse turns on the receipt of signals held by sighold.
51  *
52  * SPECIAL PROCEDURAL REQUIRMENTS
53  * 	None
54  *
55  * DETAILED DESCRIPTION
56  * 	set up pipe for parent/child communications
57  * 	fork off a child process
58  *
59  * 	parent():
60  * 		set up for unexpected signals
61  * 		wait for child to send ready message over pipe
62  * 		send all catchable signals to child process
63  *		send alarm signal to speed up timeout
64  * 		wait for child to terminate and check exit value
65  *
66  * 		if exit value is EXIT_OK
67  * 		  get message from pipe (contains array of signal counters)
68  * 		  loop through array of signal counters and record any
69  * 			signals which were not caught once.
70  * 		  record PASS or FAIL depending on what was found in the array.
71  *
72  * 		else if exit is SIG_CAUGHT then BROK (signal caught
73  *		  before released)
74  * 		else if exit is WRITE_BROK then BROK (write() to pipe failed)
75  * 		else if exit is HANDLE_ERR then BROK (error in child's
76  *		  signal handler)
77  * 		else unexpected exit value - BROK
78  *
79  * 	child():
80  * 	  phase 1:
81  * 		set up to catch all catchable signals (exit SIG_CAUGHT
82  *		  if caught)
83  * 		hold each signal with sighold()
84  * 		send parent ready message if setup went ok.
85  * 		wait for signals to arrive - timeout if they don't
86  *
87  * 	  phase 2:
88  * 		release each signal and wait a second for the handler to
89  *		  catch it.
90  * 		(the handler will record each signal it catches in an array
91  * 		and exit HANDLE_ERR if an error occurs)
92  *
93  * 		send array of counters back to parent for processing.
94  * 		exit EXIT_OK
95  * NOTES
96  *	since child is executing system calls under test, no
97  *	system call times are printed.
98  *
99 ***************************************************************************/
100 
101 #include <sys/types.h>
102 #include <sys/wait.h>
103 #include <errno.h>
104 #include <fcntl.h>
105 #include <signal.h>
106 #include <stdlib.h>
107 #include <string.h>
108 #include <time.h>
109 #include <unistd.h>
110 #include "test.h"
111 #include "safe_macros.h"
112 
113 #ifdef __linux__
114 /* glibc2.2 definition needs -D_XOPEN_SOURCE, which breaks other things. */
115 extern int sighold(int __sig);
116 extern int sigrelse(int __sig);
117 #endif
118 
119 /* Needed for NPTL */
120 #define SIGCANCEL 32
121 #define SIGTIMER 33
122 
123 void setup(void);
124 void cleanup(void);
125 static void parent(void);
126 static void child(void);
127 static void timeout(int sig);
128 static int setup_sigs(void);
129 static void handler(int sig);
130 static void wait_a_while(void);
131 static char *read_pipe(int fd);
132 static int write_pipe(int fd, char *msg);
133 static int set_timeout(void);
134 static void clear_timeout(void);
135 static void getout(void);
136 int choose_sig(int sig);
137 
138 #define TRUE  1
139 #define FALSE 0
140 
141 #ifndef DEBUG
142 #define DEBUG 0
143 #endif
144 
145 #define CHILD_EXIT(VAL) ((VAL >> 8) & 0377)	/* exit value of child process */
146 #define CHILD_SIG(VAL)   (VAL & 0377)	/* signal value of child proc */
147 
148 #define MAXMESG 512		/* the size of the message string */
149 
150 #define READY "ready"		/* signal to parent that child is set up */
151 
152 #define TIMEOUT 30		/* time (sec) used in the alarm calls */
153 
154 /* child exit values */
155 #define EXIT_OK    0
156 #define SIG_CAUGHT 8
157 #define WRITE_BROK 16
158 #define HANDLE_ERR 32
159 
160 int TST_TOTAL = 1;		/* number of test items */
161 
162 char *TCID = "sigrelse01";	/* test case identifier */
163 static char mesg[MAXMESG];	/* message buffer for tst_res */
164 static int pid;			/* process id of child */
165 static int pipe_fd[2];		/* file descriptors for pipe parent read */
166 static int pipe_fd2[2];		/* file descriptors for pipe child read */
167 static int phase;		/* flag for phase1 or phase2 of */
168 				/* signal handler */
169 static int sig_caught;		/* flag TRUE if signal caught */
170 				/* (see wait_a_while ()) */
171 
172 /* ensure that NUMSIGS is defined. */
173 #ifndef NUMSIGS
174 #define NUMSIGS NSIG
175 #endif
176 
177 /* array of counters for signals caught by handler() */
178 static int sig_array[NUMSIGS];
179 
180 /***********************************************************************
181  *   M A I N
182  ***********************************************************************/
main(int argc,char ** argv)183 int main(int argc, char **argv)
184 {
185 	int lc;
186 
187 	/* gcc -Wall complains about sig_caught not being ref'd because of the
188 	   external declarations. */
189 	sig_caught = FALSE;
190 
191 	/*
192 	 * parse standard options
193 	 */
194 	tst_parse_opts(argc, argv, NULL, NULL);
195 #ifdef UCLINUX
196 	maybe_run_child(&child, "dd", &pipe_fd[1], &pipe_fd2[0]);
197 #endif
198 
199 	/*
200 	 * perform global setup for test
201 	 */
202 	setup();
203 
204 	for (lc = 0; TEST_LOOPING(lc); lc++) {
205 
206 		tst_count = 0;
207 
208 		/*
209 		 * fork off a child process
210 		 */
211 		if ((pid = FORK_OR_VFORK()) < 0) {
212 			tst_brkm(TBROK | TERRNO, cleanup, "fork() failed");
213 
214 		} else if (pid > 0) {
215 			parent();
216 
217 		} else {
218 #ifdef UCLINUX
219 			if (self_exec(argv[0], "dd", pipe_fd[1], pipe_fd2[0]) <
220 			    0) {
221 				tst_brkm(TBROK | TERRNO, cleanup,
222 					 "self_exec() failed");
223 			}
224 #else
225 			child();
226 #endif
227 		}
228 
229 	}
230 
231 	cleanup();
232 	tst_exit();
233 
234 }				/* end main */
235 
236 /****************************************************************************
237  * parent() : wait for "ready" from child, send signals to child, wait for
238  *    child to exit and report what happened.
239  ***************************************************************************/
parent(void)240 static void parent(void)
241 {
242 	int term_stat;		/* child return status */
243 	int rv;			/* function return value */
244 	int sig;		/* current signal number */
245 	char *str;		/* string returned from read_pipe() */
246 	int *array;		/* pointer to sig_array returned from child */
247 	int fail = FALSE;	/* flag indicating test item failure */
248 	char big_mesg[MAXMESG * 6];	/* storage for big failure message */
249 	int caught_sigs;
250 
251 	/* wait for "ready" message from child */
252 	if ((str = read_pipe(pipe_fd[0])) == NULL) {
253 		/* read_pipe() failed. */
254 		tst_brkm(TBROK, getout, "%s", mesg);
255 	}
256 
257 	if (strcmp(str, READY) != 0) {
258 		/* child setup did not go well */
259 		tst_brkm(TBROK, getout, "%s", str);
260 	}
261 
262 	/*
263 	 * send signals to child and see if it holds them
264 	 */
265 
266 	for (sig = 1; sig < NUMSIGS; sig++) {
267 		if (choose_sig(sig)) {
268 			if (kill(pid, sig) < 0) {
269 				if (errno == ESRCH) {
270 					if (kill(pid, SIGTERM) < 0)
271 						tst_brkm(TBROK | TERRNO, getout,
272 							 "kill(%d, %d) and kill(%d, SIGTERM) failed",
273 							 pid, sig, pid);
274 					else
275 						tst_brkm(TBROK | TERRNO, getout,
276 							 "kill(%d, %d) failed, but kill(%d, SIGTERM) worked",
277 							 pid, sig, pid);
278 				} else
279 					tst_brkm(TBROK | TERRNO, getout,
280 						 "kill(%d, %d) failed", pid,
281 						 sig);
282 			}
283 		}
284 	}
285 
286 	if (write_pipe(pipe_fd2[1], READY) < 0) {
287 		tst_brkm(TBROK | TERRNO, getout,
288 			 "Unable to tell child to go, write to pipe failed");
289 	}
290 
291 	/*
292 	 * child is now releasing signals, wait and check exit value
293 	 */
294 	if (wait(&term_stat) < 0)
295 		tst_brkm(TBROK | TERRNO, getout, "wait() failed");
296 
297 	/* check child's signal exit value */
298 	if ((sig = CHILD_SIG(term_stat)) != 0)
299 		/* the child was zapped by a signal */
300 		tst_brkm(TBROK, cleanup, "Unexpected signal %d killed child",
301 			 sig);
302 
303 	/* get child exit value */
304 
305 	rv = CHILD_EXIT(term_stat);
306 
307 	switch (rv) {
308 	case EXIT_OK:
309 		/* sig_array sent back on pipe, check it out */
310 		if ((array = (int *)read_pipe(pipe_fd[0])) == NULL) {
311 			/* read_pipe() failed. */
312 			tst_resm(TBROK, "%s", mesg);
313 			break;
314 		}
315 #if DEBUG > 1
316 		for (sig = 1; sig < NUMSIGS; sig++) {
317 			printf("array[%d] = %d\n", sig, array[sig]);
318 		}
319 #endif
320 		caught_sigs = 0;
321 		for (sig = 1; sig < NUMSIGS; sig++) {
322 			if (choose_sig(sig)) {
323 				if (array[sig] != 1) {
324 					/* sig was not caught or caught too many times */
325 					(void)sprintf(mesg,
326 						      "\tsignal %d caught %d times (expected 1).\n",
327 						      sig, array[sig]);
328 					(void)strcat(big_mesg, mesg);
329 					fail = TRUE;
330 				} else {
331 					caught_sigs++;
332 				}
333 			}
334 		}		/* endfor */
335 
336 		if (fail == TRUE)
337 			tst_resm(TFAIL, "%s", big_mesg);
338 		else
339 			tst_resm(TPASS,
340 				 "sigrelse() released all %d signals under test.",
341 				 caught_sigs);
342 		break;
343 
344 	case TBROK:
345 		/* get BROK message from pipe */
346 		if ((str = read_pipe(pipe_fd[0])) == NULL) {
347 			/* read_pipe() failed. */
348 			tst_resm(TBROK, "%s", mesg);
349 			break;
350 		}
351 
352 		/* call tst_res: str contains the message */
353 		tst_resm(TBROK, "%s", str);
354 		break;
355 	case SIG_CAUGHT:
356 		/* a signal was caught before it was released */
357 		tst_resm(TBROK, "A signal was caught before being released.");
358 		break;
359 	case WRITE_BROK:
360 		/* the write() call failed in child's write_pipe */
361 		tst_resm(TBROK, "write() pipe failed for child.");
362 		break;
363 	case HANDLE_ERR:
364 		/* more than one signal tried to be handled at the same time */
365 		tst_resm(TBROK, "Error occured in signal handler.");
366 		break;
367 	default:
368 		tst_resm(TBROK, "Unexpected exit code %d from child", rv);
369 		break;
370 	}
371 
372 }				/* end of parent */
373 
374 /****************************************************************************
375  * child() : hold signals, notify parent and wait for parent to send signals.
376  *   If none were caught (sighold worked), release the signals one at a time
377  *   and wait for them to be caught.  Send results back to parent
378  *   for processing.
379  ***************************************************************************/
child(void)380 static void child(void)
381 {
382 	int rv;			/* return value from sighold() and sigrelse() */
383 	int sig;		/* signal value */
384 	int exit_val;		/* exit value to send to parent */
385 	char note[MAXMESG];	/* message buffer for pipe */
386 	char *str;
387 
388 	phase = 1;		/* tell handler that we do not want to catch signals */
389 
390 	/* set note to READY and if an error occurs, overwrite it */
391 	(void)strcpy(note, READY);
392 
393 	/* set alarm in case something hangs */
394 	if (set_timeout() < 0) {
395 		/* an error occured - put mesg in note and send it back to parent */
396 		(void)strcpy(note, mesg);
397 
398 	} else if (setup_sigs() < 0) {
399 		/* an error occured - put mesg in note and send it back to parent */
400 		(void)strcpy(note, mesg);
401 
402 	} else {
403 		/* all set up to catch signals, now hold them */
404 
405 		for (sig = 1; sig < NUMSIGS; sig++) {
406 			if (choose_sig(sig)) {
407 				if ((rv = sighold(sig)) != 0) {
408 					/* THEY say sighold ALWAYS returns 0 */
409 					(void)sprintf(note,
410 						      "sighold did not return 0. rv:%d",
411 						      rv);
412 					break;
413 				}
414 			}
415 		}
416 
417 	}
418 
419 	/*
420 	 * send note to parent (if not READY, parent will BROK) and
421 	 * wait for parent to send signals.  The timeout clock is set so
422 	 * that we will not wait forever - if sighold() did its job, we
423 	 * will not receive the signals.  If sighold() blew it we will
424 	 * catch a signal and the interrupt handler will exit with a
425 	 * value of SIG_CAUGHT.
426 	 */
427 	if (write_pipe(pipe_fd[1], note) < 0) {
428 		/*
429 		 * write_pipe() failed.  Set exit value to WRITE_BROK to let
430 		 * parent know what happened
431 		 */
432 		clear_timeout();
433 		exit(WRITE_BROK);
434 	}
435 
436 	/*
437 	 * if we get to this point, all signals have been held and the
438 	 * timer has expired.  Now what we want to do is release each
439 	 * signal and see if we catch it.  If we catch all signals,
440 	 * sigrelse passed, else it failed.
441 	 */
442 
443 	phase = 2;		/* let handler know we are now expecting signals */
444 
445 #if DEBUG > 0
446 	printf("child: PHASE II\n");
447 #endif
448 
449 	/* assume success and overwrite exit_val if an error occurs */
450 	exit_val = EXIT_OK;
451 
452 #if DEBUG > 0
453 	printf("child: pid=%d waiting for parent's ready...\n", getpid());
454 #endif
455 
456 	/*
457 	 * wait for parent to tell us that sigals were all sent
458 	 */
459 
460 	/* wait for "ready" message from parent */
461 	if ((str = read_pipe(pipe_fd2[0])) == NULL) {
462 		/* read_pipe() failed. */
463 		printf(" child: read_pipe failed\n");
464 		exit(TBROK);
465 	}
466 
467 	if (strcmp(str, READY) != 0) {
468 		/* parent/pipe problem */
469 		printf("child: didn't proper ready message\n");
470 		exit(TBROK);
471 	}
472 
473 	for (sig = 1; sig < NUMSIGS; sig++) {
474 		if (choose_sig(sig)) {
475 
476 			/* all set up, release and catch a signal */
477 
478 			sig_caught = FALSE;	/* handler sets it to TRUE when caught */
479 #if DEBUG > 1
480 			printf("child: releasing sig %d...\n", sig);
481 #endif
482 			if ((rv = sigrelse(sig)) != 0) {
483 				/* THEY say sigrelse ALWAYS returns 0 */
484 				(void)sprintf(note,
485 					      "sigrelse did not return 0. rv:%d",
486 					      rv);
487 				exit_val = TBROK;
488 				break;
489 			}
490 
491 			/* give signal handler some time to process signal */
492 			wait_a_while();
493 		}
494 
495 	}			/* endfor */
496 
497 	/*
498 	 * If we are error free so far...
499 	 * check the sig_array array for one occurence of
500 	 * each of the catchable signals.  If this is true,
501 	 * then PASS, otherwise FAIL.
502 	 */
503 
504 	if (exit_val == EXIT_OK) {
505 		(void)memcpy(note, (char *)sig_array,
506                             sizeof(note) < sizeof(sig_array) ?
507                             sizeof(note) : sizeof(sig_array));
508 	}
509 
510 	/* send note to parent and exit */
511 	if (write_pipe(pipe_fd[1], note) < 0) {
512 		/*
513 		 * write_pipe() failed.  Set exit value to WRITE_BROK to let
514 		 * parent know what happened
515 		 */
516 		exit(WRITE_BROK);
517 	}
518 
519 	exit(exit_val);
520 
521 }				/* end of child */
522 
523 /*****************************************************************************
524  *  setup_sigs() : set child up to catch all signals.  If there is
525  *       trouble, write message in mesg and return -1, else return 0.
526  *       The signal handler has two functions depending on which phase
527  *       of the test we are in.  The first section is executed after the
528  *       signals have been held (should not ever be used).  The second
529  *       section is executed after the signals have been released (should
530  *       be executed for each signal).
531  ****************************************************************************/
setup_sigs(void)532 static int setup_sigs(void)
533 {
534 	int sig;
535 
536 	/* set up signal handler routine */
537 	for (sig = 1; sig < NUMSIGS; sig++) {
538 		if (choose_sig(sig)) {
539 			if (signal(sig, handler) == SIG_ERR) {
540 				/* set up mesg to send back to parent */
541 				(void)sprintf(mesg,
542 					      "signal() failed for signal %d. error:%d %s.",
543 					      sig, errno, strerror(errno));
544 				return (-1);
545 			}
546 		}
547 	}
548 	return 0;
549 
550 }				/* end of setup_sigs  */
551 
552 /*****************************************************************************
553  *  handler() : child's interrupt handler for all signals.  The phase variable
554  *      is set in the child process indicating what action is to be taken.
555  *    The phase 1 section will be run if the child process catches a signal
556  *      after the signal has been held resulting in a test item BROK.
557  *      The parent detects this situation by a child exit value of SIG_CAUGHT.
558  *    The phase 2 section will be run if the child process catches a
559  *      signal after the signal has been released.  All signals must be
560  *      caught in order for a PASS.
561  ****************************************************************************/
handler(int sig)562 static void handler(int sig)
563 {
564 	static int s = 0;	/* semaphore so that we don't handle 2 */
565 	/* sigs at once */
566 #if DEBUG > 1
567 	printf("child: handler phase%d: caught signal %d.\n", phase, sig);
568 #endif
569 
570 	if (phase == 1) {
571 		/* exit the child process with a value of -1 */
572 		exit(SIG_CAUGHT);
573 
574 	} else {
575 		/* phase 2 (error if s gets incremented twice) */
576 		++s;
577 
578 		if (s > 1) {
579 			exit(HANDLE_ERR);
580 		}
581 
582 		/* increment the array element for this signal */
583 		++sig_array[sig];
584 		sig_caught = TRUE;	/* flag for wait_a_while () */
585 		--s;
586 	}
587 
588 	return;
589 
590 }				/* end of handler */
591 
592 /*****************************************************************************
593  *  read_pipe() : read data from pipe and return in buf.  If an error occurs
594  *      put message in mesg and return NULL.  Note: this routine sets a
595  *      timeout signal in case the pipe is blocked.
596  ****************************************************************************/
read_pipe(int fd)597 static char *read_pipe(int fd)
598 {
599 	static char buf[MAXMESG];	/* buffer for pipe read */
600 	int ret;
601 
602 #if DEBUG > 0
603 	printf("read_pipe: pid=%d waiting...\n", getpid());
604 #endif
605 
606 	/* set timeout alarm in case the pipe is blocked */
607 	if (set_timeout() < 0) {
608 		/* an error occured, message in mesg */
609 		return NULL;
610 	}
611 
612 	ret = -1;
613 	while (ret == -1) {	/* while empty reads */
614 		if ((ret = read(fd, buf, MAXMESG)) == 0) {
615 			(void)sprintf(mesg, "read() pipe failed. error:%d %s.",
616 				      errno, strerror(errno));
617 
618 			clear_timeout();
619 			return NULL;
620 		}
621 	}
622 	clear_timeout();
623 
624 #if DEBUG > 0
625 	printf("read_pipe: pid=%d received: %s.\n", getpid(), buf);
626 #endif
627 	return (buf);
628 
629 }				/* end of read_pipe */
630 
631 /*****************************************************************************
632  *  write_pipe(msg) : write msg to pipe.  If it fails, put message in
633  *       mesg and return -1, else return 0.
634  ****************************************************************************/
write_pipe(int fd,char * msg)635 static int write_pipe(int fd, char *msg)
636 {
637 
638 #if DEBUG > 0
639 	printf("write_pipe: pid=%d, sending %s.\n", getpid(), msg);
640 #endif
641 
642 	if (write(fd, msg, MAXMESG) < 0) {
643 		(void)sprintf(mesg, "write() pipe failed. error:%d %s.",
644 			      errno, strerror(errno));
645 
646 		return (-1);
647 	}
648 	return 0;
649 
650 }				/* end of write_pipe */
651 
652 /*****************************************************************************
653  *  set_timeout() : set alarm to signal process after the period of time
654  *       indicated by TIMEOUT.  If the signal occurs, the routine timeout()
655  *       will be executed.  If all goes ok, return 0, else load message
656  *       into mesg and return -1.
657  ****************************************************************************/
set_timeout(void)658 static int set_timeout(void)
659 {
660 	if (signal(SIGALRM, timeout) == SIG_ERR) {
661 		(void)sprintf(mesg,
662 			      "signal() failed for signal %d. error:%d %s.",
663 			      SIGALRM, errno, strerror(errno));
664 		return (-1);
665 	}
666 
667 	(void)alarm(TIMEOUT);
668 	return 0;
669 
670 }				/* end of set_timeout */
671 
672 /*****************************************************************************
673  *  clear_timeout() : turn off the alarm so that SIGALRM will not get sent.
674  ****************************************************************************/
clear_timeout(void)675 static void clear_timeout(void)
676 {
677 	(void)alarm(0);
678 
679 }				/* end of clear_timeout */
680 
681 /*****************************************************************************
682  *  timeout() : this routine is executed when the SIGALRM signal is
683  *      caught.  It does nothing but return - the read() on the pipe
684  *      will fail.
685  ****************************************************************************/
timeout(int sig)686 static void timeout(int sig)
687 {
688 #if DEBUG > 0
689 	printf("timeout: pid=%d sigalrm caught.\n", getpid());
690 #endif
691 }
692 
693 /*****************************************************************************
694  *  wait_a_while () : wait a while before returning.
695  ****************************************************************************/
wait_a_while(void)696 static void wait_a_while(void)
697 {
698 	long btime;
699 
700 	btime = time(NULL);
701 	while (time(NULL) - btime < TIMEOUT) {
702 		if (sig_caught == TRUE)
703 			break;
704 	}
705 }				/* end of wait_a_while */
706 
getout(void)707 static void getout(void)
708 {
709 	if (pid > 0 && kill(pid, SIGKILL) < 0)
710 		tst_resm(TWARN, "kill(%d, SIGKILL) failed", pid);
711 	cleanup();
712 
713 }				/* end of getout */
714 
715 #ifdef VAX
sighold(int signo)716 static int sighold(int signo)
717 {
718 	return 0;
719 }
720 
sigrelse(signo)721 static int sigrelse(signo)
722 int signo;
723 {
724 	return 0;
725 }
726 #endif
727 
choose_sig(int sig)728 int choose_sig(int sig)
729 {
730 	switch (sig) {
731 
732 	case SIGKILL:
733 	case SIGSTOP:
734 	case SIGTSTP:
735 	case SIGCONT:
736 	case SIGALRM:
737 	case SIGCANCEL:
738 	case SIGTIMER:
739 #ifdef SIGNOBDM
740 	case SIGNOBDM:
741 #endif
742 #ifdef SIGTTIN
743 	case SIGTTIN:
744 #endif
745 #ifdef SIGTTOU
746 	case SIGTTOU:
747 #endif
748 #ifdef  SIGPTINTR
749 	case SIGPTINTR:
750 #endif
751 #ifdef  SIGSWAP
752 	case SIGSWAP:
753 #endif
754 		return 0;
755 
756 	}
757 
758 	return 1;
759 
760 }
761 
setup(void)762 void setup(void)
763 {
764 
765 	tst_sig(FORK, DEF_HANDLER, cleanup);
766 
767 	TEST_PAUSE;
768 
769 	tst_tmpdir();
770 
771 	/* set up pipe for parent/child communications */
772 	SAFE_PIPE(cleanup, pipe_fd);
773 
774 	/*
775 	 * Cause the read to return 0 once EOF is encountered and the
776 	 * read to return -1 if pipe is empty.
777 	 */
778 	if (fcntl(pipe_fd[0], F_SETFL, O_NONBLOCK) == -1)
779 		tst_brkm(TBROK | TERRNO, cleanup,
780 			 "fcntl(Fds[0], F_SETFL, O_NONBLOCK) failed");
781 
782 	/* set up pipe for parent/child communications */
783 	SAFE_PIPE(cleanup, pipe_fd2);
784 
785 	/*
786 	 * Cause the read to return 0 once EOF is encountered and the
787 	 * read to return -1 if pipe is empty.
788 	 */
789 	if (fcntl(pipe_fd2[0], F_SETFL, O_NONBLOCK) == -1)
790 		tst_brkm(TBROK | TERRNO, cleanup,
791 			 "fcntl(Fds[0], F_SETFL, O_NONBLOCK) failed");
792 }
793 
cleanup(void)794 void cleanup(void)
795 {
796 	tst_rmdir();
797 
798 }
799