summaryrefslogtreecommitdiff
path: root/src/regress/lib/libc/sys/t_pipe.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_pipe.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_pipe.c')
-rw-r--r--src/regress/lib/libc/sys/t_pipe.c168
1 files changed, 168 insertions, 0 deletions
diff --git a/src/regress/lib/libc/sys/t_pipe.c b/src/regress/lib/libc/sys/t_pipe.c
new file mode 100644
index 0000000000..bd9805a4b9
--- /dev/null
+++ b/src/regress/lib/libc/sys/t_pipe.c
@@ -0,0 +1,168 @@
1/* $OpenBSD: t_pipe.c,v 1.1.1.1 2019/11/19 19:57:04 bluhm Exp $ */
2/* $NetBSD: t_pipe.c,v 1.5 2017/01/13 21:30:41 christos Exp $ */
3
4/*-
5 * Copyright (c) 2001, 2008 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#include "macros.h"
31
32#include <sys/cdefs.h>
33#include <sys/cdefs.h>
34__COPYRIGHT("@(#) Copyright (c) 2008\
35 The NetBSD Foundation, inc. All rights reserved.");
36__RCSID("$NetBSD: t_pipe.c,v 1.5 2017/01/13 21:30:41 christos Exp $");
37
38#include <sys/types.h>
39#include <sys/wait.h>
40
41#include <errno.h>
42#include <fcntl.h>
43#include <poll.h>
44#include <sched.h>
45#include <signal.h>
46#include <stdio.h>
47#include <stdlib.h>
48#include <unistd.h>
49
50#include "atf-c.h"
51
52#include "h_macros.h"
53
54static pid_t pid;
55static int nsiginfo = 0;
56
57/*
58 * This is used for both parent and child. Handle parent's SIGALRM,
59 * the childs SIGINFO doesn't need anything.
60 */
61static void
62sighand(int sig)
63{
64 if (sig == SIGALRM) {
65 kill(pid, SIGINFO);
66 }
67 if (sig == SIGINFO) {
68 nsiginfo++;
69 }
70}
71
72ATF_TC(pipe_restart);
73ATF_TC_HEAD(pipe_restart, tc)
74{
75 atf_tc_set_md_var(tc, "descr", "Checks that writing to pipe "
76 "works correctly after being interrupted and restarted "
77 "(kern/14087)");
78}
79
80ATF_TC_BODY(pipe_restart, tc)
81{
82 int pp[2], st;
83 ssize_t sz, todo, done;
84 char *f;
85 sigset_t asigset, osigset, emptysigset;
86
87 /* Initialise signal masks */
88 RL(sigemptyset(&emptysigset));
89 RL(sigemptyset(&asigset));
90 RL(sigaddset(&asigset, SIGINFO));
91
92 /* Register signal handlers for both read and writer */
93 REQUIRE_LIBC(signal(SIGINFO, sighand), SIG_ERR);
94 REQUIRE_LIBC(signal(SIGALRM, sighand), SIG_ERR);
95
96 todo = 2 * 1024 * 1024;
97 REQUIRE_LIBC(f = malloc(todo), NULL);
98
99 RL(pipe(pp));
100
101 RL(pid = fork());
102 if (pid == 0) {
103 /* child */
104 RL(close(pp[1]));
105
106 /* Do inital write. This should succeed, make
107 * the other side do partial write and wait for us to pick
108 * rest up.
109 */
110 RL(done = read(pp[0], f, 128 * 1024));
111
112 /* Wait until parent is alarmed and awakens us */
113 RL(sigprocmask(SIG_BLOCK, &asigset, &osigset));
114 while (nsiginfo == 0) {
115 if (sigsuspend(&emptysigset) != -1 || errno != EINTR)
116 atf_tc_fail("sigsuspend(&emptysigset): %s",
117 strerror(errno));
118 }
119 RL(sigprocmask(SIG_SETMASK, &osigset, NULL));
120
121 /* Read all what parent wants to give us */
122 while((sz = read(pp[0], f, 1024 * 1024)) > 0)
123 done += sz;
124
125 /*
126 * Exit with 1 if number of bytes read doesn't match
127 * number of expected bytes
128 */
129 printf("Read: %#zx\n", (size_t)done);
130 printf("Expected: %#zx\n", (size_t)todo);
131
132 exit(done != todo);
133
134 /* NOTREACHED */
135 } else {
136 RL(close(pp[0]));
137
138 /*
139 * Arrange for alarm after two seconds. Since we have
140 * handler setup for SIGARLM, the write(2) call should
141 * be restarted internally by kernel.
142 */
143 (void)alarm(2);
144
145 /* We write exactly 'todo' bytes. The very first write(2)
146 * should partially succeed, block and eventually
147 * be restarted by kernel
148 */
149 while(todo > 0 && ((sz = write(pp[1], f, todo)) > 0))
150 todo -= sz;
151
152 /* Close the pipe, so that child would stop reading */
153 RL(close(pp[1]));
154
155 /* And pickup child's exit status */
156 RL(waitpid(pid, &st, 0));
157
158 ATF_REQUIRE_EQ(WEXITSTATUS(st), 0);
159 }
160 free(f);
161}
162
163ATF_TP_ADD_TCS(tp)
164{
165 ATF_TP_ADD_TC(tp, pipe_restart);
166
167 return atf_no_error();
168}