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 SIGTTOU 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
28volatile sig_atomic_t wakeup = 1;
29
30void handler(int signo)
31{
32	printf("Caught SIGTTOU\n");
33	wakeup++;
34}
35
36int 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(SIGTTOU, &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 SIGTTOU 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, SIGTTOU);
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