10dc076565f772bb1953209fb69ea150b494aaa40robbiew/*
20dc076565f772bb1953209fb69ea150b494aaa40robbiew
30dc076565f772bb1953209fb69ea150b494aaa40robbiew * Copyright (c) 2002-2003, Intel Corporation. All rights reserved.
40dc076565f772bb1953209fb69ea150b494aaa40robbiew * Created by:  rusty.lynch REMOVE-THIS AT intel DOT com
50dc076565f772bb1953209fb69ea150b494aaa40robbiew * This file is licensed under the GPL license.  For the full content
62c28215423293e443469a07ae7011135d058b671Garrett Cooper * of this license, see the COPYING file at the top level of this
70dc076565f772bb1953209fb69ea150b494aaa40robbiew * source tree.
80dc076565f772bb1953209fb69ea150b494aaa40robbiew
92c28215423293e443469a07ae7011135d058b671Garrett Cooper  Test case for assertion #22 of the sigaction system call that verifies
102c28215423293e443469a07ae7011135d058b671Garrett Cooper  that if the SA_NODEFER flag is set for a given signal, then when the
112c28215423293e443469a07ae7011135d058b671Garrett Cooper  sa_sigaction signal-catching function is entered, then the signal that
122c28215423293e443469a07ae7011135d058b671Garrett Cooper  was caught is not added to the signal mask by raising that signal in the
130dc076565f772bb1953209fb69ea150b494aaa40robbiew  signal handler and verifying that the handler is reentered.
142c28215423293e443469a07ae7011135d058b671Garrett Cooper
150dc076565f772bb1953209fb69ea150b494aaa40robbiew  Steps:
160dc076565f772bb1953209fb69ea150b494aaa40robbiew  1. Fork a new process
170dc076565f772bb1953209fb69ea150b494aaa40robbiew  2. (parent) wait for child
18d3df7e05e9f72b583d8d7e95b26e1d0d77f7e323Garrett Cooper  3. (child) Setup a signal handler for SIGUSR2 with SA_NODEFER set
190dc076565f772bb1953209fb69ea150b494aaa40robbiew     in the sa_flags field
20d3df7e05e9f72b583d8d7e95b26e1d0d77f7e323Garrett Cooper  4. (child) raise SIGUSR2
210dc076565f772bb1953209fb69ea150b494aaa40robbiew  5. (child, signal handler) increment handler count
22d3df7e05e9f72b583d8d7e95b26e1d0d77f7e323Garrett Cooper  6. (child, signal handler) if count is 1 then raise SIGUSR2
230dc076565f772bb1953209fb69ea150b494aaa40robbiew  7. (child, signal handler) if count is 1 then set error variable
240dc076565f772bb1953209fb69ea150b494aaa40robbiew  8. (child) if error is set then return -1, else return 0
250dc076565f772bb1953209fb69ea150b494aaa40robbiew  6. (parent - returning from wait) If child returned 0 then exit 0,
260dc076565f772bb1953209fb69ea150b494aaa40robbiew     otherwise exit -1.
270dc076565f772bb1953209fb69ea150b494aaa40robbiew*/
280dc076565f772bb1953209fb69ea150b494aaa40robbiew
290dc076565f772bb1953209fb69ea150b494aaa40robbiew#define _XOPEN_SOURCE 600
300dc076565f772bb1953209fb69ea150b494aaa40robbiew
310dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <signal.h>
320dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <stdio.h>
330dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <stdlib.h>
340dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <sys/wait.h>
350dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <unistd.h>
360dc076565f772bb1953209fb69ea150b494aaa40robbiew#include "posixtest.h"
370dc076565f772bb1953209fb69ea150b494aaa40robbiew
380dc076565f772bb1953209fb69ea150b494aaa40robbiewint handler_count = 0;
390dc076565f772bb1953209fb69ea150b494aaa40robbiew
400dc076565f772bb1953209fb69ea150b494aaa40robbiewvoid handler(int signo)
410dc076565f772bb1953209fb69ea150b494aaa40robbiew{
420dc076565f772bb1953209fb69ea150b494aaa40robbiew	static int inside_handler = 0;
430dc076565f772bb1953209fb69ea150b494aaa40robbiew
44d3df7e05e9f72b583d8d7e95b26e1d0d77f7e323Garrett Cooper	printf("SIGUSR2 caught\n");
450dc076565f772bb1953209fb69ea150b494aaa40robbiew	if (inside_handler) {
460dc076565f772bb1953209fb69ea150b494aaa40robbiew		printf("Signal caught while inside handler\n");
470dc076565f772bb1953209fb69ea150b494aaa40robbiew		exit(0);
480dc076565f772bb1953209fb69ea150b494aaa40robbiew	}
490dc076565f772bb1953209fb69ea150b494aaa40robbiew
500dc076565f772bb1953209fb69ea150b494aaa40robbiew	inside_handler++;
510dc076565f772bb1953209fb69ea150b494aaa40robbiew	handler_count++;
520dc076565f772bb1953209fb69ea150b494aaa40robbiew
530dc076565f772bb1953209fb69ea150b494aaa40robbiew	if (handler_count == 1) {
54d3df7e05e9f72b583d8d7e95b26e1d0d77f7e323Garrett Cooper		printf("Raising SIGUSR2\n");
55d3df7e05e9f72b583d8d7e95b26e1d0d77f7e323Garrett Cooper		raise(SIGUSR2);
56d3df7e05e9f72b583d8d7e95b26e1d0d77f7e323Garrett Cooper		printf("Returning from raising SIGUSR2\n");
570dc076565f772bb1953209fb69ea150b494aaa40robbiew	}
580dc076565f772bb1953209fb69ea150b494aaa40robbiew
590dc076565f772bb1953209fb69ea150b494aaa40robbiew	inside_handler--;
600dc076565f772bb1953209fb69ea150b494aaa40robbiew}
610dc076565f772bb1953209fb69ea150b494aaa40robbiew
624ca2bbdcd3003f3c8df4e6129e9c7b2bd1514f87Cyril Hrubisint main(void)
630dc076565f772bb1953209fb69ea150b494aaa40robbiew{
640dc076565f772bb1953209fb69ea150b494aaa40robbiew	if (fork() == 0) {
650dc076565f772bb1953209fb69ea150b494aaa40robbiew		/* child */
660dc076565f772bb1953209fb69ea150b494aaa40robbiew
670dc076565f772bb1953209fb69ea150b494aaa40robbiew		struct sigaction act;
680dc076565f772bb1953209fb69ea150b494aaa40robbiew
690dc076565f772bb1953209fb69ea150b494aaa40robbiew		act.sa_handler = handler;
700dc076565f772bb1953209fb69ea150b494aaa40robbiew		act.sa_flags = SA_NODEFER;
710dc076565f772bb1953209fb69ea150b494aaa40robbiew		sigemptyset(&act.sa_mask);
72354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (sigaction(SIGUSR2, &act, 0) == -1) {
730dc076565f772bb1953209fb69ea150b494aaa40robbiew			perror("Unexpected error while attempting to "
740dc076565f772bb1953209fb69ea150b494aaa40robbiew			       "setup test pre-conditions");
750dc076565f772bb1953209fb69ea150b494aaa40robbiew			return PTS_UNRESOLVED;
760dc076565f772bb1953209fb69ea150b494aaa40robbiew		}
772c28215423293e443469a07ae7011135d058b671Garrett Cooper
78d3df7e05e9f72b583d8d7e95b26e1d0d77f7e323Garrett Cooper		if (raise(SIGUSR2) == -1) {
790dc076565f772bb1953209fb69ea150b494aaa40robbiew			perror("Unexpected error while attempting to "
800dc076565f772bb1953209fb69ea150b494aaa40robbiew			       "setup test pre-conditions");
810dc076565f772bb1953209fb69ea150b494aaa40robbiew			return PTS_UNRESOLVED;
820dc076565f772bb1953209fb69ea150b494aaa40robbiew		}
830dc076565f772bb1953209fb69ea150b494aaa40robbiew
840dc076565f772bb1953209fb69ea150b494aaa40robbiew		return PTS_FAIL;
850dc076565f772bb1953209fb69ea150b494aaa40robbiew	} else {
862c28215423293e443469a07ae7011135d058b671Garrett Cooper		int s;
870dc076565f772bb1953209fb69ea150b494aaa40robbiew
880dc076565f772bb1953209fb69ea150b494aaa40robbiew		/* parent */
890dc076565f772bb1953209fb69ea150b494aaa40robbiew		if (wait(&s) == -1) {
900dc076565f772bb1953209fb69ea150b494aaa40robbiew			perror("Unexpected error while setting up test "
910dc076565f772bb1953209fb69ea150b494aaa40robbiew			       "pre-conditions");
920dc076565f772bb1953209fb69ea150b494aaa40robbiew			return PTS_UNRESOLVED;
930dc076565f772bb1953209fb69ea150b494aaa40robbiew		}
940dc076565f772bb1953209fb69ea150b494aaa40robbiew
950dc076565f772bb1953209fb69ea150b494aaa40robbiew		if (!WEXITSTATUS(s)) {
960dc076565f772bb1953209fb69ea150b494aaa40robbiew			printf("Test PASSED\n");
970dc076565f772bb1953209fb69ea150b494aaa40robbiew			return PTS_PASS;
980dc076565f772bb1953209fb69ea150b494aaa40robbiew		}
990dc076565f772bb1953209fb69ea150b494aaa40robbiew	}
1000dc076565f772bb1953209fb69ea150b494aaa40robbiew
1010dc076565f772bb1953209fb69ea150b494aaa40robbiew	printf("Test FAILED\n");
1022c28215423293e443469a07ae7011135d058b671Garrett Cooper	return PTS_FAIL;
103d3df7e05e9f72b583d8d7e95b26e1d0d77f7e323Garrett Cooper}
104