1 /*
2 
3  * Copyright (c) 2002-2003, Intel Corporation. All rights reserved.
4  * Created by:  rusty.lynch REMOVE-THIS AT intel DOT com
5  * This file is licensed under the GPL license.  For the full content
6  * of this license, see the COPYING file at the top level of this
7  * source tree.
8 
9   Test assertion #17 by verifying that select returns -1 with
10   errno set to EINTR if a handler for the SIGUSR1 signal is setup with
11   the SA_RESTART flag cleared.
12  * 12/18/02 - Adding in include of sys/time.h per
13  *            rodrigc REMOVE-THIS AT attbi DOT com input that it needs
14  *            to be included whenever the timeval struct is used.
15 */
16 
17 #include <signal.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <sys/select.h>
21 #include <sys/wait.h>
22 #include <sys/time.h>
23 #include <sys/types.h>
24 #include <unistd.h>
25 #include <errno.h>
26 #include "posixtest.h"
27 
28 volatile sig_atomic_t wakeup = 1;
29 
handler(int signo LTP_ATTRIBUTE_UNUSED)30 void handler(int signo LTP_ATTRIBUTE_UNUSED)
31 {
32 	printf("Caught SIGUSR1\n");
33 	wakeup++;
34 }
35 
main(void)36 int main(void)
37 {
38 	pid_t pid;
39 	struct timeval tv;
40 
41 	if ((pid = fork()) == 0) {
42 		/* child */
43 		struct sigaction act;
44 
45 		act.sa_handler = handler;
46 		act.sa_flags = 0;
47 		sigemptyset(&act.sa_mask);
48 		sigaction(SIGUSR1, &act, 0);
49 
50 		while (wakeup == 1) {
51 			tv.tv_sec = 3;
52 			tv.tv_usec = 0;
53 			if (select(0, NULL, NULL, NULL, &tv) == -1 &&
54 			    errno == EINTR) {
55 				perror("select");
56 				return PTS_PASS;
57 			}
58 		}
59 
60 		return PTS_FAIL;
61 	} else {
62 		/* parent */
63 		int s;
64 
65 		/*
66 		   There is a race condition between the parent
67 		   process sending the SIGUSR1 signal, and the
68 		   child process being inside the 'select' function
69 		   call.
70 
71 		   I could not find a pure POSIX method for determining
72 		   the state of the child process, so I just added a delay
73 		   so that the test is valid in most conditions.  (The
74 		   problem is that it would be perfectly legal for a
75 		   POSIX conformant OS to not schedule the child process
76 		   for a long time.)
77 		 */
78 		tv.tv_sec = 1;
79 		tv.tv_usec = 0;
80 		select(0, NULL, NULL, NULL, &tv);
81 
82 		kill(pid, SIGUSR1);
83 		waitpid(pid, &s, 0);
84 		if (WEXITSTATUS(s) == PTS_PASS) {
85 			printf("Test PASSED\n");
86 			return PTS_PASS;
87 		}
88 	}
89 
90 	printf("Test FAILED\n");
91 	return PTS_FAIL;
92 }
93