blob: b72349c5435290956da69f233e7371ca7886f292 [file] [log] [blame]
plars865695b2001-08-27 22:15:12 +00001/*
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
Wanlong Gaofed96412012-10-24 10:10:29 +080020 * with this program; if not, write the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
plars865695b2001-08-27 22:15:12 +000022 *
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 */
vapier64a55442009-08-28 13:53:04 +000033/* $Id: sighold02.c,v 1.11 2009/08/28 13:53:04 vapier Exp $ */
plars865695b2001-08-27 22:15:12 +000034/*****************************************************************************
35 * OS Test - Silicon Graphics, Inc. Eagan, Minnesota
subrata_modak4bb656a2009-02-26 12:02:09 +000036 *
plars865695b2001-08-27 22:15:12 +000037 * TEST IDENTIFIER : sighold02 Holding all signals.
subrata_modak4bb656a2009-02-26 12:02:09 +000038 *
plars865695b2001-08-27 22:15:12 +000039 * PARENT DOCUMENT : sghtds01 sighold system call (CRAY X-MP and CRAY-1 only)
subrata_modak4bb656a2009-02-26 12:02:09 +000040 *
plars865695b2001-08-27 22:15:12 +000041 * AUTHOR : Bob Clark
subrata_modak4bb656a2009-02-26 12:02:09 +000042 *
plars865695b2001-08-27 22:15:12 +000043 * CO-PILOT : Barrie Kletscher
subrata_modak4bb656a2009-02-26 12:02:09 +000044 *
plars865695b2001-08-27 22:15:12 +000045 * DATE STARTED : 9/26/86
subrata_modak4bb656a2009-02-26 12:02:09 +000046 *
plars865695b2001-08-27 22:15:12 +000047 * TEST ITEMS
subrata_modak4bb656a2009-02-26 12:02:09 +000048 *
subrata_modak56207ce2009-03-23 13:35:39 +000049 * 1. sighold action to turn off the receipt of all signals was done
plars865695b2001-08-27 22:15:12 +000050 * without error.
subrata_modak56207ce2009-03-23 13:35:39 +000051 * 2. After signals were held, and sent, no signals were trapped.
subrata_modak4bb656a2009-02-26 12:02:09 +000052 *
plars865695b2001-08-27 22:15:12 +000053 * SPECIAL PROCEDURAL REQUIRMENTS
subrata_modak4bb656a2009-02-26 12:02:09 +000054 *
subrata_modak56207ce2009-03-23 13:35:39 +000055 * The program must be linked with tst_res.o and parse_opts.o.
subrata_modak4bb656a2009-02-26 12:02:09 +000056 *
plars865695b2001-08-27 22:15:12 +000057 * DETAILED DESCRIPTION
subrata_modak4bb656a2009-02-26 12:02:09 +000058 *
subrata_modak56207ce2009-03-23 13:35:39 +000059 * set up pipe for parent/child communications
60 * fork off a child process
subrata_modak4bb656a2009-02-26 12:02:09 +000061 *
subrata_modak56207ce2009-03-23 13:35:39 +000062 * PARENT:
63 * set up for unexpected signals
64 * wait for child to send ready message over pipe
plars865695b2001-08-27 22:15:12 +000065 * issue a result for sighold
subrata_modak56207ce2009-03-23 13:35:39 +000066 * send all catchable signals to child
plars865695b2001-08-27 22:15:12 +000067 * write to pipe, tell child all signals sent
68 * read pipe to get result from child
subrata_modak56207ce2009-03-23 13:35:39 +000069 * wait for child to terminate
subrata_modak4bb656a2009-02-26 12:02:09 +000070 *
subrata_modak56207ce2009-03-23 13:35:39 +000071 * CHILD:
72 * set up to catch all signals
73 * hold signals with sighold()
74 * send parent sighold results via pipe
75 * wait for signals to arrive while reading pipe
plars865695b2001-08-27 22:15:12 +000076 * write to pipe telling parent which signals were received if any.
subrata_modak4bb656a2009-02-26 12:02:09 +000077 *
plars865695b2001-08-27 22:15:12 +000078 ***************************************************************************/
79
80#include <errno.h>
81#include <signal.h>
82#include <string.h>
83#include <fcntl.h>
84#include <stdlib.h>
85#include <sys/types.h>
86#include <sys/wait.h>
87#include "test.h"
plars865695b2001-08-27 22:15:12 +000088
robbiew90e8baf2003-09-25 15:44:20 +000089/* Needed for NPTL */
robbieweeea7f02003-04-29 16:44:41 +000090#define SIGCANCEL 32
91#define SIGTIMER 33
robbieweeea7f02003-04-29 16:44:41 +000092
plars865695b2001-08-27 22:15:12 +000093#ifdef _CRAYT3E
94#define CRAYT3E 1
95#else
96#define CRAYT3E 0
97#endif
98
99#ifdef sgi
100#define SGI 1
101#else
102#define SGI 0
103#endif
104
105#ifdef __linux__
106/* glibc2.2 definition needs -D_XOPEN_SOURCE, which breaks other things. */
subrata_modak56207ce2009-03-23 13:35:39 +0000107extern int sighold(int __sig);
plars865695b2001-08-27 22:15:12 +0000108#endif
109
110/* ensure NUMSIGS is defined */
111#ifndef NUMSIGS
112#define NUMSIGS NSIG
113#endif
114
subrata_modak56207ce2009-03-23 13:35:39 +0000115#define CHILD_EXIT(VAL) ((VAL >> 8) & 0377) /* exit value of child process */
plars865695b2001-08-27 22:15:12 +0000116
117#define MAXMESG 150 /* the size of the message string */
118
119#define TIMEOUT 2 /* time used in the alarm calls as backup */
120
Cyril Hrubisfdce7d52013-04-04 18:35:48 +0200121char *TCID = "sighold02";
122int TST_TOTAL = 2;
plars865695b2001-08-27 22:15:12 +0000123
plars865695b2001-08-27 22:15:12 +0000124char signals_received[MAXMESG];
125int pid; /* process id of child */
126int Fds1[2]; /* file descriptors for pipe - child 2 parent */
127int Fds2[2]; /* file descriptors for pipe - parent 2 child */
128
129#define PARENTSREADFD Fds1[0]
130#define CHILDSWRITEFD Fds1[1]
131
132#define CHILDSREADFD Fds2[0]
133#define PARENTSWRITEFD Fds2[1]
134
plars865695b2001-08-27 22:15:12 +0000135struct pipe_packet {
subrata_modak56207ce2009-03-23 13:35:39 +0000136 int result;
137 char mesg[MAXMESG];
138 struct tblock rtimes;
plars865695b2001-08-27 22:15:12 +0000139} p_p;
140
Mike Frysingerc57fba52014-04-09 18:56:30 -0400141void do_child(void);
142void setup(void);
143void cleanup(void);
144static void getout(void);
Mike Frysingere61ddba2014-04-09 23:24:32 -0400145static void timeout(int sig);
Garrett Cooper93cbfd62010-08-16 23:39:01 -0700146static int read_pipe(int fd);
147static int write_pipe(int fd);
vapier64a55442009-08-28 13:53:04 +0000148static int setup_sigs(char *mesg);
Mike Frysingerc57fba52014-04-09 18:56:30 -0400149static void handle_sigs(int sig);
vapier64a55442009-08-28 13:53:04 +0000150static int set_timeout(char *mesg);
Mike Frysingerc57fba52014-04-09 18:56:30 -0400151static void clear_timeout(void);
plars865695b2001-08-27 22:15:12 +0000152
153int Timeout = 0;
154
155/***********************************************************************
156 * MAIN
157 ***********************************************************************/
subrata_modak56207ce2009-03-23 13:35:39 +0000158int main(int ac, char **av)
plars865695b2001-08-27 22:15:12 +0000159{
subrata_modak56207ce2009-03-23 13:35:39 +0000160 int term_stat; /* child return status */
161 int sig; /* current signal */
Cyril Hrubis89af32a2012-10-24 16:39:11 +0200162 int lc;
Cyril Hrubis0b9589f2014-05-27 17:40:33 +0200163 const char *msg;
plars865695b2001-08-27 22:15:12 +0000164
165 /***************************************************************
166 * parse standard options, and exit if there is an error
167 ***************************************************************/
Garrett Cooper45e285d2010-11-22 12:19:25 -0800168 if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL) {
subrata_modak56207ce2009-03-23 13:35:39 +0000169 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
Garrett Cooper2c282152010-12-16 00:55:50 -0800170
subrata_modak56207ce2009-03-23 13:35:39 +0000171 }
robbiewd34d5812005-07-11 22:28:09 +0000172#ifdef UCLINUX
subrata_modak56207ce2009-03-23 13:35:39 +0000173 maybe_run_child(&do_child, "dd", &CHILDSWRITEFD, &CHILDSREADFD);
robbiewd34d5812005-07-11 22:28:09 +0000174#endif
175
plars865695b2001-08-27 22:15:12 +0000176 /***************************************************************
177 * perform global setup for test
178 ***************************************************************/
subrata_modak56207ce2009-03-23 13:35:39 +0000179 setup();
plars865695b2001-08-27 22:15:12 +0000180
181 /***************************************************************
182 * check looping state if -c option given
183 ***************************************************************/
subrata_modak56207ce2009-03-23 13:35:39 +0000184 for (lc = 0; TEST_LOOPING(lc); lc++) {
plars865695b2001-08-27 22:15:12 +0000185
Caspar Zhangd59a6592013-03-07 14:59:12 +0800186 tst_count = 0;
plars865695b2001-08-27 22:15:12 +0000187
subrata_modak56207ce2009-03-23 13:35:39 +0000188 signals_received[0] = '\0';
plars865695b2001-08-27 22:15:12 +0000189
subrata_modak56207ce2009-03-23 13:35:39 +0000190 /*
191 * fork off a child process
192 */
193 if ((pid = FORK_OR_VFORK()) < 0) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800194 tst_brkm(TBROK | TERRNO, cleanup, "fork() failed");
plars865695b2001-08-27 22:15:12 +0000195
subrata_modak56207ce2009-03-23 13:35:39 +0000196 } else if (pid > 0) {
plars865695b2001-08-27 22:15:12 +0000197
subrata_modak56207ce2009-03-23 13:35:39 +0000198 /* PARENT PROCESS - first set up for unexpected signals */
199 tst_sig(FORK, DEF_HANDLER, getout);
plars865695b2001-08-27 22:15:12 +0000200
subrata_modak56207ce2009-03-23 13:35:39 +0000201 /* wait for "ready" message from child */
Garrett Cooper93cbfd62010-08-16 23:39:01 -0700202 if (read_pipe(PARENTSREADFD) != 0) {
subrata_modak56207ce2009-03-23 13:35:39 +0000203 /* read_pipe() failed. */
vapier64a55442009-08-28 13:53:04 +0000204 tst_brkm(TBROK, getout, "%s", p_p.mesg);
subrata_modak56207ce2009-03-23 13:35:39 +0000205 }
plars865695b2001-08-27 22:15:12 +0000206
subrata_modak56207ce2009-03-23 13:35:39 +0000207 if (STD_TIMING_ON) {
208 /*
209 * Insure a running total for multiple loop iterations
210 */
211 tblock.tb_total += p_p.rtimes.tb_total;
212 if (p_p.rtimes.tb_min < tblock.tb_min)
213 tblock.tb_min = p_p.rtimes.tb_min;
214 if (p_p.rtimes.tb_max > tblock.tb_max)
215 tblock.tb_max = p_p.rtimes.tb_max;
216 tblock.tb_count += p_p.rtimes.tb_count;
217 }
plars865695b2001-08-27 22:15:12 +0000218
subrata_modak56207ce2009-03-23 13:35:39 +0000219 /* check for ready message */
220 if (p_p.result != TPASS) {
221 /* child setup did not go well */
vapier64a55442009-08-28 13:53:04 +0000222 tst_brkm(p_p.result, getout, "%s", p_p.mesg);
Cyril Hrubise38b9612014-06-02 17:20:57 +0200223 } else {
vapier64a55442009-08-28 13:53:04 +0000224 tst_resm(p_p.result, "%s", p_p.mesg);
subrata_modak56207ce2009-03-23 13:35:39 +0000225 }
plars865695b2001-08-27 22:15:12 +0000226
subrata_modak56207ce2009-03-23 13:35:39 +0000227 /*
228 * send signals to child and see if it holds them
229 */
plars865695b2001-08-27 22:15:12 +0000230
subrata_modak56207ce2009-03-23 13:35:39 +0000231 for (sig = 1; sig < NUMSIGS; sig++) {
232 if ((sig == 41) && !CRAYT3E && !SGI) {
233 sig = 42; /* skip over SIGPEFAILURE for non-CRAYT3E systems */
234 }
235 if ((sig != SIGCLD) && (sig != SIGKILL) &&
236 (sig != SIGALRM) && (sig != SIGSTOP)
237 && (sig != SIGCANCEL)
238 && (sig != SIGTIMER)
plars865695b2001-08-27 22:15:12 +0000239#ifdef SIGRECOVERY
subrata_modak56207ce2009-03-23 13:35:39 +0000240 && (sig != SIGRECOVERY)
plars865695b2001-08-27 22:15:12 +0000241#endif
242#ifdef SIGRESTART
subrata_modak56207ce2009-03-23 13:35:39 +0000243 && (sig != SIGRESTART)
plars865695b2001-08-27 22:15:12 +0000244#endif
245#ifdef SIGNOBDM
subrata_modak56207ce2009-03-23 13:35:39 +0000246 && (sig != SIGNOBDM)
plars865695b2001-08-27 22:15:12 +0000247#endif
248#ifdef SIGPTINTR
subrata_modak56207ce2009-03-23 13:35:39 +0000249 && (sig != SIGPTINTR)
plars865695b2001-08-27 22:15:12 +0000250#endif
subrata_modak56207ce2009-03-23 13:35:39 +0000251 ) {
252 if (kill(pid, sig) < 0) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800253 tst_brkm(TBROK | TERRNO, NULL,
254 "kill(%d, %d) failed",
255 pid, sig);
subrata_modak56207ce2009-03-23 13:35:39 +0000256 getout();
257 }
258 }
259 }
plars865695b2001-08-27 22:15:12 +0000260
subrata_modak56207ce2009-03-23 13:35:39 +0000261 /*
262 * Tell child that all signals were sent.
263 */
264 p_p.result = TPASS;
265 strcpy(p_p.mesg, "All signals were sent");
vapier64a55442009-08-28 13:53:04 +0000266 write_pipe(PARENTSWRITEFD);
plars865695b2001-08-27 22:15:12 +0000267
subrata_modak56207ce2009-03-23 13:35:39 +0000268 /*
269 * Get childs reply about received signals.
270 */
plars865695b2001-08-27 22:15:12 +0000271
Garrett Cooper93cbfd62010-08-16 23:39:01 -0700272 if (read_pipe(PARENTSREADFD) < 0) {
vapier64a55442009-08-28 13:53:04 +0000273 tst_brkm(TBROK, getout, "%s", p_p.mesg);
subrata_modak56207ce2009-03-23 13:35:39 +0000274 }
plars865695b2001-08-27 22:15:12 +0000275
Cyril Hrubise38b9612014-06-02 17:20:57 +0200276 tst_resm(p_p.result, "%s", p_p.mesg);
plars865695b2001-08-27 22:15:12 +0000277
subrata_modak56207ce2009-03-23 13:35:39 +0000278 /*
279 * wait for child
280 */
281 if (wait(&term_stat) < 0) {
vapier64a55442009-08-28 13:53:04 +0000282 tst_brkm(TBROK, getout, "wait() failed");
subrata_modak56207ce2009-03-23 13:35:39 +0000283 }
plars865695b2001-08-27 22:15:12 +0000284
subrata_modak56207ce2009-03-23 13:35:39 +0000285 } else {
plars865695b2001-08-27 22:15:12 +0000286
subrata_modak56207ce2009-03-23 13:35:39 +0000287 /*
288 * CHILD PROCESS - set up to catch signals.
289 */
plars865695b2001-08-27 22:15:12 +0000290
robbiewd34d5812005-07-11 22:28:09 +0000291#ifdef UCLINUX
subrata_modak56207ce2009-03-23 13:35:39 +0000292 if (self_exec(av[0], "dd", CHILDSWRITEFD, CHILDSREADFD)
293 < 0) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800294 tst_brkm(TBROK | TERRNO, cleanup,
295 "self_exec() failed");
subrata_modak56207ce2009-03-23 13:35:39 +0000296 }
robbiewd34d5812005-07-11 22:28:09 +0000297#else
subrata_modak56207ce2009-03-23 13:35:39 +0000298 do_child();
plars865695b2001-08-27 22:15:12 +0000299#endif
subrata_modak56207ce2009-03-23 13:35:39 +0000300 }
plars865695b2001-08-27 22:15:12 +0000301 }
subrata_modak56207ce2009-03-23 13:35:39 +0000302 cleanup();
Garrett Cooper1e6f5a62010-12-19 09:58:10 -0800303 tst_exit();
plars865695b2001-08-27 22:15:12 +0000304
plars865695b2001-08-27 22:15:12 +0000305}
306
307/*****************************************************************************
robbiewd34d5812005-07-11 22:28:09 +0000308 * do_child()
309 ****************************************************************************/
310
Mike Frysingerc57fba52014-04-09 18:56:30 -0400311void do_child(void)
robbiewd34d5812005-07-11 22:28:09 +0000312{
subrata_modak56207ce2009-03-23 13:35:39 +0000313 int rv; /* function return value */
314 int sig; /* current signal */
315 int cnt;
robbiewd34d5812005-07-11 22:28:09 +0000316
robbiewd34d5812005-07-11 22:28:09 +0000317 p_p.result = TPASS;
robbiewd34d5812005-07-11 22:28:09 +0000318
subrata_modak56207ce2009-03-23 13:35:39 +0000319 /* set up signal handlers for the signals */
vapier64a55442009-08-28 13:53:04 +0000320 if (setup_sigs(p_p.mesg) < 0) {
subrata_modak56207ce2009-03-23 13:35:39 +0000321 p_p.result = TBROK;
subrata_modak56207ce2009-03-23 13:35:39 +0000322
323 } else {
324 /* all set up to catch signals, now hold them */
325
326 for (cnt = 0, sig = 1; sig < NUMSIGS; sig++) {
327 if ((sig == 41) && !CRAYT3E && !SGI) {
328 sig = 42; /* skip over SIGPEFAILURE for non-CRAYT3E systems */
329 }
330 if ((sig != SIGCLD) && (sig != SIGKILL) &&
331 (sig != SIGALRM) && (sig != SIGSTOP)
332#ifdef SIGNOBDM
333 && (sig != SIGNOBDM)
334#endif
335 && (sig != SIGCANCEL) && (sig != SIGTIMER)
336 ) {
337
338 cnt++;
339 TEST(sighold(sig));
340 rv = TEST_RETURN;
341 if (rv != 0) {
342 /* THEY say sighold ALWAYS returns 0 */
343 p_p.result = TFAIL;
344 (void)sprintf(p_p.mesg,
345 "sighold(%d) failed, rv:%d, errno:%d",
346 sig, rv, errno);
347 break;
348 }
349 }
350 }
351 if (STD_TIMING_ON) {
352 p_p.rtimes = tblock;
353 }
354 if (p_p.result == TPASS) {
355 sprintf(p_p.mesg,
356 "Sighold called without error for %d of %d signals",
357 cnt, NUMSIGS - 1);
358 }
359 }
360
361 /*
362 * write to parent (if not READY, parent will BROK) and
363 * wait for parent to send signals. The timeout clock is set so
364 * that we will not wait forever - if sighold() did its job, we
365 * will not receive the signals. If sighold() blew it we will
366 * catch a signal and the interrupt handler will exit(1).
367 */
368#if debug
369 printf("child: %d writing to parent fd:%d\n", getpid(), CHILDSWRITEFD);
370#endif
371 if (write_pipe(CHILDSWRITEFD) < 0 || p_p.result != TPASS) {
372 exit(2);
373 }
374
375 /*
376 * Read pipe from parent, that will tell us that all signals were sent
377 */
Garrett Cooper93cbfd62010-08-16 23:39:01 -0700378 if (read_pipe(CHILDSREADFD) != 0) {
subrata_modak56207ce2009-03-23 13:35:39 +0000379 p_p.result = TBROK;
vapier64a55442009-08-28 13:53:04 +0000380 strcpy(p_p.mesg, "read() pipe failed");
subrata_modak56207ce2009-03-23 13:35:39 +0000381 } else if (signals_received[0] == '\0') {
382 p_p.result = TPASS;
383 strcpy(p_p.mesg,
384 "No signals trapped after being sent by parent");
385 } else {
386 p_p.result = TFAIL;
387 sprintf(p_p.mesg, "signals received: %s", signals_received);
388 }
389
390 if (write_pipe(CHILDSWRITEFD) < 0) {
391 exit(2);
392 }
393
394 /* exit back to parent */
395 if (p_p.result == TPASS)
396 exit(0);
397 else
398 exit(1);
robbiewd34d5812005-07-11 22:28:09 +0000399}
400
401/*****************************************************************************
plars865695b2001-08-27 22:15:12 +0000402 * read_pipe() : read data from pipe and return in buf. If an error occurs
subrata_modak4bb656a2009-02-26 12:02:09 +0000403 * put message in mesg and return NULL. Note: this routine sets a
plars865695b2001-08-27 22:15:12 +0000404 * timeout signal in case the pipe is blocked.
405 ****************************************************************************/
406
Mike Frysingerc57fba52014-04-09 18:56:30 -0400407int read_pipe(int fd)
plars865695b2001-08-27 22:15:12 +0000408{
subrata_modak56207ce2009-03-23 13:35:39 +0000409 int ret = -1;
plars865695b2001-08-27 22:15:12 +0000410
411#ifdef debug
subrata_modak56207ce2009-03-23 13:35:39 +0000412 printf("read_pipe: %d entering, fd = %d...\n", getpid(), fd);
subrata_modak4bb656a2009-02-26 12:02:09 +0000413#endif
plars865695b2001-08-27 22:15:12 +0000414
subrata_modak56207ce2009-03-23 13:35:39 +0000415 /* set timeout alarm in case the pipe is blocked */
vapier64a55442009-08-28 13:53:04 +0000416 if (set_timeout(p_p.mesg) < 0) {
subrata_modak56207ce2009-03-23 13:35:39 +0000417 /* an error occured, message in mesg */
418 return -1;
419 }
plars865695b2001-08-27 22:15:12 +0000420
subrata_modak56207ce2009-03-23 13:35:39 +0000421 ret = read(fd, (char *)&p_p, sizeof(struct pipe_packet));
plars865695b2001-08-27 22:15:12 +0000422
423#ifdef debug
subrata_modak56207ce2009-03-23 13:35:39 +0000424 printf("read_pipe: %d read() completed ret=%d\n", getpid(), ret);
subrata_modak4bb656a2009-02-26 12:02:09 +0000425#endif
plars865695b2001-08-27 22:15:12 +0000426
subrata_modak56207ce2009-03-23 13:35:39 +0000427 clear_timeout();
plars865695b2001-08-27 22:15:12 +0000428
subrata_modak56207ce2009-03-23 13:35:39 +0000429 if (Timeout) {
430 (void)sprintf(p_p.mesg,
431 "read() pipe failed -timed out after %d seconds.",
432 TIMEOUT);
433 return -1;
434 }
plars865695b2001-08-27 22:15:12 +0000435#ifdef debug
subrata_modak56207ce2009-03-23 13:35:39 +0000436 printf("read_pipe: received %s.\n", p_p.mesg);
subrata_modak4bb656a2009-02-26 12:02:09 +0000437#endif
plars865695b2001-08-27 22:15:12 +0000438
subrata_modak56207ce2009-03-23 13:35:39 +0000439 return 0;
plars865695b2001-08-27 22:15:12 +0000440}
441
plars865695b2001-08-27 22:15:12 +0000442/*****************************************************************************
subrata_modak4bb656a2009-02-26 12:02:09 +0000443 * write_pipe(msg) : write p_p to pipe. If it fails, put message in
plars865695b2001-08-27 22:15:12 +0000444 * mesg and return -1, else return 0.
445 ****************************************************************************/
446
Mike Frysingerc57fba52014-04-09 18:56:30 -0400447static int write_pipe(int fd)
plars865695b2001-08-27 22:15:12 +0000448{
449#ifdef debug
subrata_modak56207ce2009-03-23 13:35:39 +0000450 printf("write_pipe: sending result:%d, mesg:%s.\n", p_p.result,
451 p_p.mesg);
plars865695b2001-08-27 22:15:12 +0000452#endif
subrata_modak56207ce2009-03-23 13:35:39 +0000453 if (write(fd, (char *)&p_p, sizeof(struct pipe_packet)) < 0) {
vapier64a55442009-08-28 13:53:04 +0000454 if (pid)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800455 tst_brkm(TBROK | TERRNO, getout, "write() pipe failed");
subrata_modak56207ce2009-03-23 13:35:39 +0000456 return -1;
457 }
plars865695b2001-08-27 22:15:12 +0000458#ifdef debug
subrata_modak56207ce2009-03-23 13:35:39 +0000459 printf("write_pipe: %d complete successfully, fd:%d.\n", getpid(), fd);
plars865695b2001-08-27 22:15:12 +0000460#endif
subrata_modak56207ce2009-03-23 13:35:39 +0000461 return 0;
plars865695b2001-08-27 22:15:12 +0000462}
463
464/*****************************************************************************
465 * set_timeout() : set alarm to signal process after the period of time
466 * indicated by TIMEOUT. If the signal occurs, the routine timeout()
467 * will be executed. If all goes ok, return 0, else load message
468 * into mesg and return -1.
469 ****************************************************************************/
470
vapier64a55442009-08-28 13:53:04 +0000471static int set_timeout(char *mesg)
plars865695b2001-08-27 22:15:12 +0000472{
subrata_modak56207ce2009-03-23 13:35:39 +0000473 if (signal(SIGALRM, timeout) == SIG_ERR) {
474 (void)sprintf(mesg,
475 "signal() failed for signal %d. error:%d %s.",
476 SIGALRM, errno, strerror(errno));
477 return (-1);
478 }
plars865695b2001-08-27 22:15:12 +0000479#if debug
subrata_modak56207ce2009-03-23 13:35:39 +0000480 printf("set_timeout()...\n");
plars865695b2001-08-27 22:15:12 +0000481#endif
482
subrata_modak56207ce2009-03-23 13:35:39 +0000483 Timeout = 0;
484 (void)alarm(TIMEOUT);
485 return 0;
plars865695b2001-08-27 22:15:12 +0000486}
487
488/*****************************************************************************
489 * clear_timeout() : turn off the alarm so that SIGALRM will not get sent.
490 ****************************************************************************/
491
Mike Frysingerc57fba52014-04-09 18:56:30 -0400492static void clear_timeout(void)
plars865695b2001-08-27 22:15:12 +0000493{
subrata_modak56207ce2009-03-23 13:35:39 +0000494 (void)alarm(0);
495 Timeout = 0;
plars865695b2001-08-27 22:15:12 +0000496}
497
498/*****************************************************************************
subrata_modak4bb656a2009-02-26 12:02:09 +0000499 * timeout() : this routine is executed when the SIGALRM signal is
plars865695b2001-08-27 22:15:12 +0000500 * caught. It does nothing but return - if executed during a read()
501 * system call, a -1 will be returned by the read().
502 ****************************************************************************/
503
Mike Frysingere61ddba2014-04-09 23:24:32 -0400504static void timeout(int sig)
plars865695b2001-08-27 22:15:12 +0000505{
506#ifdef debug
subrata_modak56207ce2009-03-23 13:35:39 +0000507 printf("timeout: sigalrm caught.\n");
plars865695b2001-08-27 22:15:12 +0000508#endif
subrata_modak56207ce2009-03-23 13:35:39 +0000509 Timeout = 1;
subrata_modakbdbaec52009-02-26 12:14:51 +0000510
plars865695b2001-08-27 22:15:12 +0000511}
512
513/*****************************************************************************
514 * setup_sigs() : set child up to catch all signals. If there is
515 * trouble, write message in mesg and return -1, else return 0.
516 ****************************************************************************/
517
vapier64a55442009-08-28 13:53:04 +0000518static int setup_sigs(char *mesg)
plars865695b2001-08-27 22:15:12 +0000519{
subrata_modak56207ce2009-03-23 13:35:39 +0000520 int sig;
plars865695b2001-08-27 22:15:12 +0000521
subrata_modak56207ce2009-03-23 13:35:39 +0000522 /* set up signal handler routine */
523 for (sig = 1; sig < NUMSIGS; sig++) {
524 if ((sig != SIGCLD) && (sig != SIGKILL) &&
525 (sig != SIGALRM) && (sig != SIGSTOP)
plars865695b2001-08-27 22:15:12 +0000526#ifdef SIGRESTART
subrata_modak56207ce2009-03-23 13:35:39 +0000527 && (sig != SIGRESTART)
plars865695b2001-08-27 22:15:12 +0000528#endif
529#ifdef SIGRECOVERY
subrata_modak56207ce2009-03-23 13:35:39 +0000530 && (sig != SIGRECOVERY)
plars865695b2001-08-27 22:15:12 +0000531#endif
532#ifdef SIGSWAP
subrata_modak56207ce2009-03-23 13:35:39 +0000533 && (sig != SIGSWAP)
plars865695b2001-08-27 22:15:12 +0000534#endif
subrata_modak56207ce2009-03-23 13:35:39 +0000535 && (sig != SIGCANCEL) && (sig != SIGTIMER)
536 ) {
plars865695b2001-08-27 22:15:12 +0000537
subrata_modak56207ce2009-03-23 13:35:39 +0000538 if (signal(sig, handle_sigs) == SIG_ERR) {
539 /* set up mesg to send back to parent */
540 (void)sprintf(mesg,
541 "signal() failed for signal %d. error:%d %s.",
542 sig, errno, strerror(errno));
543 return (-1);
544 }
545 }
plars865695b2001-08-27 22:15:12 +0000546 }
subrata_modak56207ce2009-03-23 13:35:39 +0000547 return 0;
plars865695b2001-08-27 22:15:12 +0000548}
549
550/*****************************************************************************
551 * handle_sigs() : interrupt handler for all signals. This will be run
552 * if the child process catches a signal (resulting in
553 * a test item FAIL if tst_res has not yet been called). The parent
554 * detects this situation by a child exit value of 1.
555 ****************************************************************************/
556
Mike Frysingerc57fba52014-04-09 18:56:30 -0400557static void handle_sigs(int sig)
plars865695b2001-08-27 22:15:12 +0000558{
subrata_modak56207ce2009-03-23 13:35:39 +0000559 char string[10];
plars865695b2001-08-27 22:15:12 +0000560
561#ifdef debug
562 printf("child: handle_sigs: caught signal %d.\n", sig);
563#endif
564
subrata_modak56207ce2009-03-23 13:35:39 +0000565 sprintf(string, " %d", sig);
566 strcat(signals_received, string);
plars865695b2001-08-27 22:15:12 +0000567
subrata_modak56207ce2009-03-23 13:35:39 +0000568 return;
plars865695b2001-08-27 22:15:12 +0000569}
570
plars865695b2001-08-27 22:15:12 +0000571/*****************************************************************************
572 * getout() : attempt to kill child process and call cleanup().
573 ****************************************************************************/
574
Mike Frysingerc57fba52014-04-09 18:56:30 -0400575static void getout(void)
plars865695b2001-08-27 22:15:12 +0000576{
vapier64a55442009-08-28 13:53:04 +0000577 if (kill(pid, SIGKILL) < 0)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800578 tst_resm(TWARN | TERRNO, "kill(%d) failed", pid);
subrata_modak56207ce2009-03-23 13:35:39 +0000579 cleanup();
plars865695b2001-08-27 22:15:12 +0000580}
581
plars865695b2001-08-27 22:15:12 +0000582/***************************************************************
583 * setup() - performs all ONE TIME setup for this test.
584 ***************************************************************/
Mike Frysingerc57fba52014-04-09 18:56:30 -0400585void setup(void)
plars865695b2001-08-27 22:15:12 +0000586{
Garrett Cooper2c282152010-12-16 00:55:50 -0800587
subrata_modak56207ce2009-03-23 13:35:39 +0000588 tst_sig(FORK, DEF_HANDLER, cleanup);
plars865695b2001-08-27 22:15:12 +0000589
subrata_modak56207ce2009-03-23 13:35:39 +0000590 /* set up pipe for child sending to parent communications */
vapier64a55442009-08-28 13:53:04 +0000591 if (pipe(Fds1) < 0)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800592 tst_brkm(TBROK | TERRNO, cleanup, "pipe() failed");
plars865695b2001-08-27 22:15:12 +0000593
subrata_modak56207ce2009-03-23 13:35:39 +0000594 /* set up pipe for parent sending to child communications */
vapier64a55442009-08-28 13:53:04 +0000595 if (pipe(Fds2) < 0)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800596 tst_brkm(TBROK | TERRNO, cleanup, "pipe() failed");
vapier64a55442009-08-28 13:53:04 +0000597
plars865695b2001-08-27 22:15:12 +0000598#if debug
subrata_modak56207ce2009-03-23 13:35:39 +0000599 printf("child 2 parent Fds1[0] = %d, Fds1[1] = %d\n", Fds1[0], Fds1[1]);
600 printf("parent 2 child Fds2[0] = %d, Fds2[1] = %d\n", Fds2[0], Fds2[1]);
plars865695b2001-08-27 22:15:12 +0000601#endif
602
subrata_modak56207ce2009-03-23 13:35:39 +0000603 TEST_PAUSE;
plars865695b2001-08-27 22:15:12 +0000604
Garrett Cooper2c282152010-12-16 00:55:50 -0800605}
plars865695b2001-08-27 22:15:12 +0000606
607/***************************************************************
608 * cleanup() - performs all ONE TIME cleanup for this test at
609 * completion or premature exit.
610 ***************************************************************/
Mike Frysingerc57fba52014-04-09 18:56:30 -0400611void cleanup(void)
plars865695b2001-08-27 22:15:12 +0000612{
plars865695b2001-08-27 22:15:12 +0000613
Chris Dearmanec6edca2012-10-17 19:54:01 -0700614}