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

📄 signal03.c

📁 cygwin, 著名的在win32下模拟unix操作系统的东东
💻 C
📖 第 1 页 / 共 2 页
字号:
	 * 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  ***********************************************************************/voidsigdfl_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. ***************************************************************/voidsetup(){    /* 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. ***************************************************************/voidcleanup(){    /*     * 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. ***********************************************************************/voidp_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. ***********************************************************************/voidc_timeout_handler(){    exit_val = TIMED_OUT;    return;}/*********************************************************************** * This signal handling routine will set a global variable and return * if called. ***********************************************************************/voidcatchsig(){   exit_val = SIG_CAUGHT;   return;}/*********************************************************************** * Update timing information ***********************************************************************/voidupdate_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;}

⌨️ 快捷键说明

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