aboutsummaryrefslogtreecommitdiff
path: root/testcases/open_posix_testsuite/conformance/interfaces/sigaction/17-10.c
blob: 68b21e92f58ce03b2f003eb0f70570fb4cf53aef (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
/*

 * Copyright (c) 2002-2003, Intel Corporation. All rights reserved.
 * Created by:  rusty.lynch REMOVE-THIS AT intel DOT com
 * This file is licensed under the GPL license.  For the full content
 * of this license, see the COPYING file at the top level of this
 * source tree.

  Test assertion #17 by verifying that select returns -1 with
  errno set to EINTR if a handler for the SIGPIPE signal is setup with
  the SA_RESTART flag cleared.
 * 12/18/02 - Adding in include of sys/time.h per
 *            rodrigc REMOVE-THIS AT attbi DOT com input that it needs
 *            to be included whenever the timeval struct is used.
*/

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/select.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include "posixtest.h"

static volatile sig_atomic_t wakeup = 1;

static void handler(int signo PTS_ATTRIBUTE_UNUSED)
{
	printf("Caught SIGPIPE\n");
	wakeup++;
}

int main(void)
{
	pid_t pid;
	struct timeval tv;

	if ((pid = fork()) == 0) {
		/* child */
		struct sigaction act;

		act.sa_handler = handler;
		act.sa_flags = 0;
		sigemptyset(&act.sa_mask);
		sigaction(SIGPIPE, &act, 0);

		while (wakeup == 1) {
			tv.tv_sec = 3;
			tv.tv_usec = 0;
			if (select(0, NULL, NULL, NULL, &tv) == -1 &&
			    errno == EINTR) {
				perror("select");
				return PTS_PASS;
			}
		}

		return PTS_FAIL;
	} else {
		/* parent */
		int s;

		/*
		   There is a race condition between the parent
		   process sending the SIGPIPE signal, and the
		   child process being inside the 'select' function
		   call.

		   I could not find a pure POSIX method for determining
		   the state of the child process, so I just added a delay
		   so that the test is valid in most conditions.  (The
		   problem is that it would be perfectly legal for a
		   POSIX conformant OS to not schedule the child process
		   for a long time.)
		 */
		tv.tv_sec = 1;
		tv.tv_usec = 0;
		select(0, NULL, NULL, NULL, &tv);

		kill(pid, SIGPIPE);
		waitpid(pid, &s, 0);
		if (WEXITSTATUS(s) == PTS_PASS) {
			printf("Test PASSED\n");
			return PTS_PASS;
		}
	}

	printf("Test FAILED\n");
	return PTS_FAIL;
}