summaryrefslogtreecommitdiff
path: root/src/regress/lib/libc/sys/t_select.c
diff options
context:
space:
mode:
authorbluhm <>2019-11-19 19:57:04 +0000
committerbluhm <>2019-11-19 19:57:04 +0000
commit9185f840eda265016178aeb0dcdba964f8f6f3e2 (patch)
treeda100b3712514c566fe948116f7926ad7f725401 /src/regress/lib/libc/sys/t_select.c
parent6a6fe688152b422f3d65c970dad56e7d9d28b1ee (diff)
downloadopenbsd-9185f840eda265016178aeb0dcdba964f8f6f3e2.tar.gz
openbsd-9185f840eda265016178aeb0dcdba964f8f6f3e2.tar.bz2
openbsd-9185f840eda265016178aeb0dcdba964f8f6f3e2.zip
Import NetBSD system call regression tests. They were written with
ATF (Automated Testing Framework), so we use a small wrapper to map it to our bsd.regress.mk framework. Only half of the 80 NetBSD tests have been taken, the others need more work to adapt. Of them 34 syscall tests pass. Moritz Buhl ported the tests to OpenBSD.
Diffstat (limited to 'src/regress/lib/libc/sys/t_select.c')
-rw-r--r--src/regress/lib/libc/sys/t_select.c219
1 files changed, 219 insertions, 0 deletions
diff --git a/src/regress/lib/libc/sys/t_select.c b/src/regress/lib/libc/sys/t_select.c
new file mode 100644
index 0000000000..94ff3d3410
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_select.c
@@ -0,0 +1,219 @@
1/* $OpenBSD: t_select.c,v 1.1.1.1 2019/11/19 19:57:04 bluhm Exp $ */
2/* $NetBSD: t_select.c,v 1.4 2017/01/13 21:18:33 christos Exp $ */
3
4/*-
5 * Copyright (c) 2011 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundatiom
9 * by Christos Zoulas.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include "macros.h"
34
35#include <assert.h>
36#include <sys/types.h>
37#include <sys/select.h>
38#include <sys/wait.h>
39#include <err.h>
40#include <stdio.h>
41#include <string.h>
42#include <signal.h>
43#include <stdlib.h>
44#include <unistd.h>
45#include <errno.h>
46#include <fcntl.h>
47
48#include "atf-c.h"
49
50static sig_atomic_t keep_going = 1;
51
52static void
53sig_handler(int signum __unused)
54{
55 keep_going = 0;
56}
57
58static void
59sigchld(int signum __unused)
60{
61}
62
63static char
64xtoa(uint8_t n)
65{
66 static const char xarray[] = "0123456789abcdef";
67 assert(n < sizeof(xarray));
68 return xarray[n];
69}
70
71static const char *
72prmask(const sigset_t *m, char *buf, size_t len)
73{
74 size_t j = 2;
75 assert(len >= 3 + sizeof(*m));
76 buf[0] = '0';
77 buf[1] = 'x';
78#define N(p, a) (((p) >> ((a) * 4)) & 0xf)
79 /* Adjusted for OpenBSD, on NetBSD sigset_t is a struct */
80 uint32_t p = (*m);
81 for (size_t k = sizeof(p); k > 0; k--)
82 buf[j++] = xtoa(N(p, k - 1));
83 buf[j] = '\0';
84 return buf;
85}
86
87static __dead void
88child(const struct timespec *ts)
89{
90 struct sigaction sa;
91 sigset_t set, oset, nset;
92 char obuf[sizeof(oset) + 3], nbuf[sizeof(nset) + 3];
93 int fd;
94
95 memset(&sa, 0, sizeof(sa));
96 sa.sa_handler = sig_handler;
97 if ((fd = open("/dev/null", O_RDONLY)) == -1)
98 err(1, "open");
99
100 if (sigaction(SIGTERM, &sa, NULL) == -1)
101 err(1, "sigaction");
102
103 sigfillset(&set);
104 if (sigprocmask(SIG_BLOCK, &set, NULL) == -1)
105 err(1, "sigprocmask");
106
107 if (sigprocmask(SIG_BLOCK, NULL, &oset) == -1)
108 err(1, "sigprocmask");
109
110 sigemptyset(&set);
111
112 for (;;) {
113 fd_set rset;
114 FD_ZERO(&rset);
115 FD_SET(fd, &rset);
116 if (pselect(1, &rset, NULL, NULL, ts, &set) == -1) {
117 if(errno == EINTR) {
118 if (!keep_going)
119 break;
120 }
121 }
122 if (ts)
123 break;
124 }
125 if (sigprocmask(SIG_BLOCK, NULL, &nset) == -1)
126 err(1, "sigprocmask");
127 if (memcmp(&oset, &nset, sizeof(oset)) != 0)
128 atf_tc_fail("pselect() masks don't match "
129 "after timeout %s != %s",
130 prmask(&nset, nbuf, sizeof(nbuf)),
131 prmask(&oset, obuf, sizeof(obuf)));
132 _exit(0);
133}
134
135ATF_TC(pselect_sigmask);
136ATF_TC_HEAD(pselect_sigmask, tc)
137{
138 atf_tc_set_md_var(tc, "descr", "Checks pselect's temporary mask "
139 "setting when a signal is received (PR lib/43625)");
140}
141
142ATF_TC_BODY(pselect_sigmask, tc)
143{
144 pid_t pid;
145 int status;
146
147 signal(SIGCHLD, sigchld);
148
149 switch (pid = fork()) {
150 case 0:
151 child(NULL);
152 /*NOTREACHED*/
153 case -1:
154 err(1, "fork");
155 default:
156 sleep(1);
157 if (kill(pid, SIGTERM) == -1)
158 err(1, "kill");
159 sleep(1);
160 switch (waitpid(pid, &status, WNOHANG)) {
161 case -1:
162 err(1, "wait");
163 case 0:
164 if (kill(pid, SIGKILL) == -1)
165 err(1, "kill");
166 atf_tc_fail("pselect() did not receive signal");
167 break;
168 default:
169 break;
170 }
171 }
172}
173
174ATF_TC(pselect_timeout);
175ATF_TC_HEAD(pselect_timeout, tc)
176{
177
178 atf_tc_set_md_var(tc, "descr", "Checks pselect's temporary mask "
179 "setting when a timeout occurs");
180}
181
182ATF_TC_BODY(pselect_timeout, tc)
183{
184 pid_t pid;
185 int status;
186 static const struct timespec zero = { 0, 0 };
187
188 signal(SIGCHLD, sigchld);
189
190 switch (pid = fork()) {
191 case 0:
192 child(&zero);
193 break;
194 case -1:
195 err(1, "fork");
196 default:
197 sleep(1);
198 switch (waitpid(pid, &status, WNOHANG)) {
199 case -1:
200 err(1, "wait");
201 case 0:
202 if (kill(pid, SIGKILL) == -1)
203 err(1, "kill");
204 atf_tc_fail("pselect() did not receive signal");
205 break;
206 default:
207 break;
208 }
209 }
210}
211
212ATF_TP_ADD_TCS(tp)
213{
214
215 ATF_TP_ADD_TC(tp, pselect_sigmask);
216 ATF_TP_ADD_TC(tp, pselect_timeout);
217
218 return atf_no_error();
219}