1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <stdio.h>
2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <unistd.h>
3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <signal.h>
4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <errno.h>
5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <sys/wait.h>
6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <string.h>
7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Make sure that a blocking syscall returns EINTR if hit by a signal,
9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   and there's no SA_RESTART */
10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void handler(int s)
12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint main()
16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	int pid;
18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	int fds[2];
19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	if (pipe(fds) == -1) {
21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		perror("FAIL: pipe\n");
22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		return 1;
23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	pid = fork();
26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	if (pid == -1) {
28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		perror("fork failed");
29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		return 1;
30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	if (pid == 0) {
33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		char ch = '?';
34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		int ret;
35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		struct sigaction sa;
36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		sa.sa_handler = handler;
38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		sigfillset(&sa.sa_mask);
39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		sa.sa_flags = 0; /* no SA_RESTART */
40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		sigaction(SIGUSR1, &sa, NULL);
42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		close(fds[1]);
44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		ret = read(fds[0], &ch, 1);
45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		if (ret != -1 || errno != EINTR)
47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			fprintf(stderr, "FAIL: expected EINTR, not %d/%s/%c\n",
48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown				ret, strerror(errno), ch);
49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	} else {
50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		signal(SIGPIPE, SIG_IGN);
51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		close(fds[0]);
53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		sleep(1);
54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		kill(pid, SIGUSR1);
55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		sleep(1);
56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		if (write(fds[1], "x", 1) != -1 || errno != EPIPE)
57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown			fprintf(stderr, "FAIL: expected write to fail with EPIPE, not %d\n", errno);
58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		waitpid(pid, NULL, 0);
60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	return 0;
63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
64