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. */
115extern int sighold(int __sig);
116extern int sigrelse(int __sig);
117#endif
118
119/* Needed for NPTL */
120#define SIGCANCEL 32
121#define SIGTIMER 33
122
123void setup(void);
124void cleanup(void);
125static void parent(void);
126static void child(void);
127static void timeout(int sig);
128static int setup_sigs(void);
129static void handler(int sig);
130static void wait_a_while(void);
131static char *read_pipe(int fd);
132static int write_pipe(int fd, char *msg);
133static int set_timeout(void);
134static void clear_timeout(void);
135static void getout(void);
136int 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
160int TST_TOTAL = 1;		/* number of test items */
161
162char *TCID = "sigrelse01";	/* test case identifier */
163static char mesg[MAXMESG];	/* message buffer for tst_res */
164static int pid;			/* process id of child */
165static int pipe_fd[2];		/* file descriptors for pipe parent read */
166static int pipe_fd2[2];		/* file descriptors for pipe child read */
167static int phase;		/* flag for phase1 or phase2 of */
168				/* signal handler */
169static 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() */
178static int sig_array[NUMSIGS];
179
180/***********************************************************************
181 *   M A I N
182 ***********************************************************************/
183int 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 ***************************************************************************/
240static 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 ***************************************************************************/
380static 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 ****************************************************************************/
532static 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 ****************************************************************************/
562static 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 ****************************************************************************/
597static 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 ****************************************************************************/
635static 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 ****************************************************************************/
658static 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 ****************************************************************************/
675static 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 ****************************************************************************/
686static 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 ****************************************************************************/
696static 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
707static 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
716static int sighold(int signo)
717{
718	return 0;
719}
720
721static int sigrelse(signo)
722int signo;
723{
724	return 0;
725}
726#endif
727
728int 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
762void 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
794void cleanup(void)
795{
796	tst_rmdir();
797
798}
799