diff options
Diffstat (limited to 'winsup/testsuite/winsup.api/ltp/signal03.c')
-rw-r--r-- | winsup/testsuite/winsup.api/ltp/signal03.c | 665 |
1 files changed, 0 insertions, 665 deletions
diff --git a/winsup/testsuite/winsup.api/ltp/signal03.c b/winsup/testsuite/winsup.api/ltp/signal03.c deleted file mode 100644 index 38ba72b..0000000 --- a/winsup/testsuite/winsup.api/ltp/signal03.c +++ /dev/null @@ -1,665 +0,0 @@ -/* - * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * Further, this software is distributed without any warranty that it is - * free of the rightful claim of any third person regarding infringement - * or the like. Any license provided herein, whether implied or - * otherwise, applies only to this software file. Patent licenses, if - * any, provided herein do not apply to combinations of this program with - * other software, or any other product whatsoever. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write the Free Software Foundation, Inc., 59 - * Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, - * Mountain View, CA 94043, or: - * - * http://www.sgi.com - * - * For further information regarding this notice, see: - * - * http://oss.sgi.com/projects/GenInfo/NoticeExplan/ - * - */ -/* $Id$ */ -/*********************************************************************************** - * - * OS Test - Silicon Graphics, Inc. Eagan, Minnesota - * - * TEST IDENTIFIER : signal03 Boundary value and other invalid value checking - * of signal setup and signal sending. - * - * PARENT DOCUMENT : sgntds01 Signal System Call - * - * AUTHOR : Dave Baumgartner - * : Rewrote 12/92 by Richard Logan - * - * CO-PILOT : Barrie Kletscher - * - * DATE STARTED : 10/17/85 - * - * TEST ITEMS - * - * 1. SIGKILL can not be set to be caught, errno:EINVAL (POSIX). - * 2. SIGKILL can not be caught. - * 3. SIGKILL can not be set to be ignored, errno:EINVAL (POSIX). - * 4. SIGKILL can not be ignored. - * 5. SIGKILL can not be reset to default, errno:EINVAL (POSIX. - * - * ENVIRONMENTAL NEEDS - * - * NONE - * - * SPECIAL PROCEDURAL REQUIREMENTS - * - * None - * - * INTERCASE DEPENDENCIES - * - * 2 depends on 1 and 4 on 3. - * - * DETAILED DESCRIPTION - * - * main() - * Call catch_test to test setup and catching of SIGKILL. - * - * - * Call ignore_test to test setup and ignoring of SIGKILL. - * - * - * Call sigdfl_test to test setting SIGKILL to default. - * - * * END OF MAIN * - * - * - * catch_test() - * - * fork a child - * if this is the parent - * sleep to let child start. - * send sig to child. - * wait for the child to terminate. - * - * if the termination status of the child equals the signal sent to it - * Test item 1 PASSED the child was killed. - * else if status equals the exit value of SIG_CAUGHT - * Test item 2 FAILED sig was caught. - * else - * Test item 2 FAILED because the child was not killed - * but sig was not caught either. - * - * else this the child - * set exit_val to SIG_NOT_CAUGHT. - * set to catch sig, where the interrupt routine just sets - * exit_val to SIG_CAUGHT. - * - * If the return value and errno, after trying to set to catch sig, - * do not indicate that an error has occurred. - * Test item 1 FAILED bad return, return value:X, errno:X. - * else - * Test item 1 PASSED sig was not set to be caught. - * - * pause until the parent sends a signal. - * The child should be killed by the signal but if not exit - * with exit_val. - * - * * End of catch_test. * - * - * - * ignore_test() - * - * fork a child - * if this is the parent - * sleep to let child start. - * send SIGKILL to child. - * wait for the child to terminate. - * - * if the termination status of the child equals SIGKILL - * Test item 4 PASSED the child was killed. - * else if the status equals the exit value of SIG_IGNORED - * Test item 4 FAILED SIGKILL was ignored. - * - * else this the child - * - * If the return value and errno, after trying to set to ignore SIGKILL, - * do not indicate that an error has occurred. - * Test item 3 FAILED bad return, return value:X, errno:X. - * else - * Test item 3 PASSED SIGKILL was not set to be ignored. - * - * pause until the parent sends SIGKILL. - * The child should be killed by the signal but if not exit - * with SIG_IGNORED. - * - * * End of ignore_test. * - * - * - * sigdfl_test() - * - * If the return value and errno, after trying to set to SIGKILL to default, - * do not indicate that an error has occurred. - * Test item 5 FAILED bad return, return value:X, errno:X. - * else - * Test item 5 PASSED SIGKILL was not set to default. - * - * * End of sigdfl_test. * - * - * BUGS/NOTES - * Since the system call under test is executed in the child, no - * timings on this system call will be reported. - * -***********************************************************************************/ - -#include <signal.h> -#include <errno.h> -#include <unistd.h> -#include <fcntl.h> -#include <string.h> -#include <stdlib.h> -#include <sys/wait.h> - -#include "test.h" -#include "usctest.h" - -void setup(); -void cleanup(); -void do_test(); -void sigdfl_test(); -void update_timings(); - -#if defined(linux) -# define SIG_PF sig_t /* This might need to be sighandler_t on some systems */ -#elif defined(__CYGWIN__) -typedef void (*sighandler_t) (int); -#define SIG_PF sighandler_t -#endif - -#define SIG_CAUGHT 1 -#define SIG_NOT_CAUGHT 0 -#define SIG_IGNORED 5 -#define TIMED_OUT 99 - -#define TIMEOUT 20 - -#define GO_FLAG 1 -#define ERROR_FLAG 2 -#define PASS_FLAG 3 -#define FAIL_FLAG 4 - -#define IGNORE_TEST 1 -#define CATCH_TEST 2 - -#define MAXMESG 150 /* The Maximum message that can be created. */ - -int exit_val; /* Global variable, used to tell whether the */ - /* child exited instead of being killed. */ -extern int errno; /* errno holds the error value returned by */ - /* a system call. */ -char mesg[MAXMESG]; /* Holds messages to pass to tst_res. */ - -struct ipc_t { - int status; - char mesg[MAXMESG]; - struct tblock timings; -} Ipc_info; - -char *TCID = "signal03"; -int TST_TOTAL = 5; -extern int Tst_count; /* count of test items completed */ - -int Pid; /* Return value from fork. */ - -long Tret; - -/*********************************************************************** - * M A I N - ***********************************************************************/ -int -main(argc, argv) -int argc; -char **argv; -{ - int lc; - const char *msg; - - /*************************************************************** - * parse standard options - ***************************************************************/ - if ( (msg=parse_opts(argc, argv, (option_t *) NULL, NULL)) != (char *) NULL ) { - tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); - tst_exit(); - } - - /*************************************************************** - * perform global setup for test - ***************************************************************/ - setup(); - - /*************************************************************** - * check looping state if -c option given - ***************************************************************/ - for (lc=0; TEST_LOOPING(lc); lc++) { - - /* reset Tst_count in case we are looping. */ - Tst_count=0; - - errno=-4; - - /* - * Call catch_test to test setup and catching of SIGKILL. - */ - (void) do_test(CATCH_TEST, Tst_count); - - /* - * Call ignore_test to test setup and ignoring of SIGKILL. - */ - (void) do_test(IGNORE_TEST, Tst_count); - - /* - * Call sigdfl_test to test setting SIGKILL to default. - */ - (void) sigdfl_test(); - - } - - cleanup(); - - return 0; -} /*End of main*/ - -/*********************************************************************** - * - ***********************************************************************/ -void -do_test(test_case, tst_count) -int test_case; -int tst_count; -{ - int term_stat; /* Termination status of the child returned to */ - /* the parent. */ - char string[30]; - int fd1[2]; /* ipc */ - int rd_sz; /* size of read */ - void p_timeout_handler(); - void c_timeout_handler(); - void catchsig(); - - Tst_count = tst_count; - - /* - * Create a pipe of ipc - */ - if ( pipe(fd1) == -1 ) { - sprintf(mesg, - "pipe system call failed, Errno: %d, Error message: %s", - errno,strerror(errno)); - tst_resm(TBROK,mesg); - tst_resm(TBROK,mesg); - return; - } - - /* - * Cause the read to return 0 once EOF is encountered and the - * read to return -1 if pipe is empty. - */ - - if ( fcntl(fd1[0], F_SETFL, O_NONBLOCK) == -1 ) { - sprintf(mesg, "fcntl(fd1[0], F_SETFL, O_NONBLOCK) failed: errno=%d", - errno); - tst_resm(TBROK,mesg); - tst_resm(TBROK,mesg); - close(fd1[0]); - close(fd1[1]); - return; - } - - if ((Pid = fork()) > 0) { /* parent */ - - signal(SIGALRM, p_timeout_handler); - - alarm(TIMEOUT); - - close(fd1[1]); /* close write side */ - - /* - * Deal with child's messages. - * Only the GO_FLAG status will allow parent to - * go on. All pipe io will be in the ipc_t structure sizes - * to avoid reading part of next message. - */ - while ( 1 ) { - - while ( (rd_sz=read(fd1[0], (char *)&Ipc_info, sizeof(Ipc_info))) != 0 ) { - if ( rd_sz > 0 ) - break; /* read something */ - } - - if ( rd_sz == 0 ) { /* if EOF encountered */ - sprintf(mesg, "child's pipe is closed before 'go' message received"); - tst_resm(TBROK, Ipc_info.mesg); - tst_resm(TBROK, Ipc_info.mesg); - close(fd1[0]); - return; - } - - else if ( Ipc_info.status == GO_FLAG ) { - break; /* go on */ - } - else if ( Ipc_info.status == ERROR_FLAG ) { - tst_resm(TBROK, "From child: %s", Ipc_info.mesg); - tst_resm(TBROK, "From child: %s", Ipc_info.mesg); - close(fd1[0]); - return; - } - else if ( Ipc_info.status == PASS_FLAG ) { - - if ( STD_FUNCTIONAL_TEST ) - tst_resm(TPASS, "From child: %s", Ipc_info.mesg); - else - Tst_count++; - update_timings(Ipc_info.timings); - } - else if ( Ipc_info.status == FAIL_FLAG ) { - tst_resm(TFAIL, "From child: %s", Ipc_info.mesg); - update_timings(Ipc_info.timings); - } - else { - tst_resm(TINFO, "Unknown message from child: %s", mesg); - } - } - - /* - * Send the signal SIGKILL to the child. - */ - if (kill(Pid,SIGKILL) == -1) - { - /* - * The kill system call failed. - */ - sprintf(mesg, - "kill(Pid,SIGKILL) failed, Errno: %d, Error message: %s", - errno,strerror(errno)); - tst_resm(TBROK,mesg); - tst_resm(TBROK,mesg); - close(fd1[0]); - return; - } - - /* - * Wait for the child to terminate and check the termination status. - */ - if (wait(&term_stat) == -1) { - /* - * The wait system call failed. - */ - sprintf(mesg, - "Wait system call failed. Errno: %d, Error message: %s", - errno,strerror(errno)); - tst_resm(TBROK,mesg); - tst_resm(TBROK,mesg); - close(fd1[0]); - return; - } - else if ( STD_FUNCTIONAL_TEST ) { - if ((term_stat & 0377) == SIGKILL) { - /* - * The child was killed by the signal sent, - * which is correct. - */ - tst_resm(TPASS,"The child was killed by SIGKILL."); - } - else if ( (term_stat >> 8) == TIMED_OUT ) { - sprintf(mesg, "child exited with a timed out exit status"); - tst_resm(TBROK,mesg); - } - else { - if ((term_stat >> 8) == SIG_IGNORED && test_case == IGNORE_TEST ) { - sprintf(mesg, - "SIGKILL was ignored by child after sent by parent."); - } - else if ((term_stat >> 8) == SIG_CAUGHT && test_case == CATCH_TEST ) { - sprintf(mesg, - "SIGKILL was caught by child after sent by parent."); - } - else { - sprintf(mesg, - "Child's termination status is unexpected. Status: %d (%#o).", - term_stat, term_stat); - } - tst_resm(TFAIL, mesg); - } - } - else { - Tst_count++; /* increment test counter */ - } - close(fd1[0]); - - } /* End of parent. */ - else if (Pid == 0) { - /* - * This is the child. - * Set up to ignore/catch SIGKILL and check the return values. - */ - errno=0; - if ( test_case == IGNORE_TEST ) { - exit_val = SIG_IGNORED; - strcpy(string, "signal(SIGKILL, SIG_IGN)"); - - Tret=(long)signal(SIGKILL, SIG_IGN); - TEST_ERRNO=errno; - } - else { - exit_val = SIG_NOT_CAUGHT; - strcpy(string, "signal(SIGKILL, catchsig)"); - Tret=(long)signal(SIGKILL, catchsig); - TEST_ERRNO=errno; - } - Ipc_info.timings=tblock; - - if ( (SIG_PF)Tret == SIG_ERR ) { - if ( TEST_ERRNO == EINVAL ) { - sprintf(Ipc_info.mesg, "%s ret:%ld SIG_ERR (%ld) as expected", - string, Tret, (long)SIG_ERR); - Ipc_info.status = PASS_FLAG; - } - else { - sprintf(Ipc_info.mesg, - "%s ret:%ld, errno:%d expected ret:%ld, errno:%d", - string, Tret, TEST_ERRNO, (long)SIG_ERR, EINVAL); - Ipc_info.status = FAIL_FLAG; - } - - write(fd1[1], (char *)&Ipc_info, sizeof(Ipc_info)); - } - else { - /* - * The child was not allowed to set the signal to - * be ignored and errno was correct. - */ - sprintf(Ipc_info.mesg, - "%s ret:%ld, errno:%d expected ret:%ld, errno:%d", - string, Tret, TEST_ERRNO, (long)SIG_ERR, EINVAL); - Ipc_info.status = FAIL_FLAG; - write(fd1[1], (char *)&Ipc_info, sizeof(Ipc_info)); - } - - /* - * tell parent we are ready - setup by child is done - */ - Ipc_info.status = GO_FLAG; - write(fd1[1], (char *)&Ipc_info, sizeof(Ipc_info)); - - /* - * Set the alarm to wake up from the pause below if - * the parents signal is ignored. - */ - signal(SIGALRM, p_timeout_handler); - alarm(TIMEOUT); - - /* - * Pause until the parent sends a signal or until alarm is received. - */ - pause(); - - exit(exit_val); - - - } /* End of child. */ - else { - /* - * The fork system call failed. - */ - sprintf(mesg, - "Fork system call failed. Errno: %d, Error message: %s", - errno,strerror(errno)); - tst_resm(TBROK,mesg); - tst_resm(TBROK,mesg); - close(fd1[0]); - close(fd1[1]); - return; - } - -} /* End of do_test. */ - -/*********************************************************************** - * sigdfl_test - test for attempt to set SIGKILL to default - ***********************************************************************/ -void -sigdfl_test() -{ - /* - * Try to set SIGKILL to default and check the return values. - */ - errno=-4; - - Tret=(long)signal(SIGKILL,SIG_DFL); - TEST_RETURN=Tret; - TEST_ERRNO=errno; - - - if ( (SIG_PF)TEST_RETURN == SIG_ERR ) { - if ( STD_FUNCTIONAL_TEST ) { - if ( TEST_ERRNO != EINVAL ) { - sprintf(mesg, - "signal(SIGKILL,SIG_DFL) ret:%d, errno:%d expected ret:-1, errno:%d", - TEST_RETURN, TEST_ERRNO, EINVAL); - tst_resm(TFAIL, mesg); - } - else { - sprintf(mesg, - "signal(SIGKILL,SIG_DFL) ret:%d, errno:%d as expected.", - TEST_RETURN, TEST_ERRNO); - tst_resm(TPASS, mesg); - } - } - else - Tst_count++; - } - else { - sprintf(mesg, - "signal(SIGKILL,SIG_DFL) ret:%d, errno:%d expected ret:-1, errno:%d", - TEST_RETURN, TEST_ERRNO, EINVAL); - tst_resm(TFAIL, mesg); - } - -} /* End of sigdfl_test. */ - -/*************************************************************** - * setup() - performs all ONE TIME setup for this test. - ***************************************************************/ -void -setup() -{ - /* capture signals */ - tst_sig(FORK, DEF_HANDLER, cleanup); - - /* make and change to a temporary directory */ - tst_tmpdir(); - - /* Pause if that option was specified */ - TEST_PAUSE; - -} /* End setup() */ - -/*************************************************************** - * cleanup() - performs all ONE TIME cleanup for this test at - * completion or premature exit. - ***************************************************************/ -void -cleanup() -{ - - /* - * print timing stats if that option was specified. - * print errno log if that option was specified. - */ - - TEST_CLEANUP; - - /* - * remove the temporary directory and exit with - * return code appropriate for results - */ - - tst_rmdir(); - - tst_exit(); - -} /* End cleanup() */ - -/*********************************************************************** - * Signal handler routine that used by the parent to handler - * a time out situation. It will attempt to kill the child and - * call cleanup. - ***********************************************************************/ -void -p_timeout_handler() -{ - kill(Pid, SIGKILL); - cleanup(); -} - -/*********************************************************************** - * Signal handler routine that used by the child to handle - * a time out situation. It will set a global varaible and return - * if called. - ***********************************************************************/ -void -c_timeout_handler() -{ - exit_val = TIMED_OUT; - return; -} - -/*********************************************************************** - * This signal handling routine will set a global variable and return - * if called. - ***********************************************************************/ -void -catchsig() -{ - exit_val = SIG_CAUGHT; - return; -} - -/*********************************************************************** - * Update timing information - ***********************************************************************/ -void -update_timings(atblock) -struct tblock atblock; -{ - tblock.tb_max += atblock.tb_max; - tblock.tb_min += atblock.tb_min; - tblock.tb_total += atblock.tb_total; - tblock.tb_count += atblock.tb_count; -} |