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 SIGSEGV 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)30 void handler(int signo)
31 {
32 printf("Caught SIGSEGV\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(SIGSEGV, &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 SIGSEGV 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, SIGSEGV);
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