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