summaryrefslogtreecommitdiff
path: root/src/regress/lib/libc/sys/t_mkfifo.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_mkfifo.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_mkfifo.c')
-rw-r--r--src/regress/lib/libc/sys/t_mkfifo.c309
1 files changed, 309 insertions, 0 deletions
diff --git a/src/regress/lib/libc/sys/t_mkfifo.c b/src/regress/lib/libc/sys/t_mkfifo.c
new file mode 100644
index 0000000000..1c2fe60e3a
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_mkfifo.c
@@ -0,0 +1,309 @@
1/* $OpenBSD: t_mkfifo.c,v 1.1.1.1 2019/11/19 19:57:03 bluhm Exp $ */
2/* $NetBSD: t_mkfifo.c,v 1.3 2019/06/20 03:31:54 kamil 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 Foundation
9 * by Jukka Ruohonen.
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 <sys/cdefs.h>
36__RCSID("$NetBSD: t_mkfifo.c,v 1.3 2019/06/20 03:31:54 kamil Exp $");
37
38#include <sys/stat.h>
39#include <sys/wait.h>
40
41#include "atf-c.h"
42#include <errno.h>
43#include <fcntl.h>
44#include <limits.h>
45#include <stdlib.h>
46#include <signal.h>
47#include <string.h>
48#include <unistd.h>
49
50static const char path[] = "fifo";
51static void support(void);
52
53static void
54support(void)
55{
56
57 errno = 0;
58
59 if (mkfifo(path, 0600) == 0) {
60 ATF_REQUIRE(unlink(path) == 0);
61 return;
62 }
63
64 if (errno == EOPNOTSUPP)
65 atf_tc_skip("the kernel does not support FIFOs");
66 else {
67 atf_tc_fail("mkfifo(2) failed");
68 }
69}
70
71ATF_TC_WITH_CLEANUP(mkfifo_block);
72ATF_TC_HEAD(mkfifo_block, tc)
73{
74 atf_tc_set_md_var(tc, "descr", "Test that FIFOs block");
75}
76
77ATF_TC_BODY(mkfifo_block, tc)
78{
79 int sta, fd = -1;
80 pid_t pid;
81
82 support();
83
84 ATF_REQUIRE(mkfifo(path, 0600) == 0);
85
86 pid = fork();
87 ATF_REQUIRE(pid >= 0);
88
89 if (pid == 0) {
90
91 /*
92 * If we open the FIFO as read-only (write-only),
93 * the call should block until another process
94 * opens the FIFO for writing (reading).
95 */
96 fd = open(path, O_RDONLY);
97
98 _exit(EXIT_FAILURE); /* NOTREACHED */
99 }
100
101 (void)sleep(1);
102
103 ATF_REQUIRE(kill(pid, SIGKILL) == 0);
104
105 (void)wait(&sta);
106
107 if (WIFSIGNALED(sta) == 0 || WTERMSIG(sta) != SIGKILL)
108 atf_tc_fail("FIFO did not block");
109
110 (void)close(fd);
111 (void)unlink(path);
112}
113
114ATF_TC_CLEANUP(mkfifo_block, tc)
115{
116 (void)unlink(path);
117}
118
119ATF_TC_WITH_CLEANUP(mkfifo_err);
120ATF_TC_HEAD(mkfifo_err, tc)
121{
122 atf_tc_set_md_var(tc, "descr", "Test erros from mkfifo(2)");
123}
124
125ATF_TC_BODY(mkfifo_err, tc)
126{
127 char buf[PATH_MAX + 1];
128
129 support();
130
131 (void)memset(buf, 'x', sizeof(buf));
132 ATF_REQUIRE(mkfifo(path, 0600) == 0);
133
134 errno = 0;
135 ATF_REQUIRE_ERRNO(EFAULT, mkfifo((char *)-1, 0600) == -1);
136
137 errno = 0;
138 ATF_REQUIRE_ERRNO(EEXIST, mkfifo("/etc/passwd", 0600) == -1);
139
140 errno = 0;
141 ATF_REQUIRE_ERRNO(EEXIST, mkfifo(path, 0600) == -1);
142
143 errno = 0;
144 ATF_REQUIRE_ERRNO(ENAMETOOLONG, mkfifo(buf, 0600) == -1);
145
146 errno = 0;
147 ATF_REQUIRE_ERRNO(ENOENT, mkfifo("/a/b/c/d/e/f/g", 0600) == -1);
148
149 ATF_REQUIRE(unlink(path) == 0);
150}
151
152ATF_TC_CLEANUP(mkfifo_err, tc)
153{
154 (void)unlink(path);
155}
156
157ATF_TC_WITH_CLEANUP(mkfifo_nonblock);
158ATF_TC_HEAD(mkfifo_nonblock, tc)
159{
160 atf_tc_set_md_var(tc, "descr", "Test O_NONBLOCK with FIFOs");
161}
162
163ATF_TC_BODY(mkfifo_nonblock, tc)
164{
165 int fd, sta;
166 pid_t pid;
167
168 support();
169
170 fd = -1;
171 ATF_REQUIRE(mkfifo(path, 0600) == 0);
172
173 pid = fork();
174 ATF_REQUIRE(pid >= 0);
175
176 if (pid == 0) {
177
178 /*
179 * If we open the FIFO as O_NONBLOCK, the O_RDONLY
180 * call should return immediately, whereas the call
181 * for write-only should fail with ENXIO.
182 */
183 fd = open(path, O_RDONLY | O_NONBLOCK);
184
185 if (fd >= 0)
186 _exit(EXIT_SUCCESS);
187
188 (void)pause(); /* NOTREACHED */
189 }
190
191 (void)sleep(1);
192
193 errno = 0;
194 ATF_REQUIRE_ERRNO(ENXIO, open(path, O_WRONLY | O_NONBLOCK) == -1);
195
196 (void)kill(pid, SIGKILL);
197 (void)wait(&sta);
198
199 if (WIFSIGNALED(sta) != 0 || WTERMSIG(sta) == SIGKILL)
200 atf_tc_fail("FIFO blocked for O_NONBLOCK open(2)");
201
202 (void)close(fd);
203 (void)unlink(path);
204}
205
206ATF_TC_CLEANUP(mkfifo_nonblock, tc)
207{
208 (void)unlink(path);
209}
210
211ATF_TC_WITH_CLEANUP(mkfifo_perm);
212ATF_TC_HEAD(mkfifo_perm, tc)
213{
214 atf_tc_set_md_var(tc, "descr", "Test permissions with mkfifo(2)");
215 atf_tc_set_md_var(tc, "require.user", "unprivileged");
216}
217
218ATF_TC_BODY(mkfifo_perm, tc)
219{
220
221 support();
222
223 errno = 0;
224 ATF_REQUIRE_ERRNO(EACCES, mkfifo("/root/fifo", 0600) == -1);
225
226 ATF_REQUIRE(mkfifo(path, 0600) == 0);
227
228 /*
229 * For some reason this fails with EFTYPE...
230 */
231 errno = 0;
232 ATF_REQUIRE_ERRNO(EFTYPE, chmod(path, 1777) == -1);
233
234 ATF_REQUIRE(unlink(path) == 0);
235}
236
237ATF_TC_CLEANUP(mkfifo_perm, tc)
238{
239 (void)unlink(path);
240}
241
242ATF_TC_WITH_CLEANUP(mkfifo_stat);
243ATF_TC_HEAD(mkfifo_stat, tc)
244{
245 atf_tc_set_md_var(tc, "descr", "Test mkfifo(2) with stat");
246}
247
248ATF_TC_BODY(mkfifo_stat, tc)
249{
250 struct stat st;
251
252 support();
253
254 (void)memset(&st, 0, sizeof(struct stat));
255
256 ATF_REQUIRE(mkfifo(path, 0600) == 0);
257 ATF_REQUIRE(stat(path, &st) == 0);
258
259 if (S_ISFIFO(st.st_mode) == 0)
260 atf_tc_fail("invalid mode from mkfifo(2)");
261
262 ATF_REQUIRE(unlink(path) == 0);
263}
264
265ATF_TC_CLEANUP(mkfifo_stat, tc)
266{
267 (void)unlink(path);
268}
269
270ATF_TC_WITH_CLEANUP(mknod_s_ififo);
271ATF_TC_HEAD(mknod_s_ififo, tc)
272{
273 atf_tc_set_md_var(tc, "descr", "Test mknod(2) with S_IFIFO");
274}
275
276ATF_TC_BODY(mknod_s_ififo, tc)
277{
278 struct stat st;
279
280 support();
281
282 (void)memset(&st, 0, sizeof(struct stat));
283
284 ATF_REQUIRE(mknod(path, S_IFIFO | 0600, 0) == 0);
285 ATF_REQUIRE(stat(path, &st) == 0);
286
287 if (S_ISFIFO(st.st_mode) == 0)
288 atf_tc_fail("invalid mode from mknod(2) with S_IFIFO");
289
290 ATF_REQUIRE(unlink(path) == 0);
291}
292
293ATF_TC_CLEANUP(mknod_s_ififo, tc)
294{
295 (void)unlink(path);
296}
297
298ATF_TP_ADD_TCS(tp)
299{
300
301 ATF_TP_ADD_TC(tp, mkfifo_block);
302 ATF_TP_ADD_TC(tp, mkfifo_err);
303 ATF_TP_ADD_TC(tp, mkfifo_nonblock);
304 ATF_TP_ADD_TC(tp, mkfifo_perm);
305 ATF_TP_ADD_TC(tp, mkfifo_stat);
306 ATF_TP_ADD_TC(tp, mknod_s_ififo);
307
308 return atf_no_error();
309}