diff --git a/tests/auth/superuser-t.c b/tests/auth/superuser-t.c index 63be96a93d..92c48c78f3 100644 --- a/tests/auth/superuser-t.c +++ b/tests/auth/superuser-t.c @@ -29,6 +29,8 @@ #ifdef HAVE_SYS_WAIT_H #include #endif +#include +#include #ifdef IGNORE_SOME_GCC_WARNINGS # pragma GCC diagnostic warning "-Wdeprecated-declarations" @@ -365,6 +367,34 @@ STEST_NewWhoAmI(struct rx_call *call, char **result) return 0; } +/* + * Primitive replacement for using sigtimedwait(). Just see if 'signo' is + * pending, and if it's not, wait 100ms and try again. Try this for + * approximately as many times as it takes to wait for 'nsecs' seconds. + */ +static int +waitforsig(int signo, int nsecs) +{ + int nsleeps; + + for (nsleeps = 0; nsleeps < nsecs * 10; nsleeps++) { + sigset_t set; + struct timespec timeo; + + opr_Verify(sigpending(&set) == 0); + if (sigismember(&set, signo)) { + return 0; + } + + /* Sleep for 100ms */ + timeo.tv_sec = 0; + timeo.tv_nsec = 100 * 1000 * 1000; + opr_Verify(nanosleep(&timeo, NULL) == 0); + } + + return -1; +} + int main(int argc, char **argv) { struct afsconf_dir *dir; @@ -372,6 +402,7 @@ int main(int argc, char **argv) int serverPid, clientPid, waited, stat; int code; int ret = 0; + sigset_t set; char *argv0 = afstest_GetProgname(argv); afstest_SkipTestsIfBadHostname(); @@ -381,8 +412,8 @@ int main(int argc, char **argv) if (argc == 3 ) { if (strcmp(argv[1], "-server") == 0) { globalDir = afsconf_Open(argv[2]); - afstest_StartTestRPCService(argv[2], TEST_PORT, TEST_SERVICE_ID, - TEST_ExecuteRequest); + afstest_StartTestRPCService(argv[2], getppid(), TEST_PORT, + TEST_SERVICE_ID, TEST_ExecuteRequest); exit(0); } else if (strcmp(argv[1], "-client") == 0) { startClient(argv[2]); @@ -396,6 +427,10 @@ int main(int argc, char **argv) /* Otherwise, do the basic configuration, then start the client and * server */ + sigemptyset(&set); + sigaddset(&set, SIGUSR1); + opr_Verify(sigprocmask(SIG_BLOCK, &set, NULL) == 0); + dirname = afstest_BuildTestConfig(); dir = afsconf_Open(dirname); @@ -421,6 +456,17 @@ int main(int argc, char **argv) ret = 1; goto out; } + + /* Our server child pid will send us a SIGUSR1 when it's started listening + * on its port. Wait for up to 5 seconds to get the USR1. */ + if (waitforsig(SIGUSR1, 5) != 0) { + fprintf(stderr, "%s: Timed out waiting for SIGUSR1 from server child\n", + argv0); + kill(serverPid, SIGTERM); + ret = 1; + goto out; + } + clientPid = fork(); if (clientPid == -1) { kill(serverPid, SIGTERM); diff --git a/tests/common/common.h b/tests/common/common.h index 061f7074d0..e1a407c9da 100644 --- a/tests/common/common.h +++ b/tests/common/common.h @@ -40,7 +40,7 @@ extern struct rx_securityClass struct rx_call; extern int afstest_StartVLServer(char *dirname, pid_t *serverPid); extern int afstest_StopServer(pid_t serverPid); -extern int afstest_StartTestRPCService(const char *, u_short, u_short, +extern int afstest_StartTestRPCService(const char *, pid_t, u_short, u_short, afs_int32 (*proc)(struct rx_call *)); /* ubik.c */ diff --git a/tests/common/servers.c b/tests/common/servers.c index 24b2bee601..70dd3667da 100644 --- a/tests/common/servers.c +++ b/tests/common/servers.c @@ -90,6 +90,7 @@ afstest_StopServer(pid_t serverPid) int afstest_StartTestRPCService(const char *configPath, + pid_t signal_pid, u_short port, u_short serviceId, afs_int32 (*proc) (struct rx_call *)) @@ -112,6 +113,10 @@ afstest_StartTestRPCService(const char *configPath, return -1; } + if (signal_pid != 0) { + kill(signal_pid, SIGUSR1); + } + afsconf_BuildServerSecurityObjects(dir, &classes, &numClasses); service = rx_NewService(0, serviceId, "test", classes, numClasses, proc);