blob: 8d8e50dbdb869829cda0eae2cff0c2f5f30814f2 [file] [log] [blame]
plars865695b2001-08-27 22:15:12 +00001/*
2 *
3 * Copyright (c) International Business Machines Corp., 2001
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
13 * the GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20/*
21 * NAME
nstrazfa31d552002-05-14 16:50:06 +000022 * fcntl14.c
plars865695b2001-08-27 22:15:12 +000023 *
24 * DESCRIPTION
25 * File locking test cases for fcntl. In Linux, S_ENFMT is not implemented
26 * in the kernel. However all standard Unix kernels define S_ENFMT as
27 * S_ISGID. So this test defines S_ENFMT as S_ISGID.
28 *
29 * ALGORITHM
30 * Various test cases are used to lock a file opened without mandatory
31 * locking, with mandatory locking and mandatory locking with NOBLOCK
32 *
33 * USAGE
nstrazfa31d552002-05-14 16:50:06 +000034 * fcntl14
plars865695b2001-08-27 22:15:12 +000035 *
36 * HISTORY
37 * 07/2001 Ported by Wayne Boyer
38 *
39 * RESTRICTIONS
40 * None
41 */
robbiew4cf80962003-03-25 21:53:41 +000042#define _GNU_SOURCE 1
plars865695b2001-08-27 22:15:12 +000043#include <fcntl.h>
44#include <sys/types.h>
45#include <sys/stat.h>
46#include <signal.h>
47#include <errno.h>
mridgedb639212005-01-04 21:04:11 +000048#include <sys/wait.h>
plars865695b2001-08-27 22:15:12 +000049#include <usctest.h>
50#include <test.h>
51
mridgedb639212005-01-04 21:04:11 +000052#define SKIP 0x0c00
53#if SKIP == F_RDLCK || SKIP== F_WRLCK
54#error invalid value for SKIP, must be distinct from F_RDLCK and F_WRLCK
55#endif
56#ifndef S_ENFMT
plars865695b2001-08-27 22:15:12 +000057#define S_ENFMT S_ISGID
mridgedb639212005-01-04 21:04:11 +000058#endif
plars865695b2001-08-27 22:15:12 +000059
60/* NOBLOCK - immediate success */
61#define NOBLOCK 2
62
63/* WILLBLOCK - blocks, then succeeds (parent must unlock records) */
64#define WILLBLOCK 3
65
66#define TIME_OUT 60
67
68typedef struct {
69 short a_type;
70 short a_whence;
71 long a_start;
72 long a_len;
mridgedb639212005-01-04 21:04:11 +000073 short b_type; /* SKIP means suppress fcntl call */
plars865695b2001-08-27 22:15:12 +000074 short b_whence;
75 long b_start;
76 long b_len;
77 short c_type;
subrata_modakb370c3c2007-11-25 16:37:35 +000078 int c_whence;
plars865695b2001-08-27 22:15:12 +000079 long c_start;
80 long c_len;
81 short c_flag;
82} testcase;
83
84static testcase testcases[] = {
85 /* Test cases: entire boundary */
86 /* #1 Parent making a write lock on entire file */
87 { F_WRLCK, 0, 0L, 0L, SKIP, 0, 0L, 0L,
88 /* Child attempting a read lock on entire file */
89 F_RDLCK, 0, 0L, 0L, WILLBLOCK },
90
91 /* #2 Parent making a write lock on entire file */
92 { F_WRLCK, 0, 0L, 0L, SKIP, 0, 0L, 0L,
93 /* Child attempting a write lock on entire file */
94 F_WRLCK, 0, 0L, 0L, WILLBLOCK },
95
96 /* #3 Parent making a read lock on entire file */
97 { F_RDLCK, 0, 0L, 0L, SKIP, 0, 0L, 0L,
98 /* Child attempting a read lock on entire file */
99 F_RDLCK, 0, 0L, 0L, NOBLOCK },
100
101 /* #4 Parent making a read lock on entire file */
102 { F_RDLCK, 0, 0L, 0L, SKIP, 0, 0L, 0L,
103 /* Child attempting a write lock on entire file */
104 F_WRLCK, 0, 0L, 0L, WILLBLOCK },
105
106 /* Test case: start boundary */
107 /* #5 Parent making a write lock on entire file */
108 { F_WRLCK, 0, 0L, 0L, SKIP, 0, 0L, 0L,
109 /*
110 * Child attempting a read lock from beginning of
111 * file for 5 bytes
112 */
113 F_RDLCK, 0, 0L, 5L, WILLBLOCK },
114
115 /* #6 Parent making a write lock on entire file */
116 { F_WRLCK, 0, 0L, 0L, SKIP, 0, 0L, 0L,
117 /*
118 * Child attempting a write lock from beginning of
119 * file for 5 bytes
120 */
121 F_WRLCK, 0, 0L, 5L, WILLBLOCK },
122
123 /* #7 Parent making a read lock on entire file */
124 { F_RDLCK, 0, 0L, 0L, SKIP, 0, 0L, 0L,
125 /*
126 * Child attempting a read lock from beginning of
127 * file for 5 bytes
128 */
129 F_RDLCK, 0, 0L, 5L, NOBLOCK },
130
131 /* #8 Parent making a read lock on entire file */
132 { F_RDLCK, 0, 0L, 0L, SKIP, 0, 0L, 0L,
133 /*
134 * Child attempting a write lock from beginning of
135 * file for 5 bytes
136 */
137 F_WRLCK, 0, 0L, 5L, WILLBLOCK },
138
139 /* Test cases: end boundary */
140 /* #9 Parent making a write lock on entire file */
141 { F_WRLCK, 0, 0L, 0L, SKIP, 0, 0L, 0L,
142 /* Child attempting a read lock from byte 7 to end of file */
143 F_RDLCK, 0, 7L, 0L, WILLBLOCK },
144
145 /* #10 Parent making a write lock on entire file */
146 { F_WRLCK, 0, 0L, 0L, SKIP, 0, 0L, 0L,
147 /* Child attempting a write lock from byte 7 to end of file */
148 F_WRLCK, 0, 7L, 0L, WILLBLOCK },
149
150 /* #11 Parent making a read lock on entire file */
151 { F_RDLCK, 0, 0L, 0L, SKIP, 0, 0L, 0L,
152 /* Child attempting a read lock from byte 7 to end of file */
153 F_RDLCK, 0, 7L, 0L, NOBLOCK },
154
155 /* #12 Parent making a read lock on entire file */
156 { F_RDLCK, 0, 0L, 0L, SKIP, 0, 0L, 0L,
157 /* Child attempting a write lock from byte 7 to end of file */
158 F_WRLCK, 0, 7L, 0L, WILLBLOCK },
159
160 /* Test cases: entire boundary ( less than entire file) */
161 /*
162 * #13 Parent making a write lock from beginning of
163 * file for 5 bytes
164 */
165 { F_WRLCK, 0, 0L, 5L, SKIP, 0, 0L, 0L,
166 /*
167 * Child attempting a read lock from beginning of
168 * file for 5 bytes
169 */
170 F_RDLCK, 0, 0L, 5L, WILLBLOCK },
171
172 /*
173 * #14 Parent making a write lock from beginning of file
174 * for 5 bytes
175 */
176 { F_WRLCK, 0, 0L, 5L, SKIP, 0, 0L, 0L,
177 /*
178 * Child attempting a write lock from beginning of
179 * file for 5 bytes
180 */
181 F_WRLCK, 0, 0L, 5L, WILLBLOCK },
182
183 /*
184 * #15 Parent making a read lock from beginning of
185 * file for 5 bytes
186 */
187 { F_RDLCK, 0, 0L, 5L, SKIP, 0, 0L, 0L,
188 /*
189 * Child attempting a read lock from beginning of
190 * file for 5 bytes
191 */
mridgedb639212005-01-04 21:04:11 +0000192 F_RDLCK, 0, 0L, 5L, NOBLOCK },
plars865695b2001-08-27 22:15:12 +0000193
194 /*
195 * #16 Parent making a read lock from beginning of
196 * file for 5 bytes
197 */
198 { F_RDLCK, 0, 0L, 5L, SKIP, 0, 0L, 0L,
199 /*
200 * Child attempting a write lock from beginning
201 * of file for 5 bytes
202 */
203 F_WRLCK, 0, 0L, 5L, WILLBLOCK },
204
205 /* Test cases: inside boundary */
206 /*
207 * #17 Parent making a write lock from beginning
208 * of file for 5 bytes
209 */
210 { F_WRLCK, 0, 0L, 5L, SKIP, 0, 0L, 0L,
211 /* Child attempting a read lock from byte 2 to byte 4 */
212 F_RDLCK, 0, 1L, 3L, WILLBLOCK },
213
214 /*
215 * #18 Parent making a write lock from beginning of
216 * file for 5 bytes
217 */
218 { F_WRLCK, 0, 0L, 5L, SKIP, 0, 0L, 0L,
219 /* Child attempting a write lock from byte 2 to byte 4 */
220 F_WRLCK, 0, 1L, 3L, WILLBLOCK },
221
222 /*
223 * #19 Parent making a read lock from beginning of
224 * file for 5 bytes
225 */
226 { F_RDLCK, 0, 0L, 5L, SKIP, 0, 0L, 0L,
227 /* Child attempting a read lock from byte 2 to byte 4 */
228 F_RDLCK, 0, 1L, 3L, NOBLOCK },
229
230 /*
231 * #20 Parent making a read lock from beginning of
232 * file for 5 bytes
233 */
234 { F_RDLCK, 0, 0L, 5L, SKIP, 0, 0L, 0L,
235 /* Child attempting a write lock from byte 2 to byte 4 */
236 F_WRLCK, 0, 1L, 3L, WILLBLOCK },
237
238 /* Test cases: cross boundary (inside to after) */
239 /*
240 * #21 Parent making a write lock from beginning of
241 * file for 5 bytes
242 */
243 { F_WRLCK, 0, 0L, 5L, SKIP, 0, 0L, 0L,
244 /* Child attempting a read lock from byte 3 to byte 7 */
245 F_RDLCK, 0, 2L, 5L, WILLBLOCK },
246
247 /*
248 * #22 Parent making a write lock from beginning
249 * of file for 5 bytes
250 */
251 { F_WRLCK, 0, 0L, 5L, SKIP, 0, 0L, 0L,
252 /* Child attempting a write lock from byte 3 to byte 7 */
253 F_WRLCK, 0, 2L, 5L, WILLBLOCK },
254
255 /*
256 * #23 Parent making a read lock from beginning of
257 * file for 5 bytes
258 */
259 { F_RDLCK, 0, 0L, 5L, SKIP, 0, 0L, 0L,
260 /* Child attempting a read lock from byte 3 to byte 7 */
261 F_RDLCK, 0, 2L, 5L, NOBLOCK },
262
263 /*
264 * #24 Parent making a read lock from beginning of
265 * file for 5 bytes
266 */
267 { F_RDLCK, 0, 0L, 5L, SKIP, 0, 0L, 0L,
268 /* Child attempting a write lock from byte 3 to byte 7 */
269 F_WRLCK, 0, 2L, 5L, WILLBLOCK },
270
271 /* Test cases: outside boundary (after) */
272
273 /*
274 * #25 Parent making a write lock from beginning of
275 * file for 5 bytes
276 */
277 { F_WRLCK, 0, 0L, 5L, SKIP, 0, 0L, 0L,
278 /* Child attempting a read lock from byte 7 to end of file */
279 F_RDLCK, 0, 6L, 0L, NOBLOCK },
280
281 /*
282 * #26 Parent making a write lock from beginning of
283 * file for 5 bytes
284 */
285 { F_WRLCK, 0, 0L, 5L, SKIP, 0, 0L, 0L,
286 /* Child attempting a write lock from byte 7 to end of file */
287 F_WRLCK, 0, 6L, 0L, NOBLOCK },
288
289 /*
290 * #27 Parent making a read lock from beginning of
291 * file for 5 bytes
292 */
293 { F_RDLCK, 0, 0L, 5L, SKIP, 0, 0L, 0L,
294 /* Child attempting a read lock from byte 7 to end of file */
295 F_RDLCK, 0, 6L, 0L, NOBLOCK },
296
297 /*
298 * #28 Parent making a read lock from beginning of
299 * file for 5 bytes
300 */
301 { F_RDLCK, 0, 0L, 5L, SKIP, 0, 0L, 0L,
302 /* Child attempting a write lock from byte 7 to end of file */
303 F_WRLCK, 0, 6L, 0L, NOBLOCK },
304
305 /* Test cases: outside boundary (before) */
306
307 /* #29 Parent making a write lock from byte 3 to byte 7 */
308 { F_WRLCK, 0, 2L, 5L, SKIP, 0, 0L, 0L,
309 /* Child attempting a read lock from beginning of file to byte 2 */
310 F_RDLCK, 0, 0L, 2L, NOBLOCK },
311
312 /* #30 Parent making a write lock from byte 3 to byte 7 */
313 { F_WRLCK, 0, 2L, 5L, SKIP, 0, 0L, 0L,
314 /* Child attempting a write lock from beginning of file to byte 2 */
315 F_WRLCK, 0, 0L, 2L, NOBLOCK },
316
317 /* #31 Parent making a write lock from byte 3 to byte 7 */
318 { F_RDLCK, 0, 2L, 5L, SKIP, 0, 0L, 0L,
319 /* Child attempting a read lock from beginning of file to byte 2 */
320 F_RDLCK, 0, 0L, 2L, NOBLOCK },
321
322 /* #32 Parent making a write lock from byte 3 to byte 7 */
323 { F_RDLCK, 0, 2L, 5L, SKIP, 0, 0L, 0L,
324 /* Child attempting a write lock from beginning of file to byte 2 */
325 F_WRLCK, 0, 0L, 2L, NOBLOCK },
326
327 /* Test cases: cross boundary (before to inside) */
328 /* #33 Parent making a write lock from byte 5 to end of file */
329 { F_WRLCK, 0, 4L, 0L, SKIP, 0, 0L, 0L,
330 /* Child attempting a read lock from byte 3 to byte 7 */
331 F_RDLCK, 0, 2L, 5L, WILLBLOCK },
332
333 /* #34 Parent making a write lock from byte 5 to end of file */
334 { F_WRLCK, 0, 4L, 0L, SKIP, 0, 0L, 0L,
335 /* Child attempting a write lock from byte 3 to byte 7 */
336 F_WRLCK, 0, 2L, 5L, WILLBLOCK },
337
338 /* #35 Parent making a read lock from byte 5 to end of file */
339 { F_RDLCK, 0, 4L, 0L, SKIP, 0, 0L, 0L,
340 /* Child attempting a read lock from byte 3 to byte 7 */
341 F_RDLCK, 0, 2L, 5L, NOBLOCK },
342
343 /* #36 Parent making a read lock from byte 5 to end of file */
344 { F_RDLCK, 0, 4L, 0L, SKIP, 0, 0L, 0L,
345 /* Child attempting a write lock from byte 3 to byte 7 */
346 F_WRLCK, 0, 2L, 5L, WILLBLOCK },
347
348 /* Start of negative L_start and L_len test cases */
349 /*
350 * #37 Parent making write lock from byte 2 to byte 3
351 * with L_start = -3
352 */
353 { F_WRLCK, 1, -3L, 2L, SKIP, 0, 0L, 0L,
354 /* Child attempting write lock on byte 1 */
355 F_WRLCK, 0, 1L, 1L, NOBLOCK },
356
357 /*
358 * #38 Parent making write lock from byte 2 to byte 3
359 * with L_start = -3
360 */
361 { F_WRLCK, 1, -3L, 2L, SKIP, 0, 0L, 0L,
362 /* Child attempting write lock on byte 4 */
363 F_WRLCK, 0, 4L, 1L, NOBLOCK },
364
365 /*
366 * #39 Parent making write lock from byte 2 to byte 3
367 * with L_start = -3
368 */
369 { F_WRLCK, 1, -3L, 2L, SKIP, 0, 0L, 0L,
370 /* Child attempting write lock on byte 2 */
371 F_WRLCK, 0, 2L, 1L, WILLBLOCK },
372
373 /*
374 * #40 Parent making write lock from byte 2 to byte 3
375 * with L_start = -3
376 */
377 { F_WRLCK, 1, -3L, 2L, SKIP, 0, 0L, 0L,
378 /* Child attempting write lock on byte 3 */
379 F_WRLCK, 0, 3L, 1L, WILLBLOCK },
380
381 /*
382 * #41 Parent making write lock from byte 2 to byte 6
383 * with L_start = -3
384 */
385 { F_WRLCK, 1, -3L, 5L, SKIP, 0, 0L, 0L,
386 /* Child attempting write lock on byte 1 */
387 F_WRLCK, 0, 1L, 1L, NOBLOCK },
388
389 /*
390 * #42 Parent making write lock from byte 2 to byte 6
391 * with L_start = -3
392 */
393 { F_WRLCK, 1, -3L, 5L, SKIP, 0, 0L, 0L,
394 /* Child attempting write lock on byte 7 */
395 F_WRLCK, 0, 1L, 1L, NOBLOCK },
396
397 /*
398 * #43 Parent making write lock from byte 2 to byte 6
399 * with L_start = -3
400 */
401 { F_WRLCK, 1, -3L, 5L, SKIP, 0, 0L, 0L,
402 /* Child attempting write lock on byte 2 */
403 F_WRLCK, 0, 2L, 1L, WILLBLOCK },
404
405 /*
406 * #44 Parent making write lock from byte 2 to byte 6
407 * with L_start = -3
408 */
409 { F_WRLCK, 1, -3L, 5L, SKIP, 0, 0L, 0L,
410 /* Child attempting write lock on byte 5 */
411 F_WRLCK, 0, 5L, 1L, WILLBLOCK },
412
413 /*
414 * #45 Parent making write lock from byte 2 to byte 6
415 * with L_start = -3
416 */
417 { F_WRLCK, 1, -3L, 5L, SKIP, 0, 0L, 0L,
418 /* Child attempting write lock on byte 6 */
419 F_WRLCK, 0, 6L, 1L, WILLBLOCK },
420
421 /*
422 * #46 Parent making write lock from byte 2 to byte 3 with
423 * L_start = -2 and L_len = -2
424 */
425 { F_WRLCK, 1, 2L, -2L, SKIP, 0, 0L, 0L,
426 /* Child attempting write lock on byte 1 */
427 F_WRLCK, 0, 1L, 1L, NOBLOCK },
428
429 /*
430 * #47 Parent making write lock from byte 2 to byte 3 with
431 * L_start = -2 and L_len = -2
432 */
433 { F_WRLCK, 1, -2L, -2L, SKIP, 0, 0L, 0L,
434 /* Child attempting write lock on byte 4 */
435 F_WRLCK, 0, 4L, 1L, NOBLOCK },
436
437 /*
438 * #48 Parent making write lock from byte 2 to byte 3 with
439 * L_start = -2 and L_len = -2
440 */
441 { F_WRLCK, 1, -2L, -2L, SKIP, 0, 0L, 0L,
442 /* Child attempting write lock on byte 2 */
443 F_WRLCK, 0, 2L, 1L, WILLBLOCK },
444
445 /*
446 * #49 Parent making write lock from byte 2 to byte 3 with
447 * L_start = -2 and L_len = -2
448 */
449 { F_WRLCK, 1, -2L, -2L, SKIP, 0, 0L, 0L,
450 /* Child attempting write lock on byte 3 */
451 F_WRLCK, 0, 3L, 1L, WILLBLOCK },
452
453 /*
454 * #50 Parent making write lock from byte 6 to byte 7 with
455 * L_start = 2 and L_len = -2
456 */
457 { F_WRLCK, 1, 2L, -2L, SKIP, 0, 0L, 0L,
458 /* Child attempting write lock on byte 5 */
459 F_WRLCK, 0, 5L, 1L, NOBLOCK },
460
461 /*
462 * #51 Parent making write lock from byte 6 to byte 7 with
463 * L_start = 2 and L_len = -2
464 */
465 { F_WRLCK, 1, 2L, -2L, SKIP, 0, 0L, 0L,
466 /* Child attempting write lock on byte 8 */
467 F_WRLCK, 0, 8L, 1L, NOBLOCK },
468
469 /*
470 * #52 Parent making write lock from byte 6 to byte 7 with
471 * L_start = 2 and L_len = -2
472 */
473 { F_WRLCK, 1, 2L, -2L, SKIP, 0, 0L, 0L,
474 /* Child attempting write lock on byte 6 */
475 F_WRLCK, 0, 6L, 1L, WILLBLOCK },
476
477 /*
478 * #53 Parent making write lock from byte 6 to byte 7 with
479 * L_start = 2 and L_len = -2
480 */
481 { F_WRLCK, 1, 2L, -2L, SKIP, 0, 0L, 0L,
482 /* Child attempting write lock on byte 7 */
483 F_WRLCK, 0, 7L, 1L, WILLBLOCK },
484
485 /*
486 * #54 Parent making write lock from byte 3 to byte 7 with
487 * L_start = 2 and L_len = -5
488 */
489 { F_WRLCK, 1, 2L, -5L, SKIP, 0, 0L, 0L,
490 /* Child attempting write lock on byte 2 */
491 F_WRLCK, 0, 2L, 1L, NOBLOCK },
492
493 /*
494 * #55 Parent making write lock from byte 3 to byte 7 with
495 * L_start = 2 and L_len = -5
496 */
497 { F_WRLCK, 1, 2L, -5L, SKIP, 0, 0L, 0L,
498 /* Child attempting write lock on byte 8 */
499 F_WRLCK, 0, 8L, 1L, NOBLOCK },
500
501 /*
502 * #56 Parent making write lock from byte 3 to byte 7 with
503 * L_start = 2 and L_len = -5
504 */
505 { F_WRLCK, 1, 2L, -5L, SKIP, 0, 0L, 0L,
506 /* Child attempting write lock on byte 3 */
507 F_WRLCK, 0, 3L, 1L, WILLBLOCK },
508
509 /*
510 * #57 Parent making write lock from byte 3 to byte 7 with
511 * L_start = 2 and L_len = -5
512 */
513 { F_WRLCK, 1, 2L, -5L, SKIP, 0, 0L, 0L,
514 /* Child attempting write lock on byte 5 */
515 F_WRLCK, 0, 5L, 1L, WILLBLOCK },
516
517 /*
518 * #58 Parent making write lock from byte 3 to byte 7 with
519 * L_start = 2 and L_len = -5
520 */
521 { F_WRLCK, 1, 2L, -5L, SKIP, 0, 0L, 0L,
522 /* Child attempting write lock on byte 7 */
523 F_WRLCK, 0, 7L, 1L, WILLBLOCK },
524
525 /* Test case for block 4 */
526 /* #59 Parent making write lock on entire file */
527 { F_WRLCK, 0, 0L, 0L, SKIP, 0, 0L, 0L,
528 /* Child attempting write lock on byte 15 to end of file */
529 F_WRLCK, 0, 15L, 0L, WILLBLOCK },
530};
531
532static testcase *thiscase;
533static struct flock flock;
534static int parent, child, status, fail = 0;
535static int got1 = 0;
536static int fd;
537static int test;
538static char tmpname[40];
539
540#define FILEDATA "ten bytes!"
541
542extern void catch1(); /* signal catching subroutine */
543extern void catch_alarm();
544
nstrazfa31d552002-05-14 16:50:06 +0000545char *TCID = "fcntl14"; /* Test program identifier */
plars865695b2001-08-27 22:15:12 +0000546int TST_TOTAL = 1; /* Total number of test cases */
547extern int Tst_count; /* Test case counter */
548
robbiewd34d5812005-07-11 22:28:09 +0000549#ifdef UCLINUX
550static char *argv0; /* Set by main(), passed to self_exec() */
551#endif
robbiew4cf80962003-03-25 21:53:41 +0000552
553/*
554 * cleanup()
555 * performs all the ONE TIME cleanup for this test at completion or
556 * premature exit
557 */
558void
559cleanup(void)
plars865695b2001-08-27 22:15:12 +0000560{
robbiew4cf80962003-03-25 21:53:41 +0000561 /*
562 * print timing status if that option was specified
563 * print errno log if that option was specified
564 */
565 TEST_CLEANUP;
plars865695b2001-08-27 22:15:12 +0000566
robbiew4cf80962003-03-25 21:53:41 +0000567 tst_rmdir();
plars865695b2001-08-27 22:15:12 +0000568
robbiew4cf80962003-03-25 21:53:41 +0000569 tst_exit();
plars865695b2001-08-27 22:15:12 +0000570}
571
572/*
573 * setup
574 * performs all ONE TIME setup for this test
575 */
576void
577setup(void)
578{
robbiew1e4cf0c2005-02-24 17:03:42 +0000579 struct sigaction act;
580
plars865695b2001-08-27 22:15:12 +0000581 tst_sig(FORK, DEF_HANDLER, cleanup); /* capture signals */
subrata_modakb370c3c2007-11-25 16:37:35 +0000582 signal(SIGHUP, SIG_IGN);
plars865695b2001-08-27 22:15:12 +0000583 umask(0);
584 TEST_PAUSE; /* Pause if that option is specified */
585 tst_tmpdir(); /* make temp dir and cd to it */
586 parent = getpid();
587
588 /* setup temporary file name */
589 sprintf(tmpname, "fcntl2.%d", parent);
590
591 /* setup signal handler for signal from child */
robbiew1e4cf0c2005-02-24 17:03:42 +0000592 memset(&act, 0, sizeof(act));
593 act.sa_handler = catch1;
594 sigemptyset(&act.sa_mask);
595 sigaddset(&act.sa_mask, SIGUSR1);
596 if ((sigaction(SIGUSR1, &act, NULL)) < 0) {
plars865695b2001-08-27 22:15:12 +0000597 tst_resm(TFAIL, "SIGUSR1 signal setup failed, errno = %d",
598 errno);
599 cleanup();
600 /*NOTREACHED*/
601 }
robbiew1e4cf0c2005-02-24 17:03:42 +0000602
603 memset(&act, 0, sizeof(act));
604 act.sa_handler = catch_alarm;
605 sigemptyset(&act.sa_mask);
606 sigaddset(&act.sa_mask, SIGALRM);
607 if ((sigaction(SIGALRM, &act, NULL)) < 0) {
plars865695b2001-08-27 22:15:12 +0000608 tst_resm(TFAIL, "SIGALRM signal setup failed");
609 cleanup();
610 /*NOTREACHED*/
611 }
612}
613
mridgedb639212005-01-04 21:04:11 +0000614void
615wake_parent(void)
616{
617 if ((kill(parent, SIGUSR1)) < 0) {
618 tst_resm(TFAIL, "Attempt to send signal to parent "
619 "failed");
620 tst_resm(TFAIL, "Test case %d, errno = %d", test + 1,
621 errno);
622 fail = 1;
623 }
624}
625
robbiewd34d5812005-07-11 22:28:09 +0000626void do_usleep_child() {
627 usleep(100000); /* XXX how long is long enough? */
628 wake_parent();
629 exit(0);
630}
631
632
robbiew4cf80962003-03-25 21:53:41 +0000633void dochild()
634{ /* child process */
mridgedb639212005-01-04 21:04:11 +0000635 int rc;
636 pid_t pid;
637
robbiew4cf80962003-03-25 21:53:41 +0000638 /* Initialize the child lock structure */
639 flock.l_type = thiscase->c_type;
640 flock.l_whence = thiscase->c_whence;
641 flock.l_start = thiscase->c_start;
642 flock.l_len = thiscase->c_len;
643 flock.l_pid = 0;
644 fail = 0;
645
646 /*
647 * Check to see if child lock will succeed. If it will, FLOCK
648 * structure will return with l_type changed to F_UNLCK. If it will
649 * not, the parent pid will be returned in l_pid and the type of
650 * lock that will block it in l_type.
651 */
mridgedb639212005-01-04 21:04:11 +0000652 if ((rc = fcntl(fd, F_GETLK, &flock)) < 0) {
robbiew4cf80962003-03-25 21:53:41 +0000653 tst_resm(TFAIL, "Attempt to check lock status failed");
654 tst_resm(TFAIL, "Test case %d, errno = %d",
655 test + 1, errno);
656 fail = 1;
mridgedb639212005-01-04 21:04:11 +0000657 } else {
robbiew4cf80962003-03-25 21:53:41 +0000658
659 if ((thiscase->c_flag) == NOBLOCK) {
660 if (flock.l_type != F_UNLCK) {
661 tst_resm(TFAIL, "Test case %d, GETLK: type = %d, "
662 "%d was expected", test + 1, flock.l_type,
663 F_UNLCK);
664 fail = 1;
665 }
666
667 if (flock.l_whence != thiscase->c_whence) {
668 tst_resm(TFAIL, "Test case %d, GETLK: whence = %d, "
669 "should have remained %d", test + 1,
670 flock.l_whence, thiscase->c_whence);
671 fail = 1;
672 }
673
674 if (flock.l_start != thiscase->c_start) {
675 tst_resm(TFAIL, "Test case %d, GETLK: start = %d, "
676 "should have remained %d", test + 1,
677 flock.l_start, thiscase->c_start);
678 fail = 1;
679 }
680
681 if (flock.l_len != thiscase->c_len) {
682 tst_resm(TFAIL, "Test case %d, GETLK: len = %d, "
683 "should have remained %d", test + 1,
684 flock.l_len, thiscase->c_len);
685 fail = 1;
686 }
687
688 if (flock.l_pid != 0) {
689 tst_resm(TFAIL, "Test case %d, GETLK: pid = %d, "
690 "should have remained 0", test + 1,
691 flock.l_pid);
692 fail = 1;
693 }
694 } else {
695 if (flock.l_pid != parent) {
696 tst_resm(TFAIL, "Test case %d, GETLK: pid = %d, "
697 "should be parent's id of %d", test + 1,
698 flock.l_pid, parent);
699 fail = 1;
700 }
701
702 if (flock.l_type != thiscase->a_type) {
703 tst_resm(TFAIL, "Test case %d, GETLK: type = %d, "
704 "should be parent's first lock type of %d",
705 test + 1, flock.l_type, thiscase->a_type);
706 fail = 1;
707 }
708 }
mridgedb639212005-01-04 21:04:11 +0000709 }
robbiew4cf80962003-03-25 21:53:41 +0000710
711 /*
712 * now try to set the lock, nonblocking
713 * This will succeed for NOBLOCK,
714 * fail for WILLBLOCK
715 */
716 flock.l_type = thiscase->c_type;
717 flock.l_whence = thiscase->c_whence;
718 flock.l_start = thiscase->c_start;
719 flock.l_len = thiscase->c_len;
720 flock.l_pid = 0;
721
mridgedb639212005-01-04 21:04:11 +0000722 if ((rc = fcntl(fd, F_SETLK, &flock)) < 0) {
robbiew4cf80962003-03-25 21:53:41 +0000723 if ((thiscase->c_flag) == NOBLOCK) {
724 tst_resm(TFAIL, "Attempt to set child NONBLOCKING "
725 "lock failed");
726 tst_resm(TFAIL, "Test case %d, errno = %d",
727 test + 1, errno);
728 fail = 1;
729 }
730 }
731
732 if ((thiscase->c_flag) == WILLBLOCK) {
733 /* Check for proper errno condition */
mridgedb639212005-01-04 21:04:11 +0000734 if (rc != -1 || (errno != EACCES && errno != EAGAIN)) {
735 tst_resm(TFAIL,
736 "SETLK: rc = %d, errno = %d, -1/EAGAIN or EACCES "
737 "was expected", rc, errno);
robbiew4cf80962003-03-25 21:53:41 +0000738 fail = 1;
739 }
mridgedb639212005-01-04 21:04:11 +0000740 if (rc == 0) {
741 /* accidentally got the lock */
742 /* XXX how to clean up? */
743 (void) fcntl(fd, F_UNLCK, &flock);
744 }
robbiew4cf80962003-03-25 21:53:41 +0000745 /*
746 * Lock should succeed after blocking and parent releases
mridgedb639212005-01-04 21:04:11 +0000747 * lock, tell the parent to release the locks.
748 * Do the lock in this process, send the signal in a child
749 * process, so that the SETLKW actually uses the blocking
750 * mechanism in the kernel.
751 *
752 * XXX inherent race: we want to wait until the
753 * F_SETLKW has started, but we don't have a way to
754 * check that reliably in the child. (We'd
755 * need some way to have fcntl() atomically unblock a
756 * signal and wait for the lock.)
robbiew4cf80962003-03-25 21:53:41 +0000757 */
robbiewd34d5812005-07-11 22:28:09 +0000758 pid = FORK_OR_VFORK();
mridgedb639212005-01-04 21:04:11 +0000759 switch (pid) {
760 case -1:
761 tst_resm(TFAIL, "Fork failed");
762 break;
763 case 0: /* child */
robbiewd34d5812005-07-11 22:28:09 +0000764#ifdef UCLINUX
765 if (self_exec(argv0, "n", 1) < 0) {
766 tst_resm(TFAIL, "self_exec failed");
767 break;
768 }
769#else
770 do_usleep_child();
771#endif
mridgedb639212005-01-04 21:04:11 +0000772 break;
773
774 default:
775 if ((rc = fcntl(fd, F_SETLKW, &flock)) < 0) {
776 tst_resm(TFAIL, "Attempt to set child BLOCKING "
robbiew4cf80962003-03-25 21:53:41 +0000777 "lock failed");
778 tst_resm(TFAIL, "Test case %d, errno = %d", test + 1,
779 errno);
780 fail = 1;
mridgedb639212005-01-04 21:04:11 +0000781 }
782 waitpid(pid, &status, 0);
783 break;
784 }
robbiew4cf80962003-03-25 21:53:41 +0000785 }
786 if (fail) {
787 exit(1);
788 } else {
789 exit(0);
790 }
791}
792
793
794void run_test(int file_flag, int file_mode, int seek, int start, int end)
plars865695b2001-08-27 22:15:12 +0000795{
plars865695b2001-08-27 22:15:12 +0000796 extern long time();
797
robbiew49058422003-07-25 16:10:11 +0000798 /* reset fail to 0 for each run_test call */
799 fail = 0;
800
plars865695b2001-08-27 22:15:12 +0000801 /* loop thru all test cases */
802 for (test = start; test < end; test++) {
803 /* open a temp file to lock */
804 fd = open(tmpname, file_flag, file_mode);
805 if (fd < 0) {
806 tst_brkm(TBROK, cleanup, "open() failed");
807 /*NOTREACHED*/
808 }
809
810 /* write some dummy data to the file */
811 if (write (fd, FILEDATA, 10) < 0) {
812 tst_brkm(TBROK, cleanup, "write() failed");
813 /*NOTREACHED*/
814 }
815
816 /* seek into file if indicated */
817 if (seek) {
818 if (lseek(fd, seek, 0) < 0) {
819 tst_brkm(TBROK, cleanup, "lseek() failed");
820 /*NOTREACHED*/
821 }
822 }
823
824 /* Initialize first parent lock structure */
825 thiscase = &testcases[test];
826 flock.l_type = thiscase->a_type;
827 flock.l_whence = thiscase->a_whence;
828 flock.l_start = thiscase->a_start;
829 flock.l_len = thiscase->a_len;
830
831 /* set the initial parent lock on the file */
832 if ((fcntl (fd, F_SETLK, &flock)) < 0) {
833 tst_resm(TFAIL, "First parent lock failed");
834 tst_resm(TFAIL, "Test case %d, errno = %d",
835 test + 1, errno);
836 fail = 1;
837 }
838
839 if ((thiscase->b_type) != SKIP) {
840 /* Initialize second parent lock structure */
841 flock.l_type = thiscase->b_type;
842 flock.l_whence = thiscase->b_whence;
843 flock.l_start = thiscase->b_start;
844 flock.l_len = thiscase->b_len;
845
846 /* set the second parent lock */
847 if ((fcntl(fd, F_SETLK, &flock)) < 0) {
848 tst_resm(TFAIL, "Second parent lock failed");
849 tst_resm(TFAIL, "Test case %d, errno = %d",
850 test + 1, errno);
851 fail = 1;
852 }
853 }
854 if ((thiscase->c_type) == SKIP) {
855 /* close the temp file and move to next test case */
856 close(fd);
857 tst_resm(TINFO, "skipping test %d", test + 1);
858 continue; /* continue to the next case */
859 }
860 /*
861 * Mask SIG_USR1 before forking child, to avoid race
862 */
863 (void)sighold(SIGUSR1);
864
robbiew49058422003-07-25 16:10:11 +0000865 /* flush the stdout to avoid garbled output */
866 fflush(stdout);
867
plars865695b2001-08-27 22:15:12 +0000868 /* spawn a child process */
robbiewd34d5812005-07-11 22:28:09 +0000869 if ((child = FORK_OR_VFORK()) == 0) {
870#ifdef UCLINUX
871 if (self_exec(argv0, "nddddddddd", 2, thiscase->c_type,
872 thiscase->c_whence, thiscase->c_start,
873 thiscase->c_len, thiscase->c_flag,
874 thiscase->a_type, fd, test, parent) < 0) {
875 tst_resm(TFAIL, "self_exec failed");
876 cleanup();
877 /*NOTREACHED*/
878 }
879#else
plars865695b2001-08-27 22:15:12 +0000880 dochild();
robbiewd34d5812005-07-11 22:28:09 +0000881#endif
plars865695b2001-08-27 22:15:12 +0000882 }
883 if (child < 0) {
884 tst_resm(TFAIL, "Fork failed");
885 cleanup();
886 /*NOTREACHED*/
887 }
888 /* parent process */
889 if ((thiscase->c_flag) == WILLBLOCK) {
890 /*
891 * Wait for a signal from the child then remove
892 * blocking lock. Set a 60 second alarm to break the
893 * pause just in case the child never signals us.
894 */
895 alarm(TIME_OUT);
896 sigpause(SIGUSR1);
897
898 /* turn off the alarm timer */
899 alarm((unsigned)0);
900 if (got1 != 1)
901 tst_resm(TINFO, "Pause terminated without "
902 "signal SIGUSR1 from child");
903 got1 = 0; /* reset the flag */
904
905 /*
906 * setup lock structure for parent to delete
907 * blocking lock then wait for child to exit
908 */
909 flock.l_type = F_UNLCK;
910 flock.l_whence = 0;
911 flock.l_start = 0L;
912 flock.l_len = 0L;
913 if ((fcntl(fd, F_SETLK, &flock)) < 0) {
914 tst_resm(TFAIL, "Attempt to release parent "
915 "lock failed");
916 tst_resm(TFAIL, "Test case %d, errno = %d",
917 test + 1, errno);
918 fail = 1;
919 }
920 }
921 /*
922 * set a 60 second alarm to break the wait just in case the
923 * child doesn't terminate on its own accord
924 */
925 alarm(TIME_OUT);
926
927 /* wait for the child to terminate and close the file */
mridgedb639212005-01-04 21:04:11 +0000928 waitpid(child, &status, 0);
plars865695b2001-08-27 22:15:12 +0000929 /* turn off the alarm clock */
930 alarm((unsigned)0);
931 if (status != 0) {
932 tst_resm(TFAIL, "tchild returned status 0x%x", status);
933 fail = 1;
934 }
935 close(fd);
936 if (fail) {
937 tst_resm(TFAIL, "testcase:%d FAILED", test + 1);
938 } else {
939 tst_resm(TPASS, "testcase:%d PASSED", test + 1);
940 }
941 }
942 unlink(tmpname);
943}
944
plars865695b2001-08-27 22:15:12 +0000945void
946catch_alarm()
947{
948 /*
949 * Timer has runout and child has not signaled, need
950 * to kill off the child as it appears it will not
951 * on its own accord. Check that it is still around
952 * as it may have terminated abnormally while parent
953 * was waiting for SIGUSR1 signal from it.
954 */
955 if (kill(child, 0) == 0) {
956 kill(child, SIGKILL);
957 perror("The child didnot terminate on its own accord");
958 }
959}
960
961void
962catch1() /* invoked on catching SIGUSR1 */
963{
robbiew1e4cf0c2005-02-24 17:03:42 +0000964 struct sigaction act;
965
plars865695b2001-08-27 22:15:12 +0000966 /*
967 * Set flag to let parent know that child is ready to have lock
968 * removed
969 */
robbiew1e4cf0c2005-02-24 17:03:42 +0000970 memset(&act, 0, sizeof(act));
971 act.sa_handler = catch1;
972 sigemptyset(&act.sa_mask);
973 sigaddset(&act.sa_mask, SIGUSR1);
974 sigaction(SIGUSR1, &act, NULL);
plars865695b2001-08-27 22:15:12 +0000975 got1++;
976}
977
robbiew4cf80962003-03-25 21:53:41 +0000978int main(int ac, char **av)
plars865695b2001-08-27 22:15:12 +0000979{
robbiew4cf80962003-03-25 21:53:41 +0000980 int lc; /* loop counter */
981 char *msg; /* message returned from parse_opts */
plars865695b2001-08-27 22:15:12 +0000982
robbiew4cf80962003-03-25 21:53:41 +0000983 /* parse standard options */
984 if ((msg = parse_opts(ac, av, (option_t *)NULL, NULL)) != (char *)NULL){
985 tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg);
986 }
plars865695b2001-08-27 22:15:12 +0000987
robbiewd34d5812005-07-11 22:28:09 +0000988#ifdef UCLINUX
989 argv0 = av[0];
990
991 maybe_run_child(&do_usleep_child, "n", 1);
992 thiscase = malloc(sizeof(testcase));
993
994 maybe_run_child(&dochild, "nddddddddd", 2, &thiscase->c_type,
995 &thiscase->c_whence, &thiscase->c_start,
996 &thiscase->c_len, &thiscase->c_flag, &thiscase->a_type,
997 &fd, &test, &parent);
998#endif
999
robbiew4cf80962003-03-25 21:53:41 +00001000 setup(); /* global setup */
1001
subrata_modak5387ba02008-05-05 08:49:34 +00001002 /*
1003 * check if the current filesystem is nfs
1004 */
1005 if(tst_is_cwd_nfs()) {
1006 tst_brkm(TCONF, cleanup, "Cannot do fcntl on a file located on an NFS filesystem");
1007 }
1008
1009
robbiew4cf80962003-03-25 21:53:41 +00001010 /* Check for looping state if -i option is given */
1011 for (lc = 0; TEST_LOOPING(lc); lc++) {
1012 /* reset Tst_count in case we are looping */
1013 Tst_count = 0;
1014
mridgedb639212005-01-04 21:04:11 +00001015/* //block1: */
robbiew4cf80962003-03-25 21:53:41 +00001016 tst_resm(TINFO, "Enter block 1: without mandatory locking");
1017 fail = 0;
1018 /*
1019 * try various file locks on an ordinary file without
1020 * mandatory locking
1021 */
1022 (void)run_test(O_CREAT | O_RDWR | O_TRUNC, 0777, 0, 0, 36);
1023 if (fail) {
1024 tst_resm(TFAIL, "Block 1, test 1 FAILED");
1025 } else {
1026 tst_resm(TPASS, "Block 1, test 1 PASSED");
1027 }
1028
1029 /* Now try with negative values for L_start and L_len */
1030 (void)run_test(O_CREAT | O_RDWR | O_TRUNC, 0777, 5, 36, 45);
1031
1032 if (fail) {
1033 tst_resm(TFAIL, "Block 1, test 2 FAILED");
1034 } else {
1035 tst_resm(TPASS, "Block 1, test 2 PASSED");
1036 }
1037
1038
1039 tst_resm(TINFO, "Exit block 1");
1040
mridgedb639212005-01-04 21:04:11 +00001041/* //block2: */
robbiew4cf80962003-03-25 21:53:41 +00001042 tst_resm(TINFO, "Enter block 2: with mandatory locking");
1043 fail = 0;
1044 /*
1045 * Try various locks on a file with mandatory record locking
1046 * this should behave the same as an ordinary file
1047 */
1048 (void)run_test(O_CREAT | O_RDWR | O_TRUNC, S_ENFMT | S_IRUSR |
1049 S_IWUSR, 0, 0, 36);
1050 if (fail) {
1051 tst_resm(TFAIL, "Block 2, test 1 FAILED");
1052 } else {
1053 tst_resm(TPASS, "Block 2, test 1 PASSED");
1054 }
1055
1056
1057 /* Now try negative values for L_start and L_len */
1058 (void)run_test(O_CREAT | O_RDWR | O_TRUNC, S_ENFMT | S_IRUSR |
1059 S_IWUSR, 5, 36, 45);
1060 if (fail) {
1061 tst_resm(TFAIL, "Block 2, test 2 FAILED");
1062 } else {
1063 tst_resm(TPASS, "Block 2, test 2 PASSED");
1064 }
1065
1066 tst_resm(TINFO, "Exit block 2");
1067
mridgedb639212005-01-04 21:04:11 +00001068/* //block3: */
robbiew4cf80962003-03-25 21:53:41 +00001069 tst_resm(TINFO, "Enter block 3");
1070 fail = 0;
1071 /*
1072 * Check that proper error status is returned when invalid
1073 * argument used for WHENCE (negative value)
1074 */
1075
1076 /* open a temporary file to lock */
1077 fd = open(tmpname, O_CREAT | O_RDWR | O_TRUNC, 0777);
1078 if (fd < 0) {
1079 tst_brkm(TBROK, cleanup, "open failed");
1080 /*NOTREACHED*/
1081 }
1082
1083 /* Write some dummy data to the file */
1084 if (write(fd, FILEDATA, 10) < 0) {
1085 tst_brkm(TBROK, cleanup, "write failed");
1086 /*NOTREACHED*/
1087 }
1088
1089 /* Initialize lock structure */
1090 flock.l_type = F_WRLCK;
1091 flock.l_whence = -1;
1092 flock.l_start = 0L;
1093 flock.l_len = 0L;
1094
1095 /* Set the lock on the file */
1096 if ((fcntl(fd, F_SETLK, &flock)) < 0) {
1097 if (errno != EINVAL) {
1098 tst_resm(TFAIL, "Expected %d got %d",
1099 EINVAL, errno);
1100 fail = 1;
1101 }
1102 } else {
1103 tst_resm(TFAIL, "Lock succeeded when it should have "
1104 "failed");
1105 fail = 1;
1106 }
1107
1108 /* Close and remove temp file */
1109 close(fd);
1110 unlink(tmpname);
1111
1112 if (fail) {
1113 tst_resm(TINFO, "Test with mandatory "
1114 "locking FAILED");
1115 } else {
1116 tst_resm(TINFO, "Test with mandatory "
1117 "locking PASSED");
1118 }
1119 tst_resm(TINFO, "Exit block 3");
1120
mridgedb639212005-01-04 21:04:11 +00001121/* //block4: */
robbiew4cf80962003-03-25 21:53:41 +00001122 tst_resm(TINFO, "Enter block 4");
1123 fail = 0;
1124 /*
1125 * Check that a lock on end of file is still valid when
1126 * additional data is appended to end of file and a new
1127 * process attempts to lock new data
1128 */
1129 /* open a temp file to lock */
1130 fd = open(tmpname, O_CREAT | O_RDWR | O_TRUNC, 0777);
1131 if (fd < 0) {
1132 tst_brkm(TBROK, cleanup, "open failed");
1133 /*NOTREACHED*/
1134 }
1135
1136 /* Write some dummy data to the file */
1137 if (write(fd, FILEDATA, 10) < 0) {
1138 tst_brkm(TBROK, cleanup, "write failed");
1139 /*NOTREACHED*/
1140 }
1141
1142 /* Initialize first parent lock structure */
1143 thiscase = &testcases[58];
1144 flock.l_type = thiscase->a_type;
1145 flock.l_whence = thiscase->a_whence;
1146 flock.l_start = thiscase->a_start;
1147 flock.l_len = thiscase->a_len;
1148
1149 /* Set the initial parent lock on the file */
1150 if ((fcntl(fd, F_SETLK, &flock)) < 0) {
1151 tst_resm(TFAIL, "First parent lock failed");
1152 tst_resm(TFAIL, "Test case %d, errno = %d", 58, errno);
1153 fail = 1;
1154 }
1155
1156 /* Write some additional data to end of file */
1157 if (write(fd, FILEDATA, 10) < 0) {
1158 tst_brkm(TBROK, cleanup, "write failed");
1159 /*NOTREACHED*/
1160 }
1161
1162 /* Mask signal to avoid race */
1163 if (sighold(SIGUSR1) < 0) {
1164 tst_brkm(TBROK, cleanup, "sighold failed");
1165 /*NOTREACHED*/
1166 }
1167
1168 /* spawn a child process */
subrata_modakb370c3c2007-11-25 16:37:35 +00001169 if ((child = FORK_OR_VFORK()) == 0) {
robbiewd34d5812005-07-11 22:28:09 +00001170#ifdef UCLINUX
1171 if (self_exec(argv0, "nddddddddd", 2, thiscase->c_type,
1172 thiscase->c_whence, thiscase->c_start,
1173 thiscase->c_len, thiscase->c_flag,
1174 thiscase->a_type, fd, test, parent) < 0) {
1175 tst_resm(TFAIL, "self_exec failed");
1176 cleanup();
1177 /*NOTREACHED*/
1178 }
1179#else
robbiew4cf80962003-03-25 21:53:41 +00001180 dochild();
robbiewd34d5812005-07-11 22:28:09 +00001181#endif
robbiew4cf80962003-03-25 21:53:41 +00001182 }
1183 if (child < 0) {
1184 tst_resm(TFAIL, "Fork failed");
1185 cleanup();
1186 /*NOTREACHED*/
1187 }
1188
1189 /* parent process */
1190
1191 /*
1192 * Wait for a signal from the child then remove blocking lock.
1193 * Set a 60 sec alarm to break the pause just in case the
1194 * child doesn't terminate on its own accord
1195 */
1196 (void)alarm(TIME_OUT);
1197
1198 /* pause for the SIGUSR1 signal from child */
1199 (void)sigpause(SIGUSR1);
1200
1201 /* turn off the alarm timer */
1202 (void)alarm((unsigned)0);
1203 if (got1 != 1) {
1204 tst_resm(TINFO, "Pause terminated without signal "
1205 "SIGUSR1 from child");
1206 }
1207 got1 = 0; /* reset flag */
1208
1209 /*
1210 * Set up lock structure for parent to delete
1211 * blocking lock then wait for child to exit
1212 */
1213 flock.l_type = F_UNLCK;
1214 flock.l_whence = 0;
1215 flock.l_start = 0L;
1216 flock.l_len = 0L;
1217 if ((fcntl(fd, F_SETLK, &flock)) < 0) {
1218 tst_resm(TFAIL, "Attempt to release parent lock "
1219 "failed");
1220 tst_resm(TFAIL, "Test case %d, errno = %d", test + 1,
1221 errno);
1222 fail = 1;
1223 }
1224
1225 /*
1226 * set a 60 sec alarm to break the wait just in case the
1227 * child doesn't terminate on its own accord
1228 */
1229 (void)alarm(TIME_OUT);
1230
1231 /* wait for the child to terminate and close the file */
1232 waitpid(child, &status, 0);
1233 if (WEXITSTATUS(status) != 0) {
1234 fail = 1;
1235 tst_resm(TFAIL, "child returned bad exit status");
1236 }
1237
1238 /* turn off the alarm clock */
1239 (void)alarm((unsigned)0);
1240 if (status != 0) {
1241 tst_resm(TFAIL, "child returned status 0x%x", status);
1242 fail = 1;
1243 }
1244 close(fd);
1245 unlink(tmpname);
1246
1247 if (fail) {
1248 tst_resm(TINFO, "Test of locks on file FAILED");
1249 } else {
1250 tst_resm(TINFO, "Test of locks on file PASSED");
1251 }
1252 tst_resm(TINFO, "Exit block 4");
1253 }
1254 cleanup();
subrata_modak43337a32009-02-26 11:43:51 +00001255 return 0;
plars865695b2001-08-27 22:15:12 +00001256}