From: Robert W. <ro...@us...> - 2005-02-24 17:04:22
|
Update of /cvsroot/ltp/ltp/testcases/kernel/syscalls/fcntl In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15956 Modified Files: fcntl11.c fcntl14.c fcntl16.c fcntl17.c fcntl19.c fcntl20.c fcntl21.c Log Message: Applied patch from David Miller: ====================================================================== fcntl16.c (and probably a bunch of other places in the ltp testsuite) use the following scheme: static int alarm_flag; static void catch_alarm(int signo) { alarm_flag = 1; } signal(SIGALRM, catch_alarm); ... alarm(TIME_OUT); wait(&status); Just a quick scan shows that, among the fcntl tests alone, this technique is used in fcntl14.c, fcntl15.c, fcntl16.c, and fcntl17.c The expectation is that if no wait() events occur, the SIGALRM will cause the wait() to return with -EINTR after the signal handler catch_alarm() runs. This never happens, because signal() gives BSD signal semantics and part of that is that the SA_RESTART flag is passed into the actual system call (usually rt_sigaction) used to register the signal handler. SA_RESTART means that the system call is restarted, not returned from, when the signal handler returns. In order to fix this, test cases using this technique in LTP will need to explicitly call sigaction() with the appropriate flags. In particular, it will need to have the SA_RESTART flag clear in such calls. What's really fascinating to me is that this test is passing for somebody out there, I can't believe I'm the only person hitting this :-) I ran my little test program above both on x86 and sparc64, just in case it was some difference in glibc's signal() implementation, but both cases pass the SA_RESTART flag in and both cases restart the wait4() call after the signal handler runs and the program thus hangs forever afterwards. I note that recently there were some "portability" changes for AIX and Solaris that tried to start using sigaction(). These changes are buggy because although they clear sa_flags the rest of the structure besides sa_flags and sa_handler is not initialized. A memset() is needed on the whole sigaction structure, and also a sigaddset(&act.sa_mask, X) is necessary (where X is the signal being registered) before initializing the other elements. But once again, I have no idea how these ltp tests work for other people and this bug has been present in ltp for a very long time. Any insight into that matter would be very appreciated. :-) Index: fcntl17.c =================================================================== RCS file: /cvsroot/ltp/ltp/testcases/kernel/syscalls/fcntl/fcntl17.c,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** fcntl17.c 4 Jan 2005 21:04:32 -0000 1.9 --- fcntl17.c 24 Feb 2005 17:03:42 -0000 1.10 *************** *** 95,98 **** --- 95,99 ---- char *buf = STRING; char template[PATH_MAX]; + struct sigaction act; tst_sig(FORK, DEF_HANDLER, NULL); /* capture signals */ *************** *** 132,136 **** } ! if (signal(SIGALRM, catch_alarm) == SIG_ERR) { tst_resm(TFAIL, "SIGALRM signal setup failed, errno: %d", errno); --- 133,141 ---- } ! memset(&act, 0, sizeof(act)); ! act.sa_handler = catch_alarm; ! sigemptyset(&act.sa_mask); ! sigaddset(&act.sa_mask, SIGALRM); ! if (sigaction(SIGALRM, &act, NULL) < 0) { tst_resm(TFAIL, "SIGALRM signal setup failed, errno: %d", errno); *************** *** 138,142 **** } ! if (signal(SIGCLD, catch_child) == SIG_ERR) { tst_resm(TFAIL, "SIGCLD signal setup failed, errno: %d", errno); --- 143,151 ---- } ! memset(&act, 0, sizeof(act)); ! act.sa_handler = catch_child; ! sigemptyset(&act.sa_mask); ! sigaddset(&act.sa_mask, SIGCLD); ! if (sigaction(SIGCLD, &act, NULL) < 0) { tst_resm(TFAIL, "SIGCLD signal setup failed, errno: %d", errno); Index: fcntl16.c =================================================================== RCS file: /cvsroot/ltp/ltp/testcases/kernel/syscalls/fcntl/fcntl16.c,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** fcntl16.c 7 Feb 2005 20:03:09 -0000 1.7 --- fcntl16.c 24 Feb 2005 17:03:42 -0000 1.8 *************** *** 406,410 **** setup(void) { ! struct sigaction sact; /* capture signals */ --- 406,410 ---- setup(void) { ! struct sigaction sact; /* capture signals */ *************** *** 426,444 **** * Set up signal handling functions */ ! sact.sa_flags = 0; ! sact.sa_handler = catch_usr1; ! (void)sigaction(SIGUSR1, &sact, NULL); sact.sa_handler = catch_usr2; ! (void)sigaction(SIGUSR2, &sact, NULL); sact.sa_handler = catch_alarm; ! (void)sigaction(SIGALRM, &sact, NULL); ! ! /* (void)signal(SIGUSR1, catch_usr1); ! (void)signal(SIGUSR2, catch_usr2); ! (void)signal(SIGALRM, catch_alarm); ! */ } --- 426,446 ---- * Set up signal handling functions */ ! memset(&sact, 0, sizeof(sact)); sact.sa_handler = catch_usr1; ! sigemptyset(&sact.sa_mask); ! sigaddset(&sact.sa_mask, SIGUSR1); ! sigaction(SIGUSR1, &sact, NULL); + memset(&sact, 0, sizeof(sact)); sact.sa_handler = catch_usr2; ! sigemptyset(&sact.sa_mask); ! sigaddset(&sact.sa_mask, SIGUSR2); ! sigaction(SIGUSR2, &sact, NULL); + memset(&sact, 0, sizeof(sact)); sact.sa_handler = catch_alarm; ! sigemptyset(&sact.sa_mask); ! sigaddset(&sact.sa_mask, SIGALRM); ! sigaction(SIGALRM, &sact, NULL); } Index: fcntl14.c =================================================================== RCS file: /cvsroot/ltp/ltp/testcases/kernel/syscalls/fcntl/fcntl14.c,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** fcntl14.c 4 Jan 2005 21:04:18 -0000 1.6 --- fcntl14.c 24 Feb 2005 17:03:42 -0000 1.7 *************** *** 574,577 **** --- 574,579 ---- setup(void) { + struct sigaction act; + tst_sig(FORK, DEF_HANDLER, cleanup); /* capture signals */ umask(0); *************** *** 584,588 **** /* setup signal handler for signal from child */ ! if ((signal(SIGUSR1, catch1)) == SIG_ERR) { tst_resm(TFAIL, "SIGUSR1 signal setup failed, errno = %d", errno); --- 586,594 ---- /* setup signal handler for signal from child */ ! memset(&act, 0, sizeof(act)); ! act.sa_handler = catch1; ! sigemptyset(&act.sa_mask); ! sigaddset(&act.sa_mask, SIGUSR1); ! if ((sigaction(SIGUSR1, &act, NULL)) < 0) { tst_resm(TFAIL, "SIGUSR1 signal setup failed, errno = %d", errno); *************** *** 590,594 **** /*NOTREACHED*/ } ! if ((signal(SIGALRM, catch_alarm)) == SIG_ERR) { tst_resm(TFAIL, "SIGALRM signal setup failed"); cleanup(); --- 596,605 ---- /*NOTREACHED*/ } ! ! memset(&act, 0, sizeof(act)); ! act.sa_handler = catch_alarm; ! sigemptyset(&act.sa_mask); ! sigaddset(&act.sa_mask, SIGALRM); ! if ((sigaction(SIGALRM, &act, NULL)) < 0) { tst_resm(TFAIL, "SIGALRM signal setup failed"); cleanup(); *************** *** 923,931 **** catch1() /* invoked on catching SIGUSR1 */ { /* * Set flag to let parent know that child is ready to have lock * removed */ ! signal(SIGUSR1, (void (*)())catch1); got1++; } --- 934,948 ---- catch1() /* invoked on catching SIGUSR1 */ { + struct sigaction act; + /* * Set flag to let parent know that child is ready to have lock * removed */ ! memset(&act, 0, sizeof(act)); ! act.sa_handler = catch1; ! sigemptyset(&act.sa_mask); ! sigaddset(&act.sa_mask, SIGUSR1); ! sigaction(SIGUSR1, &act, NULL); got1++; } Index: fcntl11.c =================================================================== RCS file: /cvsroot/ltp/ltp/testcases/kernel/syscalls/fcntl/fcntl11.c,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** fcntl11.c 4 Jan 2005 21:04:18 -0000 1.9 --- fcntl11.c 24 Feb 2005 17:03:42 -0000 1.10 *************** *** 105,108 **** --- 105,109 ---- char *buf = STRING; char template[PATH_MAX]; + struct sigaction act; /* capture signals */ *************** *** 128,132 **** } ! if ((signal(SIGCLD, catch_child)) == SIG_ERR) { tst_resm(TFAIL, "SIGCLD signal setup failed, errno: %d", errno); --- 129,137 ---- } ! memset(&act, 0, sizeof(act)); ! act.sa_handler = catch_child; ! sigemptyset(&act.sa_mask); ! sigaddset(&act.sa_mask, SIGCLD); ! if ((sigaction(SIGCLD, &act, NULL)) < 0) { tst_resm(TFAIL, "SIGCLD signal setup failed, errno: %d", errno); Index: fcntl20.c =================================================================== RCS file: /cvsroot/ltp/ltp/testcases/kernel/syscalls/fcntl/fcntl20.c,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** fcntl20.c 4 Jan 2005 21:04:34 -0000 1.8 --- fcntl20.c 24 Feb 2005 17:03:43 -0000 1.9 *************** *** 87,90 **** --- 87,91 ---- char *buf = STRING; char template[PATH_MAX]; + struct sigaction act; /* capture signals */ *************** *** 111,115 **** } ! if ((signal(SIGCLD, catch_child)) == SIG_ERR) { tst_resm(TFAIL, "SIGCLD signal setup failed, errno: %d", errno); --- 112,120 ---- } ! memset(&act, 0, sizeof(act)); ! act.sa_handler = catch_child; ! sigemptyset(&act.sa_mask); ! sigaddset(&act.sa_mask, SIGCLD); ! if ((sigaction(SIGCLD, &act, NULL)) < 0) { tst_resm(TFAIL, "SIGCLD signal setup failed, errno: %d", errno); Index: fcntl21.c =================================================================== RCS file: /cvsroot/ltp/ltp/testcases/kernel/syscalls/fcntl/fcntl21.c,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** fcntl21.c 4 Jan 2005 21:04:34 -0000 1.8 --- fcntl21.c 24 Feb 2005 17:03:43 -0000 1.9 *************** *** 86,90 **** char *buf = STRING; char template[PATH_MAX]; ! /* capture signals */ --- 86,90 ---- char *buf = STRING; char template[PATH_MAX]; ! struct sigaction act; /* capture signals */ *************** *** 112,116 **** } ! if ((signal(SIGCLD, catch_child)) == SIG_ERR) { tst_resm(TFAIL, "SIGCLD signal setup failed, errno: %d", errno); --- 112,120 ---- } ! memset(&act, 0, sizeof(act)); ! act.sa_handler = catch_child; ! sigemptyset(&act.sa_mask); ! sigaddset(&act.sa_mask, SIGCLD); ! if ((sigaction(SIGCLD, &act, NULL)) < 0) { tst_resm(TFAIL, "SIGCLD signal setup failed, errno: %d", errno); Index: fcntl19.c =================================================================== RCS file: /cvsroot/ltp/ltp/testcases/kernel/syscalls/fcntl/fcntl19.c,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** fcntl19.c 4 Jan 2005 21:04:33 -0000 1.8 --- fcntl19.c 24 Feb 2005 17:03:42 -0000 1.9 *************** *** 90,93 **** --- 90,94 ---- char *buf = STRING; char template[PATH_MAX]; + struct sigaction act; /* capture signals */ *************** *** 115,119 **** } ! if ((signal(SIGCLD, catch_child)) == SIG_ERR) { tst_resm(TFAIL, "SIGCLD signal setup failed, errno: %d", errno); --- 116,124 ---- } ! memset(&act, 0, sizeof(act)); ! act.sa_handler = catch_child; ! sigemptyset(&act.sa_mask); ! sigaddset(&act.sa_mask, SIGCLD); ! if ((sigaction(SIGCLD, &act, NULL)) < 0) { tst_resm(TFAIL, "SIGCLD signal setup failed, errno: %d", errno); |