/* Test case for assertion #1 of the sigaction system call that shows sigaction (when used with a non-null act pointer) changes the action for a signal. Steps: 1. Use sigaction to setup a signal handler for SIGABRT 2. Add SIGABRT to the signal mask. 3. Raise SIGABRT. Now, SIGABRT is pending. 4. Call pthread_sigmask() again. Verify that global variable pthread_sigmask_return_val is not set to anything other than it's initial value (which is 1), while we're still inside the signal handler code. 5. Once pthread_sigmask() returns, verify that it returns a zero, and verify that the global handler_called variable has been set to 1; 6. If we manage to verify both steps 4 and 5, then we've proved that signal was delivered before pthread_sigmask() returned. */ #include #include #include #include #include "posixtest.h" int handler_called = 0; int pthread_sigmask_return_val = 1; /* some value that's not a 1 or 0 */ void handler(int signo) { handler_called = 1; if (pthread_sigmask_return_val != 1) { printf("FAIL: pthread_sigmask() returned before signal was delivered.\n"); exit(PTS_FAIL); } } void *a_thread_func() { struct sigaction act; sigset_t blocked_set1; sigemptyset(&blocked_set1); sigaddset(&blocked_set1, SIGABRT); act.sa_handler = handler; act.sa_flags = 0; sigemptyset(&act.sa_mask); if (sigaction(SIGABRT, &act, 0) == -1) { perror("Unexpected error while attempting to setup test " "pre-conditions"); pthread_exit((void*)1); } if (pthread_sigmask(SIG_SETMASK, &blocked_set1, NULL) == -1) { perror("Unexpected error while attempting to use pthread_sigmask.\n"); pthread_exit((void*)1); } if ((raise(SIGABRT) == -1)) { perror("Unexpected error while attempting to setup test " "pre-conditions"); pthread_exit((void*)1); } pthread_sigmask_return_val = pthread_sigmask(SIG_UNBLOCK, &blocked_set1, NULL); if (pthread_sigmask_return_val != 0) { perror("Unexpected error while attempting to use pthread_sigmask.\n"); pthread_exit((void*)1); } if (handler_called != 1) { perror("Handler wasn't called, implying signal was not delivered.\n"); pthread_exit((void*)1); } printf("Test PASSED: signal was delivered before the call to pthread_sigmask returned.\n"); pthread_exit((void*)0); /* To please some compilers */ return NULL; } int main() { int *thread_return_value; pthread_t new_thread; if (pthread_create(&new_thread, NULL, a_thread_func, NULL) != 0) { perror("Error creating new thread\n"); return PTS_UNRESOLVED; } if (pthread_join(new_thread, (void*)&thread_return_value) != 0) { perror("Error in pthread_join()\n"); return PTS_UNRESOLVED; } if ((long)thread_return_value != 0) { if ((long)thread_return_value == 1) { printf ("Test UNRESOLVED\n"); return PTS_UNRESOLVED; } else if ((long)thread_return_value == -1) { printf ("Test FAILED\n"); return PTS_FAIL; } else { printf ("Test UNRESOLVED\n"); return PTS_UNRESOLVED; } } return PTS_PASS; }