blob: bfab4fd44689562498c91b041ff68ab9240ae354 [file] [log] [blame]
/*
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 <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#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;
}