/* Test assertion #10 by verifying that SIGCHLD signals are sent to a parent when their children are stopped. * 12/18/02 - Adding in include of sys/time.h per * rodrigc REMOVE-THIS AT attbi DOT com input that it needs * to be included whenever the timeval struct is used. * */ #include #include #include #include #include #include #include #include #include "posixtest.h" #define NUMSTOPS 10 static volatile int child_stopped; static volatile int child_continued; static volatile int notification; static void handler(int signo PTS_ATTRIBUTE_UNUSED, siginfo_t *info, void *context PTS_ATTRIBUTE_UNUSED) { if (!info) return; notification = info->si_code; switch (notification) { case CLD_STOPPED: printf("Child has been stopped\n"); child_stopped++; break; case CLD_CONTINUED: printf("Child has been continued\n"); child_continued++; break; } } static void wait_for_notification(int val) { struct timeval tv; while (notification != val) { tv.tv_sec = 1; tv.tv_usec = 0; if (!select(0, NULL, NULL, NULL, &tv)) break; } } int main(void) { pid_t pid; struct sigaction act; struct timeval tv; act.sa_sigaction = handler; act.sa_flags = SA_SIGINFO; sigemptyset(&act.sa_mask); sigaction(SIGCHLD, &act, 0); if ((pid = fork()) < 0) { printf("fork() did not return success\n"); return PTS_UNRESOLVED; } else if (pid == 0) { /* child */ while (1) { /* wait forever, or until we are interrupted by a signal */ tv.tv_sec = 0; tv.tv_usec = 0; select(0, NULL, NULL, NULL, &tv); } return 0; } else { /* parent */ int s; int i; for (i = 0; i < NUMSTOPS; i++) { printf("--> Sending SIGSTOP\n"); notification = 0; kill(pid, SIGSTOP); /* Don't let the kernel optimize away queued SIGSTOP/SIGCONT signals. */ wait_for_notification(CLD_STOPPED); printf("--> Sending SIGCONT\n"); notification = 0; kill(pid, SIGCONT); /* SIGCHLD doesn't queue, make sure CLD_CONTINUED doesn't mask the next CLD_STOPPED */ wait_for_notification(CLD_CONTINUED); } kill(pid, SIGKILL); waitpid(pid, &s, 0); } if (child_stopped == NUMSTOPS && child_continued == NUMSTOPS) { printf("Test PASSED\n"); return 0; } printf("Test FAILED\n"); return -1; }