Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
script3r
GitHub Repository: script3r/os161
Path: blob/master/user/testbin/badcall/bad_waitpid.c
734 views
1
/*
2
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
3
* The President and Fellows of Harvard College.
4
*
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions
7
* are met:
8
* 1. Redistributions of source code must retain the above copyright
9
* notice, this list of conditions and the following disclaimer.
10
* 2. Redistributions in binary form must reproduce the above copyright
11
* notice, this list of conditions and the following disclaimer in the
12
* documentation and/or other materials provided with the distribution.
13
* 3. Neither the name of the University nor the names of its contributors
14
* may be used to endorse or promote products derived from this software
15
* without specific prior written permission.
16
*
17
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
18
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
21
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27
* SUCH DAMAGE.
28
*/
29
30
/*
31
* bad calls to waitpid()
32
*/
33
34
#include <sys/types.h>
35
#include <stdlib.h>
36
#include <unistd.h>
37
#include <errno.h>
38
#include <err.h>
39
40
#include "config.h"
41
#include "test.h"
42
43
static
44
void
45
wait_badpid(int pid, const char *desc)
46
{
47
int rv, x;
48
rv = waitpid(pid, &x, 0);
49
report_test2(rv, errno, EINVAL, NOSUCHPID_ERROR, desc);
50
}
51
52
static
53
void
54
wait_badstatus(void *ptr, const char *desc)
55
{
56
int rv, pid, x;
57
58
pid = fork();
59
if (pid<0) {
60
warn("UH-OH: fork failed");
61
return;
62
}
63
if (pid==0) {
64
exit(0);
65
}
66
67
rv = waitpid(pid, ptr, 0);
68
report_test(rv, errno, EFAULT, desc);
69
waitpid(pid, &x, 0);
70
}
71
72
static
73
void
74
wait_unaligned(void)
75
{
76
int rv, pid, x;
77
int status[2]; /* will have integer alignment */
78
char *ptr;
79
80
pid = fork();
81
if (pid<0) {
82
warn("UH-OH: fork failed");
83
return;
84
}
85
if (pid==0) {
86
exit(0);
87
}
88
89
/* start with proper integer alignment */
90
ptr = (char *)(&status[0]);
91
92
/* generate improper alignment on platforms with restrictions*/
93
ptr++;
94
95
rv = waitpid(pid, (int *)ptr, 0);
96
report_survival(rv, errno, "wait with unaligned status");
97
if (rv<0) {
98
waitpid(pid, &x, 0);
99
}
100
}
101
102
static
103
void
104
wait_badflags(void)
105
{
106
int rv, x, pid;
107
108
pid = fork();
109
if (pid<0) {
110
warn("UH-OH: fork failed");
111
return;
112
}
113
if (pid==0) {
114
exit(0);
115
}
116
117
rv = waitpid(pid, &x, 309429);
118
report_test(rv, errno, EINVAL, "wait with bad flags");
119
waitpid(pid, &x, 0);
120
}
121
122
static
123
void
124
wait_self(void)
125
{
126
int rv, x;
127
rv = waitpid(getpid(), &x, 0);
128
report_survival(rv, errno, "wait for self");
129
}
130
131
static
132
void
133
wait_parent(void)
134
{
135
int mypid, childpid, rv, x;
136
137
mypid = getpid();
138
childpid = fork();
139
if (childpid<0) {
140
warn("UH-OH: can't fork");
141
return;
142
}
143
if (childpid==0) {
144
/* Child. Wait for parent. */
145
rv = waitpid(mypid, &x, 0);
146
report_survival(rv, errno, "wait for parent (from child)");
147
_exit(0);
148
}
149
rv = waitpid(childpid, &x, 0);
150
report_survival(rv, errno, "wait for parent test (from parent)");
151
}
152
153
////////////////////////////////////////////////////////////
154
155
static
156
void
157
wait_siblings_child(void)
158
{
159
int pids[2], mypid, otherpid, fd, rv, x;
160
161
mypid = getpid();
162
163
fd = open(TESTFILE, O_RDONLY);
164
if (fd<0) {
165
warn("UH-OH: child process (pid %d) can't open %s",
166
mypid, TESTFILE);
167
return;
168
}
169
170
/*
171
* Busy-wait until the parent writes the pids into the file.
172
* This sucks, but there's not a whole lot else we can do.
173
*/
174
do {
175
rv = lseek(fd, 0, SEEK_SET);
176
if (rv<0) {
177
warn("UH-OH: child process (pid %d) lseek error",
178
mypid);
179
return;
180
}
181
rv = read(fd, pids, sizeof(pids));
182
if (rv<0) {
183
warn("UH-OH: child process (pid %d) read error",
184
mypid);
185
return;
186
}
187
} while (rv < (int)sizeof(pids));
188
189
if (mypid==pids[0]) {
190
otherpid = pids[1];
191
}
192
else if (mypid==pids[1]) {
193
otherpid = pids[0];
194
}
195
else {
196
warn("UH-OH: child process (pid %d) got garbage in comm file",
197
mypid);
198
return;
199
}
200
close(fd);
201
202
rv = waitpid(otherpid, &x, 0);
203
report_survival(rv, errno, "sibling wait");
204
}
205
206
static
207
void
208
wait_siblings(void)
209
{
210
int pids[2], fd, rv, x;
211
212
/* Note: this may also blow up if FS synchronization is substandard */
213
214
fd = open_testfile(NULL);
215
if (fd<0) {
216
return;
217
}
218
219
pids[0] = fork();
220
if (pids[0]<0) {
221
warn("UH-OH: can't fork");
222
return;
223
}
224
if (pids[0]==0) {
225
close(fd);
226
wait_siblings_child();
227
_exit(0);
228
}
229
230
pids[1] = fork();
231
if (pids[1]<0) {
232
warn("UH-OH: can't fork");
233
/* abandon the other child process :( */
234
return;
235
}
236
if (pids[1]==0) {
237
close(fd);
238
wait_siblings_child();
239
_exit(0);
240
}
241
242
rv = write(fd, pids, sizeof(pids));
243
if (rv < 0) {
244
warn("UH-OH: write error on %s", TESTFILE);
245
/* abandon child procs :( */
246
return;
247
}
248
if (rv != (int)sizeof(pids)) {
249
warnx("UH-OH: write error on %s: short count", TESTFILE);
250
/* abandon child procs :( */
251
return;
252
}
253
254
rv = waitpid(pids[0], &x, 0);
255
if (rv<0) {
256
warn("UH-OH: error waiting for child 0 (pid %d)", pids[0]);
257
}
258
rv = waitpid(pids[1], &x, 0);
259
if (rv<0) {
260
warn("UH-OH: error waiting for child 1 (pid %d)", pids[1]);
261
}
262
warnx("passed: siblings wait for each other");
263
close(fd);
264
remove(TESTFILE);
265
}
266
267
////////////////////////////////////////////////////////////
268
269
void
270
test_waitpid(void)
271
{
272
wait_badpid(-8, "wait for pid -8");
273
wait_badpid(-1, "wait for pid -1");
274
wait_badpid(0, "pid zero");
275
wait_badpid(NONEXIST_PID, "nonexistent pid");
276
277
wait_badstatus(NULL, "wait with NULL status");
278
wait_badstatus(INVAL_PTR, "wait with invalid pointer status");
279
wait_badstatus(KERN_PTR, "wait with kernel pointer status");
280
281
wait_unaligned();
282
283
wait_badflags();
284
285
wait_self();
286
wait_parent();
287
wait_siblings();
288
}
289
290