⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kill02.c

📁 cygwin, 著名的在win32下模拟unix操作系统的东东
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * 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: kill02.c,v 1.1 2001/09/13 17:30:23 duda Exp $ *//***********************************************************************************    OS Test -  Silicon Graphics, Inc.    TEST IDENTIFIER :  kill02  Sending a signal to processes with the same process group ID.    PARENT DOCUMENT :  kiltds01  Kill System Call.		    AUTHOR          :  Dave Baumgartner    CO-PILOT        :  Barrie Kletscher    DATE STARTED    :  12/30/85    TEST ITEMS	1. Sending a signal to pid of zero sends to all processes whose process	   group ID is equal to the process group ID as the sender.	2. Sending a signal to pid of zero does not send to processes in another process group.    OUTPUT SPECIFICATIONS	PASS :		kiltcs02 1 PASS The signal was sent to all processes in the process group.		kiltcs02 2 PASS The signal was not sent to selective processes that were not in the process group.	FAIL :		kiltcs02 1 FAIL The signal was not sent to all processes in the process group.		kiltcs02 2 FAIL The signal was sent to a process that was not in the process group.	BROK :		kiltcs02 # BROK System call XXX failed. Errno:X, Error message:XXX.		kiltcs02 # BROK Setting to catch unexpected signal %d failed. Errno: %d, Error message %s.		kiltcs02 # BROK Setting to ignore signal %d failed. Errno: %d, Error message %s.	WARN :		kiltcs02 0 WARN Unexpected signal X was caught.    SPECIAL PROCEDURAL REQUIREMENTS	The program must be linked with tst_res.o.    DETAILED DESCRIPTION	**Setup**	Set up unexpected signal handling.	Set up one pipe for each process to be created with no blocking for read.		**MAIN**	If setup fails exit.	Fork 2 children(1 & 2).	Wait for set up complete messages from the 1st and 2nd child.	Send the signal SIGUSR1 with pid equal to zero.	Sleep a reasonable amount of time so that each child has been swapped in	to process the signal.	Now decide the outcome of the test items by reading from each pipe to find	out if the child was interrupted by the signal and wrote to it.	Remove the second child.	Tell the first child it is time to remove it's child B because the decisions have been made.	Exit.	**First Child**	Set to catch SIGUSR1 with an int_rout1.	Set up to handle the message from the parent to remove child B.	Fork two children(A & B).	Wait for set up complete messages from child A & child B.	Send a set up complete message to the parent.	Pause until the signal SIGUSR1 comes in from the parent.	Pause until the parent says it is time to remove the child.	Exit.	**Second Child**	Set to catch SIGUSR1 with an int_rout2.	Set the process group to be something different than the parents.	Send a set up complete message to the parent.	Pause until killed by parent because this child shouldn't receive signal SIGUSR1.	**Child A**	Set to catch SIGUSR1 with an int_routA.	Send a set up complete message to the parent(First Child).	Pause until the signal SIGUSR1 comes in from the parent.	Exit.	**Child B**	Set to catch SIGUSR1 with an int_routB.	Set the process group to be something different than the parents(First Child's).	Send a set up complete message to the parent.	Pause until killed by parent because this child shouldn't receive signal SIGUSR1.	**usr1_rout-Used by all children**	Write to the appropriate pipe that the signal SIGUSR1 was caught.	**usr2_rout**	Remove child B.******************************************************************************/#include <sys/param.h>#include <signal.h>#include <errno.h>   #include <fcntl.h>#include <string.h>#include <stdlib.h>#include "test.h"    #include "usctest.h"#define MAXMESG 150		/*The maximum message that can be created.		*/#define CHAR_SET_FAILED	"0"	/*Set up failing status transferred through the pipe.	*/#define CHAR_SET_PASSED	"1"	/*Set up passing status transferred through the pipe.	*/#define SIG_CAUGHT	"2"	/*Indicates that the signal SIGUSR1 was caught.		*/#define SIG_RECEIVED	1	/*Integer value that indicates that the signal SIGUSR1	*/				/*was caught.						*/#define SIG_NOT_RECD	0	/*Integer value that indicates that the signal SIGUSR1	*/				/*was caught.						*/#define INT_SET_FAILED	0	/*Set up failing status transferred through the pipe.	*/#define INT_SET_PASSED	1	/*Set up passing status transferred through the pipe.	*/#define SLEEP_TIME	10	/*Amount of time the children get to catch the signal 	*/#define TRUE	 	40	/*Child exits with this if execution was as	*/				/*expected.						*/#define FALSE	 	50	/*Child exits with this if it timed out waiting for the 	*/				/*parents signal.					*/#define TIMEOUT		60	/*Amount of time given in alarm calls.			*/#define CHILD_EXIT(VAR) ((VAR >> 8) & 0377)  /*Exit value from the child.		*/#define CHILD_SIG(VAR) (VAR & 0377) /*Signal value from the termination of child.	*/				/*from the parent.					*/#define SYS_FAIL	"The system call %s failed. Errno: %d, Error message: %s."int pid1;			/*Return value from 1st fork. Global so that it can be	*/				/*used in interrupt handling routines.			*/int pid2;			/*Return value from 2nd fork. Global so that it can be	*/				/*used in interrupt handling routines.			*/int pidA;			/*Return value from 1st fork in child 1. Global so that it 	*/				/*can be used in interrupt handling routines.		*/int pidB;			/*Return value from 2nd fork in child 1. Global so that it 	*/				/*can be used in interrupt handling routines.		*/extern int errno;		/*Error number returned by a system call.		*/int pipe1_fd[2];		/*Pipe file descriptors used for communication  	*/				/*between child 1 and the 1st parent.			*/int pipe2_fd[2];		/*Pipe file descriptors used for communication  	*/				/*between child 2 and the 1st parent.			*/int pipeA_fd[2];		/*Pipe file descriptors used for communication  	*/				/*between child A and the 1st parent.			*/int pipeB_fd[2];		/*Pipe file descriptors used for communication  	*/				/*between child B and the 1st parent.			*/char pipe_buf[10];		/*Pipe buffer.					 	*/char buf_tmp1[2],buf_tmp2[2];	/*Temp hold for info read into pipe_buf.		*/int read1_stat = 0;		/*Number of characters read from pipe 1.		*/int read2_stat = 0;		/*Number of characters read from pipe 2.		*/int readA_stat = 0;		/*Number of characters read from pipe A.		*/int readB_stat = 0;		/*Number of characters read from pipe B.		*/int alarm_flag = FALSE;		/*This flag indicates an alarm time out.			*/char who_am_i = '0';		/*This indicates which process is which when using	*/				/*interrupt routine usr1_rout.				*/void notify_timeout();		/*Signal handler that the parent enters if it times out	*/				/*waiting for the child to indicate its set up status.	*/void parent_rout();		/*This is the parents routine.				*/void child1_rout();		/*This is child 1's routine.				*/void child2_rout();		/*This is child 2's routine.				*/void childA_rout();		/*This is child A's routine.				*/void childB_rout();		/*This is child B's routine.				*/void usr1_rout();		/*This routine is used by all children to indicate that	*/				/*they have caught signal SIGUSR1.			*/void par_kill();		/*This routine is called by the original parent to	*/				/*remove child 2 and to indicate to child 1 to 		*/				/*remove its children.					*/void chld1_kill();		/*This routine is used by child 1 to remove itself and	*/				/*its children A and B.					*/void setup();void cleanup();char *TCID="kill02";          /* Test program identifier.    */int TST_TOTAL=2;                /* Total number of test cases. */extern int Tst_count;           /* Test Case counter for tst_* routines */extern int Tst_nobuf;           /* var. used to turn off tst_res buffering */int exp_enos[]={0};             /* Array of expected errnos *//*********************************************************************** * MAIN ***********************************************************************/intmain(int ac, char **av){  char mesg[MAXMESG];	/* Holds messages to pass to tst_res.		 */    int lc;             /* loop counter */    const char *msg;	/* message returned from parse_opts */    Tst_nobuf=1;    /***************************************************************     * parse standard options, and exit if there is an error     * the -t and -f options not support yet.     ***************************************************************/    if ( (msg=parse_opts(ac, av, (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;	if ((pid1 = fork()) > 0)	{	    /*	     *  This is the parent, fork again to create child 2.	     */	     if ((pid2 = fork()) > 0) {		/*		 *  This is the parent.		 */		 (void) parent_rout();	     }	     else if (pid2 == 0) {		/*		 *  This is child 2.		 */		 (void) child2_rout();	     }	     else {		/*		 *  The second fork failed kill the first child.		 */		 if (kill(pid1,SIGKILL) == -1 && errno != ESRCH) {			tst_resm(TWARN,"Child process may not have been killed.");		 }		 (void) sprintf(mesg,SYS_FAIL,"fork",errno,strerror(errno));		 tst_brkm(TBROK,cleanup,mesg);	    }	}	else if (pid1 == 0) {	    /*	     *  This is child 1.	     */	     (void) child1_rout();	}	else {	    /*	     * Fork failed.	     */	     (void) sprintf(mesg,SYS_FAIL,"fork",errno,strerror(errno)); 	     tst_brkm(TBROK,cleanup,mesg);	 }   }   cleanup();   return 0;} /* END OF MAIN.*//****************************************************************************** *  This is the parents routine.  The parent waits for the children 1 and 2 to *  get set up. Then sends the signal and checks the outcome. *********************************************************************************/void parent_rout(){	char mesg[MAXMESG];	/*Used to buffer messages for tst_resm.	*/  /*   *  Set to catch the alarm signal SIGALRM.   */   if (signal(SIGALRM,notify_timeout) == SIG_ERR) {	(void) par_kill();	tst_brkm(TBROK, NULL,	    "Could not set to catch the parents time out alarm.");	tst_exit();   }  /*   *  Setting to catch the timeout alarm worked now let the children start up.   *  Set an alarm which causes a time out on the read pipe loop.   *  The children will notify the parent that set up is complete   *  and the pass/fail status of set up.   */   (void) alarm(TIMEOUT);   while ((read(pipe1_fd[0],pipe_buf,1) != 1) && (alarm_flag == FALSE))	/*EMPTY*/;   strncpy(buf_tmp1,pipe_buf,1);   (void) alarm(TIMEOUT);   while ((read(pipe2_fd[0],pipe_buf,1) != 1) && (alarm_flag == FALSE))	/*EMPTY*/;   (void) alarm(0);	/*Reset the alarm clock.*/   strncpy(buf_tmp2,pipe_buf,1);  /*   *  Check the alarm flag.   */   if (alarm_flag == TRUE) {	 tst_brkm(TBROK,NULL,"The set up of the children failed by timing out.");	 (void) par_kill();	 cleanup();   }  /*   *  Check to see if either child failed in the set up.   */   if ( (strncmp(buf_tmp1,CHAR_SET_FAILED,1) == 0) ||	(strncmp(buf_tmp2,CHAR_SET_FAILED,1) == 0)) {	/*	 * Problems were encountered in the set up of one of the children.	 * The error message has been displayed by the child.	 */	 (void) par_kill();	 cleanup();   }  /*   *  Setup passed, now send SIGUSR1 to process id of zero.   */   TEST( kill(0,SIGUSR1) );     if ( TEST_RETURN == -1)   {	(void) sprintf(mesg,SYS_FAIL,"kill",errno,strerror(errno));	tst_brkm(TBROK,NULL,mesg);	(void) par_kill();	cleanup();   }  /*   *  Sleep for a while to allow the children to get a chance to    *  catch the signal.   */   (void) sleep(SLEEP_TIME);	  /*   *  The signal was sent above and time has run out for child response,   *  check the outcomes.   */   read1_stat = read(pipe1_fd[0],pipe_buf,1);   if (read1_stat == -1 && errno == EAGAIN) read1_stat = 0;   read2_stat = read(pipe2_fd[0],pipe_buf,1);   if (read2_stat == -1 && errno == EAGAIN) read2_stat = 0;   readA_stat = read(pipeA_fd[0],pipe_buf,1);   if (readA_stat == -1 && errno == EAGAIN) readA_stat = 0;   readB_stat = read(pipeB_fd[0],pipe_buf,1);   if (readB_stat == -1 && errno == EAGAIN) readB_stat = 0;   if (read1_stat == -1 || read2_stat == -1 || 		   readA_stat == -1 || readB_stat == -1) {	/*	 * The read system call failed.	 */	 (void) sprintf(mesg,SYS_FAIL,"read",errno,strerror(errno));	 tst_brkm(TBROK,NULL,mesg);	 (void) par_kill();	 cleanup();   }   /*    * Check the processes that were supposed to get the signal.    */    if (read1_stat == SIG_RECEIVED) {	if (readA_stat == SIG_RECEIVED) {	    /*	     *  Both processes, 1 and A, that were supposed to receive	     *  the signal did receive the signal.	     */	    if ( STD_FUNCTIONAL_TEST )	        tst_resm(TPASS,		    "The signal was sent to all processes in the process group.");	    else		Tst_count++;	}	else { /*Process A didn't receive the signal.*/	    tst_resm(TFAIL,"Process A did not receive the signal.");	}    }    else { /*Process 1 didn't receive the signal.*/	tst_resm(TFAIL,"Process 1 did not receive the signal.");    }   /*    * Check the processes that were not supposed to get the signal.    */    if (read2_stat == SIG_NOT_RECD) {	if (readB_stat == SIG_NOT_RECD) {	    /*	     *  Both processes, 2 and B did not receive the signal.	     */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -