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
31 static void
signal_handler(int signum)32 signal_handler(int signum)
33 {
34 }
35
36 void
expect_signal_impl(int signum,const char * signame,const char * file,int line)37 expect_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
60 void
reject_signal_impl(int signum,const char * signame,const char * file,int line)61 reject_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
77 void
test_init(void)78 test_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
94 void
test_barrier(int sfd)95 test_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
103 int
test_fork(pid_t * ppid,int * psfd)104 test_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
125 int
test_wait(pid_t pid,int sfd)126 test_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