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