blob: 2f8b615583f36b77a9e8a89998655ea77f118dad [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 * fcntl21.c
plars865695b2001-08-27 22:15:12 +000023 *
24 * DESCRIPTION
25 * Check locking of regions of a file
26 *
27 * ALGORITHM
28 * Test changing lock sections around a read lock
29 *
30 * USAGE
nstrazfa31d552002-05-14 16:50:06 +000031 * fcntl21
plars865695b2001-08-27 22:15:12 +000032 *
33 * HISTORY
34 * 07/2001 Ported by Wayne Boyer
35 *
36 * RESTRICTIONS
37 * None
38 */
39
40#include <fcntl.h>
41#include <errno.h>
42#include <signal.h>
43#include <test.h>
44#include <usctest.h>
45
46#define STRINGSIZE 27
47#define STRING "abcdefghijklmnopqrstuvwxyz\n"
48#define STOP 0xFFF0
49
50int parent_pipe[2];
51int child_pipe[2];
52int fd;
plarsa1e518d2002-09-09 18:23:52 +000053pid_t parent_pid, child_pid;
plars865695b2001-08-27 22:15:12 +000054char *file;
55
56void parent_put();
57void parent_get();
58void child_put();
59void child_get();
60void stop_child();
plarsa1e518d2002-09-09 18:23:52 +000061void compare_lock(struct flock *, short, short, int, int, pid_t);
plars865695b2001-08-27 22:15:12 +000062void unlock_file();
63void do_test(struct flock *, short, short, int, int);
64void catch_child();
65char *str_type();
66int do_lock(int, short, short, int, int);
67
nstrazfa31d552002-05-14 16:50:06 +000068char *TCID = "fcntl21";
plars865695b2001-08-27 22:15:12 +000069int TST_TOTAL = 1;
70extern int Tst_count;
71
72void setup(void);
73void cleanup(void);
74int fail;
75
76main(int ac, char **av)
77{
78 struct flock tl;
79
80 int lc; /* loop counter */
81 char *msg; /* message returned from parse_opts */
82
83 /* parse standard options */
84 if ((msg = parse_opts(ac, av, (option_t *)NULL, NULL)) != (char *)NULL){
85 tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg);
86 }
87
88 setup(); /* global setup */
89
90 /* Check for looping state if -i option is given */
91 for (lc = 0; TEST_LOOPING(lc); lc++) {
92 /* reset Tst_count in case we are looping */
93 Tst_count = 0;
94
95 if ((child_pid = fork()) == 0) {
96 do_child();
97 }
98 if (child_pid < 0) {
99 tst_resm(TFAIL, "Fork failed");
100 cleanup();
101 }
102
103 (void)close(parent_pipe[0]);
104 (void)close(child_pipe[1]);
105
106block1:
107 tst_resm(TINFO, "Enter block 1");
108 fail = 0;
109 /*
110 * Set a read lock on the whole file
111 */
112 if (do_lock(F_SETLK, (short)F_RDLCK, (short)0, 0, 0) < 0) {
113 tst_resm(TFAIL, "fcntl on file %s failed, errno =%d",
114 file, errno);
115 fail = 1;
116 }
117
118 /*
119 * Test to make sure it's there.
120 */
121 do_test(&tl, (short)F_WRLCK, (short)0, 0, 0);
122 compare_lock(&tl, (short)F_RDLCK, (short)0, 0, 0, parent_pid);
123
124 /*
125 * remove the lock set above
126 */
127 unlock_file();
128
129 if (fail) {
130 tst_resm(TINFO, "Test block 1: FAILED");
131 } else {
132 tst_resm(TINFO, "Test block 1: PASSED");
133 }
134 tst_resm(TINFO, "Exit block 1");
135
136block2:
137 tst_resm(TINFO, "Enter block 2");
138 fail = 0;
139
140 /*
141 * Set a write lock on the whole file
142 */
143 if (do_lock(F_SETLK, (short)F_WRLCK, (short)0, 0, 0) < 0) {
144 tst_resm(TFAIL, "fcntl on file %s failed, errno =%d",
145 file, errno);
146 fail = 1;
147 }
148
149 /*
150 * Test to make sure its there
151 */
152 do_test(&tl, (short)F_WRLCK, (short)0, 0, 0);
153 compare_lock(&tl, (short)F_WRLCK, (short)0, 0, 0, parent_pid);
154
155 /*
156 * remove the lock set above
157 */
158 unlock_file();
159
160 if (fail) {
161 tst_resm(TINFO, "Test block 2: FAILED");
162 } else {
163 tst_resm(TINFO, "Test block 2: PASSED");
164 }
165
166 tst_resm(TINFO, "Exit block 2");
167
168block3:
169 tst_resm(TINFO, "Enter block 3");
170 fail = 0;
171
172 /*
173 * Add a read lock to the middle of the file and a write
174 * at the begining
175 */
176 if (do_lock(F_SETLK, (short)F_RDLCK, (short)0, 10, 5) < 0) {
177 tst_resm(TFAIL, "fcntl on file %s failed, errno =%d",
178 file, errno);
179 fail = 1;
180 }
181
182 if (do_lock(F_SETLK, (short)F_WRLCK, (short)0, 1, 5) < 0) {
183 tst_resm(TFAIL, "fcntl on file %s failed, errno =%d",
184 file, errno);
185 fail = 1;
186 }
187
188 /*
189 * Test write lock
190 */
191 do_test(&tl, F_WRLCK, 0, 0, 0);
192 compare_lock(&tl, (short)F_WRLCK, (short)0, 1, 5, parent_pid);
193
194 /*
195 * Test read lock
196 */
197 do_test(&tl, F_WRLCK, 0, 6, 0);
198 compare_lock(&tl, (short)F_RDLCK, (short)0, 10, 5, parent_pid);
199
200 /*
201 * Test that the rest of the file is unlocked
202 */
203 do_test(&tl, F_WRLCK, 0, 15, 0);
204 compare_lock(&tl, (short)F_UNLCK, (short)0, 15, 0, 0);
205
206 /*
207 * remove all the locks set above
208 */
209 unlock_file();
210
211 if (fail) {
212 tst_resm(TINFO, "Test block 3: FAILED");
213 } else {
214 tst_resm(TINFO, "Test block 3 : PASSED");
215 }
216 tst_resm(TINFO, "Exit block 3");
217
218block4:
219 tst_resm(TINFO, "Enter block 4");
220 fail = 0;
221
222 /*
223 * Set a read lock at the middle of the file and a
224 * write lock just before
225 */
226 if (do_lock(F_SETLK, (short)F_RDLCK, (short)0, 10, 5) < 0) {
227 tst_resm(TFAIL, "fcntl on file %s failed, errno =%d",
228 file, errno);
229 fail = 1;
230 }
231
232 if (do_lock(F_SETLK, (short)F_WRLCK, (short)0, 5, 5) < 0) {
233 tst_resm(TFAIL, "fcntl on file %s failed, errno =%d",
234 file, errno);
235 fail = 1;
236 }
237
238 /*
239 * Test the write lock
240 */
241 do_test(&tl, (short)F_WRLCK, (short)0, 0, 0);
242 compare_lock(&tl, (short)F_WRLCK, (short)0, 5, 5, parent_pid);
243
244 /*
245 * Test the read lock.
246 */
247 do_test(&tl, (short)F_WRLCK, (short)0, 10, 0);
248 compare_lock(&tl, (short)F_RDLCK, (short)0, 10, 5, parent_pid);
249
250 /*
251 * Test to make sure the rest of the file is unlocked.
252 */
253 do_test(&tl, (short)F_WRLCK, (short)0, 15, 0);
254 compare_lock(&tl, (short)F_UNLCK, (short)0, 15, 0, 0);
255
256 /*
257 * remove all the locks set above
258 */
259 unlock_file();
260
261 if (fail) {
262 tst_resm(TINFO, "Test block 4: FAILED");
263 } else {
264 tst_resm(TINFO, "Test block 4: PASSED");
265 }
266 tst_resm(TINFO, "Exit block 4");
267
268block5:
269 tst_resm(TINFO, "Enter block 5");
270 fail = 0;
271
272 /*
273 * Set a read lock in the middle and a write lock that
274 * ends at the first byte of the read lock
275 */
276 if (do_lock(F_SETLK, (short)F_RDLCK, (short)0, 10, 5) < 0) {
277 tst_resm(TFAIL, "fcntl on file %s failed, errno =%d",
278 file, errno);
279 fail = 1;
280 }
281
282 if (do_lock(F_SETLK, (short)F_WRLCK, (short)0, 5, 6) < 0) {
283 tst_resm(TFAIL, "fcntl on file %s failed, errno =%d",
284 file, errno);
285 fail = 1;
286 }
287
288 /*
289 * Test write lock
290 */
291 do_test(&tl, (short)F_WRLCK, (short)0, 0, 0);
292 compare_lock(&tl, (short)F_WRLCK, (short)0, 5, 6, parent_pid);
293
294 /*
295 * Test read lock
296 */
297 do_test(&tl, (short)F_WRLCK, (short)0, 11, 0);
298 compare_lock(&tl, (short)F_RDLCK, (short)0, 11, 4, parent_pid);
299
300 /*
301 * Test to make sure the rest of the file is unlocked.
302 */
303 do_test(&tl, (short)F_WRLCK, (short)0, 15, 0);
304 compare_lock(&tl, (short)F_UNLCK, (short)0, 15, 0, 0);
305
306 /*
307 * remove all the locks set above
308 */
309 unlock_file();
310
311 if (fail) {
312 tst_resm(TINFO, "Test block 5: FAILED");
313 } else {
314 tst_resm(TINFO, "Test block 5: PASSED");
315 }
316 tst_resm(TINFO, "Exit block 5");
317
318block6:
319 tst_resm(TINFO, "Enter block 6");
320 fail = 0;
321
322 /*
323 * Set a read lock on the middle of the file and a write
324 * lock that overlaps the front of the read.
325 */
326 if (do_lock(F_SETLK, (short)F_RDLCK, (short)0, 10, 5) < 0) {
327 tst_resm(TFAIL, "fcntl on file %s failed, errno =%d",
328 file, errno);
329 fail = 1;
330 }
331
332 if (do_lock(F_SETLK, (short)F_WRLCK, (short)0, 5, 8) < 0) {
333 tst_resm(TFAIL, "fcntl on file %s failed, errno =%d",
334 file, errno);
335 fail = 1;
336 }
337
338 /*
339 * Test the write lock
340 */
341 do_test(&tl, (short)F_WRLCK, (short)0, 5, 0);
342 compare_lock(&tl, (short)F_WRLCK, (short)0, 5, 8, parent_pid);
343
344 /*
345 * Test the read lock
346 */
347 do_test(&tl, (short)F_WRLCK, (short)0, 13, 0);
348 compare_lock(&tl, (short)F_RDLCK, (short)0, 13, 2, parent_pid);
349
350 /*
351 * Test to make sure the rest of the file is unlocked.
352 */
353 do_test(&tl, (short)F_WRLCK, (short)0, 15, 0);
354 compare_lock(&tl, (short)F_UNLCK, (short)0, 15, 0, 0);
355
356 /*
357 * remove all the locks set above
358 */
359 unlock_file();
360
361 if (fail) {
362 tst_resm(TINFO, "Test block 6 FAILED");
363 } else {
364 tst_resm(TINFO, "Test block 6 PASSED");
365 }
366 tst_resm(TINFO, "Exit block 6");
367
368block7:
369 tst_resm(TINFO, "Enter block 7");
370 fail = 0;
371
372 /*
373 * Set a read lock in the middle of a file and a write
374 * lock in the middle of it
375 */
376 if (do_lock(F_SETLK, (short)F_RDLCK, (short)0, 10, 10) < 0) {
377 tst_resm(TFAIL, "fcntl on file %s failed, errno =%d",
378 file, errno);
379 fail = 1;
380 }
381
382 if (do_lock(F_SETLK, (short)F_WRLCK, (short)0, 13, 5) < 0) {
383 tst_resm(TFAIL, "fcntl on file %s failed, errno =%d",
384 file, errno);
385 fail = 1;
386 }
387
388 /*
389 * Test the first read lock
390 */
391 do_test(&tl, (short)F_WRLCK, (short)0 , 0, 0);
392 compare_lock(&tl, (short)F_RDLCK, (short)0, 10, 3, parent_pid);
393
394 /*
395 * Test the write lock
396 */
397 do_test(&tl, (short)F_WRLCK, (short)0, 13, 0);
398 compare_lock(&tl, (short)F_WRLCK, (short)0, 13, 5, parent_pid);
399
400 /*
401 * Test the second read lock
402 */
403 do_test(&tl, (short)F_WRLCK, (short)0, 18, 0);
404 compare_lock(&tl, (short)F_RDLCK, (short)0, 18, 2, parent_pid);
405
406 /*
407 * Test to make sure the rest of the file is unlocked
408 */
409 do_test(&tl, (short)F_WRLCK, (short)0, 20, 0);
410 compare_lock(&tl, (short)F_UNLCK, (short)0, 20, 0, 0);
411
412 /*
413 * remove all the locks set above.
414 */
415 unlock_file();
416 if (fail) {
417 tst_resm(TINFO, "Test block 7: FAILED");
418 } else {
419 tst_resm(TINFO, "Test block 7: PASSED");
420 }
421 tst_resm(TINFO, "Exit block 7");
422
423block8:
424 tst_resm(TINFO, "Enter block 8");
425 fail = 0;
426 /*
427 * Set a read lock in the middle of the file and a write
428 * lock that overlaps the end
429 */
430 if (do_lock(F_SETLK, (short)F_RDLCK, (short)0, 10, 5) < 0) {
431 tst_resm(TFAIL, "fcntl on file %s failed, errno =%d",
432 file, errno);
433 fail = 1;
434 }
435
436 /*
437 * Set a write lock on the whole file
438 */
439 if (do_lock(F_SETLK, (short)F_WRLCK, (short)0, 13, 5) < 0) {
440 tst_resm(TFAIL, "fcntl on file %s failed, errno =%d",
441 file, errno);
442 fail = 1;
443 }
444
445 /*
446 * Test the read lock
447 */
448 do_test(&tl, (short)F_WRLCK, (short)0, 0, 0);
449 compare_lock(&tl, (short)F_RDLCK, (short)0, 10, 3, parent_pid);
450
451 /*
452 * Test the write lock
453 */
454 do_test(&tl, (short)F_WRLCK, (short)0, 13, 0);
455 compare_lock(&tl, (short)F_WRLCK, (short)0, 13, 5, parent_pid);
456
457 /*
458 * Test to make sure the rest of the file is unlocked
459 */
460 do_test(&tl, (short)F_WRLCK, (short)0, 18, 0);
461 compare_lock(&tl, (short)F_UNLCK, (short)0, 18, 0, 0);
462
463 /*
464 * remove all the locks set above
465 */
466 unlock_file();
467
468 if (fail) {
469 tst_resm(TINFO, "Test block 8: FAILED");
470 } else {
471 tst_resm(TINFO, "Test block 8: PASSED");
472 }
473 tst_resm(TINFO, "Exit block 8");
474
475block9:
476 tst_resm(TINFO, "Enter block 9");
477 fail = 0;
478
479 /*
480 * Set a read lock in the middle of the file and a write
481 * lock starting at the last byte of the read lock
482 */
483 if (do_lock(F_SETLK, (short)F_RDLCK, (short)0, 10, 5) < 0) {
484 tst_resm(TFAIL, "fcntl on file %s failed, errno =%d",
485 file, errno);
486 fail = 1;
487 }
488
489 /*
490 * Set a write lock on the whole file.
491 */
492 if (do_lock(F_SETLK, (short)F_WRLCK, (short)0, 14, 5) < 0) {
493 tst_resm(TFAIL, "fcntl on file %s failed, errno =%d",
494 file, errno);
495 fail = 1;
496 }
497
498 /*
499 * Test read lock
500 */
501 do_test(&tl, (short)F_WRLCK, (short)0, 0, 0);
502 compare_lock(&tl, (short)F_RDLCK, (short)0, 10, 4, parent_pid);
503
504 /*
505 * Test the write lock
506 */
507 do_test(&tl, (short)F_WRLCK, (short)0, 14, 0);
508 compare_lock(&tl, (short)F_WRLCK, (short)0, 14, 5, parent_pid);
509
510 /*
511 * Test to make sure the end of the file is unlocked
512 */
513 do_test(&tl, (short)F_WRLCK, (short)0, 19, 0);
514 compare_lock(&tl, (short)F_UNLCK, (short)0, 19, 0, 0);
515
516 /*
517 * remove all the locks set above
518 */
519 unlock_file();
520
521 if (fail) {
522 tst_resm(TINFO, "Test block 9: FAILED");
523 } else {
524 tst_resm(TINFO, "Test block 9: PASSED");
525 }
526 tst_resm(TINFO, "Exit block 9");
527
528block10:
529 tst_resm(TINFO, "Enter block 10");
530 fail = 0;
531
532 /*
533 * Set a read lock in the middle of the file and a write
534 * lock that starts just after the last byte of the
535 * read lock.
536 */
537 if (do_lock(F_SETLK, (short)F_RDLCK, (short)0, 10, 5) < 0) {
538 tst_resm(TFAIL, "fcntl on file %s failed, errno =%d",
539 file, errno);
540 fail = 1;
541 }
542
543 /*
544 * Set a write lock on the whole file
545 */
546 if (do_lock(F_SETLK, (short)F_WRLCK, (short)0, 15, 5) < 0) {
547 tst_resm(TFAIL, "fcntl on file %s failed, errno =%d",
548 file, errno);
549 fail = 1;
550 }
551
552 /*
553 * Test the read lock
554 */
555 do_test(&tl, (short)F_WRLCK, (short)0, 0, 0);
556 compare_lock(&tl, (short)F_RDLCK, (short)0, 10, 5, parent_pid);
557
558 /*
559 * Test the write lock
560 */
561 do_test(&tl, (short)F_WRLCK, (short)0, 15, 0);
562 compare_lock(&tl, (short)F_WRLCK, (short)0, 15, 5, parent_pid);
563
564 /*
565 * Test to make sure the rest of the file is unlocked
566 */
567 do_test(&tl, (short)F_WRLCK, (short)0, 20, 0);
568 compare_lock(&tl, (short)F_UNLCK, (short)0, 20, 0, 0);
569
570 /*
571 * remove all the locks set above
572 */
573 unlock_file();
574
575 if (fail) {
576 tst_resm(TINFO, "Test block 10: FAILED");
577 } else {
578 tst_resm(TINFO, "Test block 10: PASSED");
579 }
580 tst_resm(TINFO, "Exit block 10");
581
582block11:
583 tst_resm(TINFO, "Enter block 11");
584 fail = 0;
585
586 /*
587 * Set a read lock at the middle of the file and a write
588 * lock that starts past the end of the read lock.
589 */
590 if (do_lock(F_SETLK, (short)F_RDLCK, (short)0, 10, 5) < 0) {
591 tst_resm(TFAIL, "fcntl on file %s failed, errno =%d",
592 file, errno);
593 fail = 1;
594 }
595
596 if (do_lock(F_SETLK, (short)F_WRLCK, (short)0, 16, 5) < 0) {
597 tst_resm(TFAIL, "fcntl on file %s failed, errno =%d",
598 file, errno);
599 fail = 1;
600 }
601
602 /*
603 * Test the read lock
604 */
605 do_test(&tl, (short)F_WRLCK, (short)0, 0, 0);
606 compare_lock(&tl, (short)F_RDLCK, (short)0, 10, 5, parent_pid);
607
608 /*
609 * Test that byte in between is unlocked
610 */
611 do_test(&tl, (short)F_WRLCK, (short)0, 15, 1);
612 compare_lock(&tl, (short)F_UNLCK, (short)0, 15, 1, 0);
613
614 /*
615 * Test the write lock
616 */
617 do_test(&tl, (short)F_WRLCK, (short)0, 16, 0);
618 compare_lock(&tl, (short)F_WRLCK, (short)0, 16, 5, parent_pid);
619
620 /*
621 * Test to make sure the rest of the file is unlocked
622 */
623 do_test(&tl, (short)F_WRLCK, (short)0, 21, 0);
624 compare_lock(&tl, (short)F_UNLCK, (short)0, 21, 0, 0);
625
626 /*
627 * remove all the locks set above
628 */
629 unlock_file();
630
631 if (fail) {
632 tst_resm(TINFO, "Test block 11: FAILED");
633 } else {
634 tst_resm(TINFO, "Test block 11: PASSED");
635 }
636 tst_resm(TINFO, "Exit block 11");
637
638 stop_child();
639 close(fd);
640 }
641 cleanup();
642}
643
644/*
645 * setup
646 * performs all ONE TIME setup for this test
647 */
648void
649setup()
650{
651 char *buf = STRING;
652
653 /* capture signals */
654 tst_sig(FORK, DEF_HANDLER, cleanup);
655
656 umask(0);
657
658 /* Pause if that option was specified */
659 TEST_PAUSE;
660
661 pipe(parent_pipe);
662 pipe(child_pipe);
663 parent_pid = getpid();
664 file = tempnam(".", NULL);
665
666 if ((fd = open(file, O_RDWR|O_CREAT, 0777)) < 0) {
667 tst_resm(TFAIL, "Couldn't open %s! errno = %d", file, errno);
668 fail = 1;
669 }
670
671 if (write(fd, buf, STRINGSIZE) < 0) {
672 tst_resm(TFAIL, "Couldn't write %s! errno = %d", file, errno);
673 fail = 1;
674 }
675
plars95391832002-06-12 17:05:08 +0000676 if ((signal(SIGCLD, catch_child)) == SIG_ERR) {
plars865695b2001-08-27 22:15:12 +0000677 tst_resm(TFAIL, "SIGCLD signal setup failed, errno: %d",
678 errno);
679 fail = 1;
680 }
681}
682
683/*
684 * cleanup()
685 * performs all ONE TIME cleanup for this test at completion or
686 * premature exit
687 */
688void
689cleanup()
690{
691 /*
692 * print timing stats if that option was specified
693 * print errno log if that option was specified
694 */
695 TEST_CLEANUP;
696
697 unlink(file);
698
699 /* exit with return code appropriate for results */
700 tst_exit();
701}
702
703do_child()
704{
705 struct flock fl;
706
707 close(parent_pipe[1]);
708 close(child_pipe[0]);
709 while(1) {
710 child_get(&fl);
711 if (fcntl(fd, F_GETLK, &fl) < 0) {
712 tst_resm(TFAIL, "fcntl on file %s failed, errno =%d",
713 file, errno);
714 fail = 1;
715 }
716 child_put(&fl);
717 }
718}
719
720do_lock(int cmd, short type, short whence, int start, int len)
721{
722 struct flock fl;
723
724 fl.l_type = type;
725 fl.l_whence = whence;
726 fl.l_start = start;
727 fl.l_len = len;
728 return(fcntl(fd, cmd, &fl));
729}
730
731void
732do_test(struct flock *fl, short type, short whence, int start, int len)
733{
734 fl->l_type = type;
735 fl->l_whence = whence;
736 fl->l_start = start;
737 fl->l_len = len;
738 fl->l_pid = (short)0;
739
740 parent_put(fl);
741 parent_get(fl);
742}
743
744void
745compare_lock(struct flock *fl, short type, short whence, int start, int len,
plarsa1e518d2002-09-09 18:23:52 +0000746 pid_t pid)
plars865695b2001-08-27 22:15:12 +0000747{
748 if (fl->l_type != type) {
749 tst_resm(TFAIL, "lock type is wrong should be %s is %s",
750 str_type(type), str_type(fl->l_type));
751 fail = 1;
752 }
753
754 if (fl->l_whence != whence) {
755 tst_resm(TFAIL, "lock whence is wrong should be %d is %d",
756 whence, fl->l_whence);
757 fail = 1;
758 }
759
760 if (fl->l_start != start) {
761 tst_resm(TFAIL, "region starts in wrong place, should be"
762 "%d is %d", start, fl->l_start);
763 fail = 1;
764 }
765
766 if (fl->l_len != len) {
767 tst_resm(TFAIL, "region length is wrong, should be %d is %d",
768 len, fl->l_len);
769 fail = 1;
770 }
771
772 if (fl->l_pid != pid) {
773 tst_resm(TFAIL, "locking pid is wrong, should be %d is %d",
774 pid, fl->l_pid);
775 fail = 1;
776 }
777}
778
779void
780unlock_file()
781{
782 struct flock fl;
783
784 if (do_lock(F_SETLK, (short)F_UNLCK, (short)0, 0, 0) < 0) {
785 tst_resm(TFAIL, "fcntl on file %s failed, errno =%d", file,
786 errno);
787 fail = 1;
788 }
789 do_test(&fl, F_WRLCK, 0, 0, 0);
plarsa1e518d2002-09-09 18:23:52 +0000790 compare_lock(&fl, (short)F_UNLCK, (short)0, 0, 0, (pid_t)0);
plars865695b2001-08-27 22:15:12 +0000791}
792
793char *
794str_type(int type)
795{
796 static char buf[20];
797
798 switch (type) {
799 case 1:
800 return("F_RDLCK");
801 case 2:
802 return("F_WRLCK");
803 case 3:
804 return("F_UNLCK");
805 default:
806 sprintf(buf, "BAD VALUE: %d", type);
807 return(buf);
808 }
809}
810
811void
812parent_put(struct flock *l)
813{
814 if (write(parent_pipe[1], l, sizeof(*l)) != sizeof(*l)) {
815 tst_resm(TFAIL, "couldn't send message to child");
816 fail = 1;
817 }
818}
819
820void
821parent_get(struct flock *l)
822{
823 if (read(child_pipe[0], l, sizeof(*l)) != sizeof(*l)) {
824 tst_resm(TFAIL, "couldn't get message from child");
825 fail = 1;
826 }
827}
828
829void
830child_put(struct flock *l)
831{
832 if (write(child_pipe[1], l, sizeof(*l)) != sizeof(*l)) {
833 tst_resm(TFAIL, "couldn't send message to parent");
834 fail = 1;
835 }
836}
837
838void
839child_get(struct flock *l)
840{
841 if (read(parent_pipe[0], l, sizeof(*l)) != sizeof(*l)) {
842 tst_resm(TFAIL, "couldn't get message from parent");
843 cleanup();
844 } else if (l->l_type == (short)STOP) {
845 exit(0);
846 }
847}
848
849void
850stop_child()
851{
852 struct flock fl;
853
854 (void) signal(SIGCLD, (void (*)())SIG_DFL);
855 fl.l_type = STOP;
856 parent_put(&fl);
857 wait(0);
858}
859
860void
861catch_child()
862{
863 tst_resm(TFAIL, "Unexpected death of child process");
864 cleanup();
865}