1/*	$OpenBSD: util.c,v 1.1 2020/09/16 14:02:23 mpi Exp $	*/
2
3/*
4 * Copyright (c) 2018 Visa Hankala
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include <sys/socket.h>
20#include <sys/wait.h>
21#include <assert.h>
22#include <errno.h>
23#include <poll.h>
24#include <signal.h>
25#include <stdio.h>
26#include <string.h>
27#include <unistd.h>
28
29#include "common.h"
30
31static void
32signal_handler(int signum)
33{
34}
35
36void
37expect_signal_impl(int signum, const char *signame, const char *file, int line)
38{
39	sigset_t sigmask;
40	struct timespec tmo;
41	int ret;
42
43	tmo.tv_sec = 5;
44	tmo.tv_nsec = 0;
45	sigprocmask(0, NULL, &sigmask);
46	sigdelset(&sigmask, signum);
47	ret = ppoll(NULL, 0, &tmo, &sigmask);
48	if (ret == 0) {
49		fprintf(stderr, "%s:%d: signal %s timeout\n",
50		    file, line, signame);
51		_exit(1);
52	}
53	if (ret != -1) {
54		fprintf(stderr, "%s: poll: unexpected return value: %d\n",
55		    __func__, ret);
56		_exit(1);
57	}
58}
59
60void
61reject_signal_impl(int signum, const char *signame, const char *file, int line)
62{
63	sigset_t sigmask;
64
65	if (sigpending(&sigmask) != 0) {
66		fprintf(stderr, "%s: sigpending: %s\n", __func__,
67		    strerror(errno));
68		_exit(1);
69	}
70	if (sigismember(&sigmask, signum)) {
71		fprintf(stderr, "%s:%d: signal %s not expected\n", file, line,
72		    signame);
73		_exit(1);
74	}
75}
76
77void
78test_init(void)
79{
80	sigset_t mask;
81
82	sigemptyset(&mask);
83	sigaddset(&mask, SIGCHLD);
84	sigaddset(&mask, SIGIO);
85	sigaddset(&mask, SIGURG);
86	sigprocmask(SIG_BLOCK, &mask, NULL);
87	signal(SIGCHLD, signal_handler);
88	signal(SIGIO, signal_handler);
89	signal(SIGURG, signal_handler);
90
91	alarm(10);
92}
93
94void
95test_barrier(int sfd)
96{
97	char b = 0;
98
99	assert(write(sfd, &b, 1) == 1);
100	assert(read(sfd, &b, 1) == 1);
101}
102
103int
104test_fork(pid_t *ppid, int *psfd)
105{
106	pid_t pid;
107	int fds[2];
108
109	assert(socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == 0);
110
111	pid = fork();
112	assert(pid != -1);
113	*ppid = pid;
114	if (pid == 0) {
115		close(fds[0]);
116		*psfd = fds[1];
117		return CHILD;
118	} else {
119		close(fds[1]);
120		*psfd = fds[0];
121		return PARENT;
122	}
123}
124
125int
126test_wait(pid_t pid, int sfd)
127{
128	int status;
129
130	close(sfd);
131	if (pid == 0)
132		_exit(0);
133	assert(waitpid(pid, &status, 0) == pid);
134	return 0;
135}
136