xref: /openbsd-src/regress/sys/kern/flock/flock.c (revision 46035553bfdd96e63c94e32da0210227ec2e3cf1)
1 /*-
2  * Copyright (c) 2008 Isilon Inc http://www.isilon.com/
3  * Authors: Doug Rabson <dfr@rabson.org>
4  * Developed with Red Inc: Alfred Perlstein <alfred@freebsd.org>
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  * $FreeBSD: src/tools/regression/file/flock/flock.c,v 1.3 2008/06/26 10:21:54 dfr Exp $
28  */
29 
30 #include <sys/time.h>
31 #include <sys/stat.h>
32 
33 #include <err.h>
34 #include <errno.h>
35 #include <fcntl.h>
36 #include <limits.h>
37 #include <signal.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <unistd.h>
42 
43 #include "util.h"
44 
45 int verbose = 0;
46 
47 static void
48 ignore_alarm(int __unused sig)
49 {
50 }
51 
52 static int
53 safe_kill(pid_t pid, int sig)
54 {
55 	int save_errno;
56 	int status;
57 
58 	save_errno = errno;
59 	errno = 0;
60 	status = kill(pid, sig);
61 	errno = save_errno;
62 
63 	return (status);
64 }
65 
66 /*
67  * Test 1 - F_GETLK on unlocked region
68  *
69  * If no lock is found that would prevent this lock from being
70  * created, the structure is left unchanged by this function call
71  * except for the lock type which is set to F_UNLCK.
72  */
73 static int
74 test1(int fd)
75 {
76 	struct flock fl1, fl2;
77 
78 	memset(&fl1, 1, sizeof(fl1));
79 	fl1.l_type = F_WRLCK;
80 	fl1.l_whence = SEEK_SET;
81 	fl2 = fl1;
82 
83 	if (fcntl(fd, F_GETLK, &fl1) < 0)
84 		err(1, "F_GETLK");
85 
86 	if (verbose) printf("1 - F_GETLK on unlocked region: ");
87 	FAIL(fl1.l_start != fl2.l_start);
88 	FAIL(fl1.l_len != fl2.l_len);
89 	FAIL(fl1.l_pid != fl2.l_pid);
90 	FAIL(fl1.l_type != F_UNLCK);
91 	FAIL(fl1.l_whence != fl2.l_whence);
92 
93 	SUCCEED;
94 }
95 
96 /*
97  * Test 2 - F_SETLK on locked region
98  *
99  * If a shared or exclusive lock cannot be set, fcntl returns
100  * immediately with EACCES or EAGAIN.
101  */
102 static int
103 test2(int fd)
104 {
105 	/*
106 	 * We create a child process to hold the lock which we will
107 	 * test. We use a pipe to communicate with the child.
108 	 */
109 	int pid;
110 	int pfd[2];
111 	struct flock fl;
112 	char ch;
113 	int res;
114 
115 	if (pipe(pfd) < 0)
116 		err(1, "pipe");
117 
118 	fl.l_start = 0;
119 	fl.l_len = 0;
120 	fl.l_type = F_WRLCK;
121 	fl.l_whence = SEEK_SET;
122 
123 	pid = fork();
124 	if (pid < 0)
125 		err(1, "fork");
126 
127 	if (pid == 0) {
128 		/*
129 		 * We are the child. We set a write lock and then
130 		 * write one byte back to the parent to tell it. The
131 		 * parent will kill us when its done.
132 		 */
133 		if (fcntl(fd, F_SETLK, &fl) < 0)
134 			err(1, "F_SETLK (child)");
135 		if (write(pfd[1], "a", 1) < 0)
136 			err(1, "writing to pipe (child)");
137 		pause();
138 		exit(0);
139 	}
140 
141 	/*
142 	 * Wait until the child has set its lock and then perform the
143 	 * test.
144 	 */
145 	if (read(pfd[0], &ch, 1) != 1)
146 		err(1, "reading from pipe (child)");
147 
148 	/*
149 	 * fcntl should return -1 with errno set to either EACCES or
150 	 * EAGAIN.
151 	 */
152 	if (verbose) printf("2 - F_SETLK on locked region: ");
153 	res = fcntl(fd, F_SETLK, &fl);
154 	safe_kill(pid, SIGTERM);
155 	safe_waitpid(pid);
156 	close(pfd[0]);
157 	close(pfd[1]);
158 	FAIL(res == 0);
159 	FAIL(errno != EACCES && errno != EAGAIN);
160 
161 	SUCCEED;
162 }
163 
164 /*
165  * Test 3 - F_SETLKW on locked region
166  *
167  * If a shared or exclusive lock is blocked by other locks, the
168  * process waits until the request can be satisfied.
169  *
170  * XXX this test hangs on FreeBSD NFS filesystems due to limitations
171  * in FreeBSD's client (and server) lockd implementation.
172  */
173 static int
174 test3(int fd)
175 {
176 	/*
177 	 * We create a child process to hold the lock which we will
178 	 * test. We use a pipe to communicate with the child.
179 	 */
180 	int pid;
181 	int pfd[2];
182 	struct flock fl;
183 	char ch;
184 	int res;
185 
186 	if (pipe(pfd) < 0)
187 		err(1, "pipe");
188 
189 	fl.l_start = 0;
190 	fl.l_len = 0;
191 	fl.l_type = F_WRLCK;
192 	fl.l_whence = SEEK_SET;
193 
194 	pid = fork();
195 	if (pid < 0)
196 		err(1, "fork");
197 
198 	if (pid == 0) {
199 		/*
200 		 * We are the child. We set a write lock and then
201 		 * write one byte back to the parent to tell it. The
202 		 * parent will kill us when its done.
203 		 */
204 		if (fcntl(fd, F_SETLK, &fl) < 0)
205 			err(1, "F_SETLK (child)");
206 		if (write(pfd[1], "a", 1) < 0)
207 			err(1, "writing to pipe (child)");
208 		pause();
209 		exit(0);
210 	}
211 
212 	/*
213 	 * Wait until the child has set its lock and then perform the
214 	 * test.
215 	 */
216 	if (read(pfd[0], &ch, 1) != 1)
217 		err(1, "reading from pipe (child)");
218 
219 	/*
220 	 * fcntl should wait until the alarm and then return -1 with
221 	 * errno set to EINTR.
222 	 */
223 	if (verbose) printf("3 - F_SETLKW on locked region: ");
224 
225 	alarm(1);
226 
227 	res = fcntl(fd, F_SETLKW, &fl);
228 	safe_kill(pid, SIGTERM);
229 	safe_waitpid(pid);
230 	close(pfd[0]);
231 	close(pfd[1]);
232 	FAIL(res == 0);
233 	FAIL(errno != EINTR);
234 
235 	SUCCEED;
236 }
237 
238 /*
239  * Test 4 - F_GETLK on locked region
240  *
241  * Get the first lock that blocks the lock.
242  */
243 static int
244 test4(int fd)
245 {
246 	/*
247 	 * We create a child process to hold the lock which we will
248 	 * test. We use a pipe to communicate with the child.
249 	 */
250 	int pid;
251 	int pfd[2];
252 	struct flock fl;
253 	char ch;
254 
255 	if (pipe(pfd) < 0)
256 		err(1, "pipe");
257 
258 	fl.l_start = 0;
259 	fl.l_len = 99;
260 	fl.l_type = F_WRLCK;
261 	fl.l_whence = SEEK_SET;
262 
263 	pid = fork();
264 	if (pid < 0)
265 		err(1, "fork");
266 
267 	if (pid == 0) {
268 		/*
269 		 * We are the child. We set a write lock and then
270 		 * write one byte back to the parent to tell it. The
271 		 * parent will kill us when its done.
272 		 */
273 		if (fcntl(fd, F_SETLK, &fl) < 0)
274 			err(1, "F_SETLK (child)");
275 		if (write(pfd[1], "a", 1) < 0)
276 			err(1, "writing to pipe (child)");
277 		pause();
278 		exit(0);
279 	}
280 
281 	/*
282 	 * Wait until the child has set its lock and then perform the
283 	 * test.
284 	 */
285 	if (read(pfd[0], &ch, 1) != 1)
286 		err(1, "reading from pipe (child)");
287 
288 	/*
289 	 * fcntl should return a lock structure reflecting the lock we
290 	 * made in the child process.
291 	 */
292 	if (fcntl(fd, F_GETLK, &fl) < 0)
293 		err(1, "F_GETLK");
294 
295 	if (verbose) printf("4 - F_GETLK on locked region: ");
296 	FAIL(fl.l_start != 0);
297 	FAIL(fl.l_len != 99);
298 	FAIL(fl.l_type != F_WRLCK);
299 	FAIL(fl.l_pid != pid);
300 
301 	safe_kill(pid, SIGTERM);
302 	safe_waitpid(pid);
303 	close(pfd[0]);
304 	close(pfd[1]);
305 
306 	SUCCEED;
307 }
308 
309 /*
310  * Test 5 - F_SETLKW simple deadlock
311  *
312  * If a blocking shared lock request would cause a deadlock (i.e. the
313  * lock request is blocked by a process which is itself blocked on a
314  * lock currently owned by the process making the new request),
315  * EDEADLK is returned.
316  */
317 static int
318 test5(int fd)
319 {
320 	/*
321 	 * We create a child process to hold the lock which we will
322 	 * test. Because our test relies on the child process being
323 	 * blocked on the parent's lock, we can't easily use a pipe to
324 	 * synchronize so we just sleep in the parent to given the
325 	 * child a chance to setup.
326 	 *
327 	 * To create the deadlock condition, we arrange for the parent
328 	 * to lock the first byte of the file and the child to lock
329 	 * the second byte.  After locking the second byte, the child
330 	 * will attempt to lock the first byte of the file, and
331 	 * block. The parent will then attempt to lock the second byte
332 	 * (owned by the child) which should cause deadlock.
333 	 */
334 	int pid;
335 	struct flock fl;
336 	int res;
337 
338 	/*
339 	 * Lock the first byte in the parent.
340 	 */
341 	fl.l_start = 0;
342 	fl.l_len = 1;
343 	fl.l_type = F_WRLCK;
344 	fl.l_whence = SEEK_SET;
345 	if (fcntl(fd, F_SETLK, &fl) < 0)
346 		err(1, "F_SETLK 1 (parent)");
347 
348 	pid = fork();
349 	if (pid < 0)
350 		err(1, "fork");
351 
352 	if (pid == 0) {
353 		/*
354 		 * Lock the second byte in the child and then block on
355 		 * the parent's lock.
356 		 */
357 		fl.l_start = 1;
358 		if (fcntl(fd, F_SETLK, &fl) < 0)
359 			err(1, "F_SETLK (child)");
360 		fl.l_start = 0;
361 		if (fcntl(fd, F_SETLKW, &fl) < 0)
362 			err(1, "F_SETLKW (child)");
363 		exit(0);
364 	}
365 
366 	/*
367 	 * Wait until the child has set its lock and then perform the
368 	 * test.
369 	 */
370 	sleep(1);
371 
372 	/*
373 	 * fcntl should immediately return -1 with errno set to
374 	 * EDEADLK. If the alarm fires, we failed to detect the
375 	 * deadlock.
376 	 */
377 	alarm(1);
378 	if (verbose) printf("5 - F_SETLKW simple deadlock: ");
379 
380 	fl.l_start = 1;
381 	res = fcntl(fd, F_SETLKW, &fl);
382 	safe_kill(pid, SIGTERM);
383 	safe_waitpid(pid);
384 
385 	FAIL(res == 0);
386 	FAIL(errno != EDEADLK);
387 
388 	fl.l_start = 0;
389 	fl.l_len = 0;
390 	fl.l_type = F_UNLCK;
391 	if (fcntl(fd, F_SETLK, &fl) < 0)
392 		err(1, "F_UNLCK");
393 
394 	/*
395 	 * Cancel the alarm to avoid confusing later tests.
396 	 */
397 	alarm(0);
398 
399 	SUCCEED;
400 }
401 
402 /*
403  * Test 6 - F_SETLKW complex deadlock.
404  *
405  * This test involves three process, P, C1 and C2. We set things up so
406  * that P locks byte zero, C1 locks byte 1 and C2 locks byte 2. We
407  * also block C2 by attempting to lock byte zero. Lastly, P attempts
408  * to lock a range including byte 1 and 2. This represents a deadlock
409  * (due to C2's blocking attempt to lock byte zero).
410  */
411 static int
412 test6(int fd)
413 {
414 	/*
415 	 * Because our test relies on the child process being blocked
416 	 * on the parent's lock, we can't easily use a pipe to
417 	 * synchronize so we just sleep in the parent to given the
418 	 * children a chance to setup.
419 	 */
420 	int pid1, pid2;
421 	struct flock fl;
422 	int res;
423 
424 	/*
425 	 * Lock the first byte in the parent.
426 	 */
427 	fl.l_start = 0;
428 	fl.l_len = 1;
429 	fl.l_type = F_WRLCK;
430 	fl.l_whence = SEEK_SET;
431 	if (fcntl(fd, F_SETLK, &fl) < 0)
432 		err(1, "F_SETLK 1 (parent)");
433 
434 	pid1 = fork();
435 	if (pid1 < 0)
436 		err(1, "fork");
437 
438 	if (pid1 == 0) {
439 		/*
440 		 * C1
441 		 * Lock the second byte in the child and then sleep
442 		 */
443 		fl.l_start = 1;
444 		if (fcntl(fd, F_SETLK, &fl) < 0)
445 			err(1, "F_SETLK (child1)");
446 		pause();
447 		exit(0);
448 	}
449 
450 	pid2 = fork();
451 	if (pid2 < 0)
452 		err(1, "fork");
453 
454 	if (pid2 == 0) {
455 		/*
456 		 * C2
457 		 * Lock the third byte in the child and then block on
458 		 * the parent's lock.
459 		 */
460 		fl.l_start = 2;
461 		if (fcntl(fd, F_SETLK, &fl) < 0)
462 			err(1, "F_SETLK (child2)");
463 		fl.l_start = 0;
464 		if (fcntl(fd, F_SETLKW, &fl) < 0)
465 			err(1, "F_SETLKW (child2)");
466 		exit(0);
467 	}
468 
469 	/*
470 	 * Wait until the children have set their locks and then
471 	 * perform the test.
472 	 */
473 	sleep(1);
474 
475 	/*
476 	 * fcntl should immediately return -1 with errno set to
477 	 * EDEADLK. If the alarm fires, we failed to detect the
478 	 * deadlock.
479 	 */
480 	alarm(1);
481 	if (verbose) printf("6 - F_SETLKW complex deadlock: ");
482 
483 	fl.l_start = 1;
484 	fl.l_len = 2;
485 	res = fcntl(fd, F_SETLKW, &fl);
486 	safe_kill(pid1, SIGTERM);
487 	safe_waitpid(pid1);
488 	safe_kill(pid2, SIGTERM);
489 	safe_waitpid(pid2);
490 
491 	fl.l_start = 0;
492 	fl.l_len = 0;
493 	fl.l_type = F_UNLCK;
494 	if (fcntl(fd, F_SETLK, &fl) < 0)
495 		err(1, "F_UNLCK");
496 
497 	FAIL(res == 0);
498 	FAIL(errno != EDEADLK);
499 
500 	/*
501 	 * Cancel the alarm to avoid confusing later tests.
502 	 */
503 	alarm(0);
504 
505 	SUCCEED;
506 }
507 
508 /*
509  * Test 7 - F_SETLK shared lock on exclusive locked region
510  *
511  * If a shared or exclusive lock cannot be set, fcntl returns
512  * immediately with EACCES or EAGAIN.
513  */
514 static int
515 test7(int fd)
516 {
517 	/*
518 	 * We create a child process to hold the lock which we will
519 	 * test. We use a pipe to communicate with the child.
520 	 */
521 	int pid;
522 	int pfd[2];
523 	struct flock fl;
524 	char ch;
525 	int res;
526 
527 	if (pipe(pfd) < 0)
528 		err(1, "pipe");
529 
530 	fl.l_start = 0;
531 	fl.l_len = 0;
532 	fl.l_type = F_WRLCK;
533 	fl.l_whence = SEEK_SET;
534 
535 	pid = fork();
536 	if (pid < 0)
537 		err(1, "fork");
538 
539 	if (pid == 0) {
540 		/*
541 		 * We are the child. We set a write lock and then
542 		 * write one byte back to the parent to tell it. The
543 		 * parent will kill us when its done.
544 		 */
545 		if (fcntl(fd, F_SETLK, &fl) < 0)
546 			err(1, "F_SETLK (child)");
547 		if (write(pfd[1], "a", 1) < 0)
548 			err(1, "writing to pipe (child)");
549 		pause();
550 		exit(0);
551 	}
552 
553 	/*
554 	 * Wait until the child has set its lock and then perform the
555 	 * test.
556 	 */
557 	if (read(pfd[0], &ch, 1) != 1)
558 		err(1, "reading from pipe (child)");
559 
560 	/*
561 	 * fcntl should wait until the alarm and then return -1 with
562 	 * errno set to EINTR.
563 	 */
564 	if (verbose) printf("7 - F_SETLK shared lock on exclusive locked region: ");
565 
566 	fl.l_type = F_RDLCK;
567 	res = fcntl(fd, F_SETLK, &fl);
568 	safe_kill(pid, SIGTERM);
569 	safe_waitpid(pid);
570 	close(pfd[0]);
571 	close(pfd[1]);
572 
573 	FAIL(res == 0);
574 	FAIL(errno != EACCES && errno != EAGAIN);
575 
576 	SUCCEED;
577 }
578 
579 /*
580  * Test 8 - F_SETLK shared lock on share locked region
581  *
582  * When a shared lock is set on a segment of a file, other processes
583  * shall be able to set shared locks on that segment or a portion of
584  * it.
585  */
586 static int
587 test8(int fd)
588 {
589 	/*
590 	 * We create a child process to hold the lock which we will
591 	 * test. We use a pipe to communicate with the child.
592 	 */
593 	int pid;
594 	int pfd[2];
595 	struct flock fl;
596 	char ch;
597 	int res;
598 
599 	if (pipe(pfd) < 0)
600 		err(1, "pipe");
601 
602 	fl.l_start = 0;
603 	fl.l_len = 0;
604 	fl.l_type = F_RDLCK;
605 	fl.l_whence = SEEK_SET;
606 
607 	pid = fork();
608 	if (pid < 0)
609 		err(1, "fork");
610 
611 	if (pid == 0) {
612 		/*
613 		 * We are the child. We set a write lock and then
614 		 * write one byte back to the parent to tell it. The
615 		 * parent will kill us when its done.
616 		 */
617 		if (fcntl(fd, F_SETLK, &fl) < 0)
618 			err(1, "F_SETLK (child)");
619 		if (write(pfd[1], "a", 1) < 0)
620 			err(1, "writing to pipe (child)");
621 		pause();
622 		exit(0);
623 	}
624 
625 	/*
626 	 * Wait until the child has set its lock and then perform the
627 	 * test.
628 	 */
629 	if (read(pfd[0], &ch, 1) != 1)
630 		err(1, "reading from pipe (child)");
631 
632 	/*
633 	 * fcntl should wait until the alarm and then return -1 with
634 	 * errno set to EINTR.
635 	 */
636 	if (verbose) printf("8 - F_SETLK shared lock on share locked region: ");
637 
638 	fl.l_type = F_RDLCK;
639 	res = fcntl(fd, F_SETLK, &fl);
640 
641 	safe_kill(pid, SIGTERM);
642 	safe_waitpid(pid);
643 	close(pfd[0]);
644 	close(pfd[1]);
645 
646 	fl.l_start = 0;
647 	fl.l_len = 0;
648 	fl.l_type = F_UNLCK;
649 	if (fcntl(fd, F_SETLK, &fl) < 0)
650 		err(1, "F_UNLCK");
651 
652 	FAIL(res != 0);
653 
654 	SUCCEED;
655 }
656 
657 /*
658  * Test 9 - F_SETLK exclusive lock on share locked region
659  *
660  * If a shared or exclusive lock cannot be set, fcntl returns
661  * immediately with EACCES or EAGAIN.
662  */
663 static int
664 test9(int fd)
665 {
666 	/*
667 	 * We create a child process to hold the lock which we will
668 	 * test. We use a pipe to communicate with the child.
669 	 */
670 	int pid;
671 	int pfd[2];
672 	struct flock fl;
673 	char ch;
674 	int res;
675 
676 	if (pipe(pfd) < 0)
677 		err(1, "pipe");
678 
679 	fl.l_start = 0;
680 	fl.l_len = 0;
681 	fl.l_type = F_RDLCK;
682 	fl.l_whence = SEEK_SET;
683 
684 	pid = fork();
685 	if (pid < 0)
686 		err(1, "fork");
687 
688 	if (pid == 0) {
689 		/*
690 		 * We are the child. We set a write lock and then
691 		 * write one byte back to the parent to tell it. The
692 		 * parent will kill us when its done.
693 		 */
694 		if (fcntl(fd, F_SETLK, &fl) < 0)
695 			err(1, "F_SETLK (child)");
696 		if (write(pfd[1], "a", 1) < 0)
697 			err(1, "writing to pipe (child)");
698 		pause();
699 		exit(0);
700 	}
701 
702 	/*
703 	 * Wait until the child has set its lock and then perform the
704 	 * test.
705 	 */
706 	if (read(pfd[0], &ch, 1) != 1)
707 		err(1, "reading from pipe (child)");
708 
709 	/*
710 	 * fcntl should wait until the alarm and then return -1 with
711 	 * errno set to EINTR.
712 	 */
713 	if (verbose) printf("9 - F_SETLK exclusive lock on share locked region: ");
714 
715 	fl.l_type = F_WRLCK;
716 	res = fcntl(fd, F_SETLK, &fl);
717 	safe_kill(pid, SIGTERM);
718 	safe_waitpid(pid);
719 	close(pfd[0]);
720 	close(pfd[1]);
721 
722 	FAIL(res == 0);
723 	FAIL(errno != EACCES && errno != EAGAIN);
724 
725 	SUCCEED;
726 }
727 
728 /*
729  * Test 10 - trying to set bogus pid or sysid values
730  *
731  * The l_pid and l_sysid fields are only used with F_GETLK to return
732  * the process ID of the process holding a blocking lock and the
733  * system ID of the system that owns that process
734  */
735 static int
736 test10(int fd)
737 {
738 	/*
739 	 * We create a child process to hold the lock which we will
740 	 * test. We use a pipe to communicate with the child.
741 	 */
742 	int pid;
743 	int pfd[2];
744 	struct flock fl;
745 	char ch;
746 
747 	if (pipe(pfd) < 0)
748 		err(1, "pipe");
749 
750 	fl.l_start = 0;
751 	fl.l_len = 0;
752 	fl.l_type = F_WRLCK;
753 	fl.l_whence = SEEK_SET;
754 	fl.l_pid = 9999;
755 
756 	pid = fork();
757 	if (pid < 0)
758 		err(1, "fork");
759 
760 	if (pid == 0) {
761 		/*
762 		 * We are the child. We set a write lock and then
763 		 * write one byte back to the parent to tell it. The
764 		 * parent will kill us when its done.
765 		 */
766 		if (fcntl(fd, F_SETLK, &fl) < 0)
767 			err(1, "F_SETLK (child)");
768 		if (write(pfd[1], "a", 1) < 0)
769 			err(1, "writing to pipe (child)");
770 		pause();
771 		exit(0);
772 	}
773 
774 	/*
775 	 * Wait until the child has set its lock and then perform the
776 	 * test.
777 	 */
778 	if (read(pfd[0], &ch, 1) != 1)
779 		err(1, "reading from pipe (child)");
780 
781 	if (verbose) printf("10 - trying to set bogus pid or sysid values: ");
782 
783 	if (fcntl(fd, F_GETLK, &fl) < 0)
784 		err(1, "F_GETLK");
785 
786 	safe_kill(pid, SIGTERM);
787 	safe_waitpid(pid);
788 	close(pfd[0]);
789 	close(pfd[1]);
790 
791 	FAIL(fl.l_pid != pid);
792 
793 	SUCCEED;
794 }
795 
796 /*
797  * Test 11 - remote locks
798  *
799  * XXX temporary interface which will be removed when the kernel lockd
800  * is added.
801  */
802 static int
803 test11(int fd)
804 {
805 #ifdef F_SETLK_REMOTE
806 	struct flock fl;
807 	int res;
808 
809 	if (geteuid() != 0)
810 		return 0;
811 
812 	fl.l_start = 0;
813 	fl.l_len = 0;
814 	fl.l_type = F_WRLCK;
815 	fl.l_whence = SEEK_SET;
816 	fl.l_pid = 9999;
817 	fl.l_sysid = 1001;
818 
819 	if (verbose) printf("11 - remote locks: ");
820 
821 	res = fcntl(fd, F_SETLK_REMOTE, &fl);
822 	FAIL(res != 0);
823 
824 	fl.l_sysid = 1002;
825 	res = fcntl(fd, F_SETLK_REMOTE, &fl);
826 	FAIL(res == 0);
827 	FAIL(errno != EACCES && errno != EAGAIN);
828 
829 	res = fcntl(fd, F_GETLK, &fl);
830 	FAIL(res != 0);
831 	FAIL(fl.l_pid != 9999);
832 	FAIL(fl.l_sysid != 1001);
833 
834 	fl.l_type = F_UNLCK;
835 	fl.l_sysid = 1001;
836 	fl.l_start = 0;
837 	fl.l_len = 0;
838 	res = fcntl(fd, F_SETLK_REMOTE, &fl);
839 	FAIL(res != 0);
840 
841 	fl.l_pid = 1234;
842 	fl.l_sysid = 1001;
843 	fl.l_start = 0;
844 	fl.l_len = 1;
845 	fl.l_whence = SEEK_SET;
846 	fl.l_type = F_RDLCK;
847 	res = fcntl(fd, F_SETLK_REMOTE, &fl);
848 	FAIL(res != 0);
849 
850 	fl.l_sysid = 1002;
851 	res = fcntl(fd, F_SETLK_REMOTE, &fl);
852 	FAIL(res != 0);
853 
854 	fl.l_type = F_UNLCKSYS;
855 	fl.l_sysid = 1001;
856 	res = fcntl(fd, F_SETLK_REMOTE, &fl);
857 	FAIL(res != 0);
858 
859 	fl.l_type = F_WRLCK;
860 	res = fcntl(fd, F_GETLK, &fl);
861 	FAIL(res != 0);
862 	FAIL(fl.l_pid != 1234);
863 	FAIL(fl.l_sysid != 1002);
864 
865 	fl.l_type = F_UNLCKSYS;
866 	fl.l_sysid = 1002;
867 	res = fcntl(fd, F_SETLK_REMOTE, &fl);
868 	FAIL(res != 0);
869 
870 	SUCCEED;
871 #else
872 	return 0;
873 #endif
874 }
875 
876 /*
877  * Test 12 - F_SETLKW on locked region which is then unlocked
878  *
879  * If a shared or exclusive lock is blocked by other locks, the
880  * process waits until the request can be satisfied.
881  */
882 static int
883 test12(int fd)
884 {
885 	/*
886 	 * We create a child process to hold the lock which we will
887 	 * test. We use a pipe to communicate with the child.
888 	 */
889 	int pid;
890 	int pfd[2];
891 	struct flock fl;
892 	char ch;
893 	int res;
894 
895 	if (pipe(pfd) < 0)
896 		err(1, "pipe");
897 
898 	fl.l_start = 0;
899 	fl.l_len = 0;
900 	fl.l_type = F_WRLCK;
901 	fl.l_whence = SEEK_SET;
902 
903 	pid = fork();
904 	if (pid < 0)
905 		err(1, "fork");
906 
907 	if (pid == 0) {
908 		/*
909 		 * We are the child. We set a write lock and then
910 		 * write one byte back to the parent to tell it. The
911 		 * parent will kill us when its done.
912 		 */
913 		if (fcntl(fd, F_SETLK, &fl) < 0)
914 			err(1, "F_SETLK (child)");
915 		if (write(pfd[1], "a", 1) < 0)
916 			err(1, "writing to pipe (child)");
917 
918 		sleep(1);
919 		exit(0);
920 	}
921 
922 	/*
923 	 * Wait until the child has set its lock and then perform the
924 	 * test.
925 	 */
926 	if (read(pfd[0], &ch, 1) != 1)
927 		err(1, "reading from pipe (child)");
928 
929 	/*
930 	 * fcntl should wait until the alarm and then return -1 with
931 	 * errno set to EINTR.
932 	 */
933 	if (verbose) printf("12 - F_SETLKW on locked region which is then unlocked: ");
934 
935 	//alarm(1);
936 
937 	res = fcntl(fd, F_SETLKW, &fl);
938 	safe_kill(pid, SIGTERM);
939 	safe_waitpid(pid);
940 	close(pfd[0]);
941 	close(pfd[1]);
942 	FAIL(res != 0);
943 
944 	fl.l_start = 0;
945 	fl.l_len = 0;
946 	fl.l_type = F_UNLCK;
947 	if (fcntl(fd, F_SETLK, &fl) < 0)
948 		err(1, "F_UNLCK");
949 
950 	SUCCEED;
951 }
952 
953 /*
954  * Test 13 - F_SETLKW on locked region, race with owner
955  *
956  * If a shared or exclusive lock is blocked by other locks, the
957  * process waits until the request can be satisfied.
958  */
959 static int
960 test13(int fd)
961 {
962 	/*
963 	 * We create a child process to hold the lock which we will
964 	 * test. We use a pipe to communicate with the child.
965 	 */
966 	int i;
967 	int pid;
968 	int pfd[2];
969 	struct flock fl;
970 	char ch;
971 	int res;
972 	struct itimerval itv;
973 
974 	if (verbose) printf("13 - F_SETLKW on locked region, race with owner: ");
975 	fflush(stdout);
976 
977 	for (i = 0; i < 100; i++) {
978 		if (pipe(pfd) < 0)
979 			err(1, "pipe");
980 
981 		fl.l_start = 0;
982 		fl.l_len = 0;
983 		fl.l_type = F_WRLCK;
984 		fl.l_whence = SEEK_SET;
985 
986 		pid = fork();
987 		if (pid < 0)
988 			err(1, "fork");
989 
990 		if (pid == 0) {
991 			/*
992 			 * We are the child. We set a write lock and then
993 			 * write one byte back to the parent to tell it. The
994 			 * parent will kill us when its done.
995 			 */
996 			if (fcntl(fd, F_SETLK, &fl) < 0)
997 				err(1, "F_SETLK (child)");
998 			if (write(pfd[1], "a", 1) < 0)
999 				err(1, "writing to pipe (child)");
1000 
1001 			sleep(1);
1002 			exit(0);
1003 		}
1004 
1005 		/*
1006 		 * Wait until the child has set its lock and then perform the
1007 		 * test.
1008 		 */
1009 		while (read(pfd[0], &ch, 1) != 1) {
1010 			if (errno == EINTR)
1011 				continue;
1012 			err(1, "reading from pipe (child)");
1013 		}
1014 
1015 		/*
1016 		 * fcntl should wait until the alarm and then return -1 with
1017 		 * errno set to EINTR.
1018 		 */
1019 		itv.it_interval.tv_sec = 0;
1020 		itv.it_interval.tv_usec = 0;
1021 		itv.it_value.tv_sec = 0;
1022 		itv.it_value.tv_usec = 2;
1023 		setitimer(ITIMER_REAL, &itv, NULL);
1024 
1025 		res = fcntl(fd, F_SETLKW, &fl);
1026 		safe_kill(pid, SIGTERM);
1027 		safe_waitpid(pid);
1028 		close(pfd[0]);
1029 		close(pfd[1]);
1030 		FAIL(!(res == 0 || (res == -1 && errno == EINTR)));
1031 
1032 		fl.l_start = 0;
1033 		fl.l_len = 0;
1034 		fl.l_type = F_UNLCK;
1035 		if (fcntl(fd, F_SETLK, &fl) < 0)
1036 			err(1, "F_UNLCK");
1037 	}
1038 	SUCCEED;
1039 }
1040 
1041 /*
1042  * Test 14 - soak test
1043  */
1044 static int
1045 test14(int fd)
1046 {
1047 #define CHILD_COUNT 20
1048 	/*
1049 	 * We create a set of child processes and let each one run
1050 	 * through a random sequence of locks and unlocks.
1051 	 */
1052 	int i, j, id;
1053 	int pids[CHILD_COUNT], pid;
1054 	char buf[128];
1055 	char tbuf[128];
1056 	int map[128];
1057 	char outbuf[512];
1058 	struct flock fl;
1059 	struct itimerval itv;
1060 	int status;
1061 	int id_base = 0;
1062 
1063 	if (verbose) printf("14 - soak test: ");
1064 	fflush(stdout);
1065 
1066 	for (i = 0; i < 128; i++)
1067 		map[i] = F_UNLCK;
1068 
1069 	for (i = 0; i < CHILD_COUNT; i++) {
1070 
1071 		pid = fork();
1072 		if (pid < 0)
1073 			err(1, "fork");
1074 		if (pid) {
1075 			/*
1076 			 * Parent - record the pid and continue.
1077 			 */
1078 			pids[i] = pid;
1079 			continue;
1080 		}
1081 
1082 		/*
1083 		 * Child - do some work and exit.
1084 		 */
1085 		id = id_base + i;
1086 		for (j = 0; j < 50; j++) {
1087 			int start, end, len;
1088 			int set, wrlock;
1089 
1090 			do {
1091 				start = arc4random_uniform(128);
1092 				end = arc4random_uniform(128);
1093 			} while (end <= start);
1094 
1095 			set = arc4random_uniform(2);
1096 			wrlock = arc4random_uniform(2);
1097 
1098 			len = end - start;
1099 			fl.l_start = start;
1100 			fl.l_len = len;
1101 			fl.l_whence = SEEK_SET;
1102 			if (set)
1103 				fl.l_type = wrlock ? F_WRLCK : F_RDLCK;
1104 			else
1105 				fl.l_type = F_UNLCK;
1106 
1107 			itv.it_interval.tv_sec = 0;
1108 			itv.it_interval.tv_usec = 0;
1109 			itv.it_value.tv_sec = 0;
1110 			itv.it_value.tv_usec = 3000;
1111 			setitimer(ITIMER_REAL, &itv, NULL);
1112 
1113 			if (fcntl(fd, F_SETLKW, &fl) < 0) {
1114 				if (errno == EDEADLK || errno == EINTR) {
1115 					if (verbose) {
1116 						snprintf(outbuf, sizeof(outbuf),
1117 						    "%d[%d]: %s [%d .. %d] %s\n",
1118 						    id, j,
1119 						    set ? (wrlock ? "write lock"
1120 							: "read lock")
1121 						    : "unlock", start, end,
1122 						    errno == EDEADLK
1123 						    ? "deadlock"
1124 						    : "interrupted");
1125 						write(1, outbuf,
1126 						    strlen(outbuf));
1127 					}
1128 					continue;
1129 				} else {
1130 					perror("fcntl");
1131 				}
1132 			}
1133 
1134 			itv.it_interval.tv_sec = 0;
1135 			itv.it_interval.tv_usec = 0;
1136 			itv.it_value.tv_sec = 0;
1137 			itv.it_value.tv_usec = 0;
1138 			setitimer(ITIMER_REAL, &itv, NULL);
1139 
1140 			if (verbose) {
1141 				snprintf(outbuf, sizeof(outbuf),
1142 				    "%d[%d]: %s [%d .. %d] succeeded\n",
1143 				    id, j,
1144 				    set ? (wrlock ? "write lock" : "read lock")
1145 				    : "unlock", start, end);
1146 				write(1, outbuf, strlen(outbuf));
1147 			}
1148 
1149 			if (set) {
1150 				if (wrlock) {
1151 					/*
1152 					 * We got a write lock - write
1153 					 * our ID to each byte that we
1154 					 * managed to claim.
1155 					 */
1156 					for (i = start; i < end; i++)
1157 						map[i] = F_WRLCK;
1158 					memset(&buf[start], id, len);
1159 					if (pwrite(fd, &buf[start], len,
1160 						start) != len) {
1161 						printf("%d: short write\n", id);
1162 						exit(1);
1163 					}
1164 				} else {
1165 					/*
1166 					 * We got a read lock - read
1167 					 * the bytes which we claimed
1168 					 * so that we can check that
1169 					 * they don't change
1170 					 * unexpectedly.
1171 					 */
1172 					for (i = start; i < end; i++)
1173 						map[i] = F_RDLCK;
1174 					if (pread(fd, &buf[start], len,
1175 						start) != len) {
1176 						printf("%d: short read\n", id);
1177 						exit(1);
1178 					}
1179 				}
1180 			} else {
1181 				for (i = start; i < end; i++)
1182 					map[i] = F_UNLCK;
1183 			}
1184 
1185 			usleep(1000);
1186 
1187 			/*
1188 			 * Read back the whole region so that we can
1189 			 * check that all the bytes we have some kind
1190 			 * of claim to have the correct value.
1191 			 */
1192 			if (pread(fd, tbuf, sizeof(tbuf), 0) != sizeof(tbuf)) {
1193 				printf("%d: short read\n", id);
1194 				exit(1);
1195 			}
1196 
1197 			for (i = 0; i < 128; i++) {
1198 				if (map[i] != F_UNLCK && buf[i] != tbuf[i]) {
1199 					snprintf(outbuf, sizeof(outbuf),
1200 					    "%d: byte %d expected %d, "
1201 					    "got %d\n", id, i, buf[i], tbuf[i]);
1202 					write(1, outbuf, strlen(outbuf));
1203 					exit(1);
1204 				}
1205 			}
1206 		}
1207 		if (verbose)
1208 			printf("%d[%d]: done\n", id, j);
1209 
1210 		exit(0);
1211 	}
1212 
1213 	status = 0;
1214 	for (i = 0; i < CHILD_COUNT; i++) {
1215 		status += safe_waitpid(pids[i]);
1216 	}
1217 	if (status)
1218 		FAIL(status != 0);
1219 
1220 	SUCCEED;
1221 }
1222 
1223 /*
1224  * Test 15 - flock(2) semantcs
1225  *
1226  * When a lock holder has a shared lock and attempts to upgrade that
1227  * shared lock to exclusive, it must drop the shared lock before
1228  * blocking on the exclusive lock.
1229  *
1230  * To test this, we first arrange for two shared locks on the file,
1231  * and then attempt to upgrade one of them to exclusive. This should
1232  * drop one of the shared locks and block. We interrupt the blocking
1233  * lock request and examine the lock state of the file after dropping
1234  * the other shared lock - there should be no active locks at this
1235  * point.
1236  */
1237 static int
1238 test15(int fd)
1239 {
1240 #ifdef LOCK_EX
1241 	/*
1242 	 * We create a child process to hold the lock which we will
1243 	 * test. We use a pipe to communicate with the child.
1244 	 *
1245 	 * Since we only have one file descriptors and lock ownership
1246 	 * for flock(2) goes with the file descriptor, we use fcntl to
1247 	 * set the child's shared lock.
1248 	 */
1249 	int pid;
1250 	int pfd[2];
1251 	int fd2;
1252 	struct flock fl;
1253 	char ch;
1254 	int res;
1255 
1256 	if (pipe(pfd) < 0)
1257 		err(1, "pipe");
1258 
1259 	pid = fork();
1260 	if (pid < 0)
1261 		err(1, "fork");
1262 
1263 	if (pid == 0) {
1264 		/*
1265 		 * We are the child. We set a shared lock and then
1266 		 * write one byte back to the parent to tell it. The
1267 		 * parent will kill us when its done.
1268 		 */
1269 		fl.l_start = 0;
1270 		fl.l_len = 0;
1271 		fl.l_type = F_RDLCK;
1272 		fl.l_whence = SEEK_SET;
1273 		if (fcntl(fd, F_SETLK, &fl) < 0)
1274 			err(1, "fcntl(F_SETLK) (child)");
1275 		if (write(pfd[1], "a", 1) < 0)
1276 			err(1, "writing to pipe (child)");
1277 		pause();
1278 		exit(0);
1279 	}
1280 
1281 	/*
1282 	 * Wait until the child has set its lock and then perform the
1283 	 * test.
1284 	 */
1285 	if (read(pfd[0], &ch, 1) != 1)
1286 		err(1, "reading from pipe (child)");
1287 
1288 	fd2 = dup(fd);
1289 	if (flock(fd, LOCK_SH) < 0)
1290 		err(1, "flock shared");
1291 
1292 	/*
1293 	 * flock should wait until the alarm and then return -1 with
1294 	 * errno set to EINTR.
1295 	 */
1296 	if (verbose) printf("15 - flock(2) semantics: ");
1297 
1298 	alarm(1);
1299 	flock(fd, LOCK_EX);
1300 
1301 	/*
1302 	 * Kill the child to force it to drop its locks.
1303 	 */
1304 	safe_kill(pid, SIGTERM);
1305 	safe_waitpid(pid);
1306 
1307 	fl.l_start = 0;
1308 	fl.l_len = 0;
1309 	fl.l_type = F_WRLCK;
1310 	fl.l_whence = SEEK_SET;
1311 	res = fcntl(fd, F_GETLK, &fl);
1312 
1313 	close(pfd[0]);
1314 	close(pfd[1]);
1315 	FAIL(res != 0);
1316 	FAIL(fl.l_type != F_UNLCK);
1317 
1318 	SUCCEED;
1319 #else
1320 	return 0;
1321 #endif
1322 }
1323 
1324 /*
1325  * Test 16 - double free regression
1326  *
1327  * Not applicable anymore due to stricter bounds validation.
1328  */
1329 static int
1330 test16(int fd)
1331 {
1332 #if 0
1333 	struct flock fl;
1334 	int res;
1335 
1336 	fl.l_pid = 0;
1337 	fl.l_type = 1;
1338 	fl.l_whence = 0;
1339 
1340 	fl.l_start = 0;
1341 	fl.l_len = 0x8000000000000000;
1342 	res = fcntl(fd, F_SETLK, &fl);
1343 	FAIL(res != 0);
1344 
1345 	fl.l_start = 0x10000;
1346 	fl.l_len = 0;
1347 	res = fcntl(fd, F_SETLK, &fl);
1348 	FAIL(res != 0);
1349 
1350 	fl.l_start = 0;
1351 	fl.l_len = 0x8000000000000000;
1352 	res = fcntl(fd, F_SETLK, &fl);
1353 	FAIL(res != 0);
1354 
1355 	fl.l_start = 0x10000;
1356 	fl.l_len = 0;
1357 	res = fcntl(fd, F_SETLK, &fl);
1358 	FAIL(res != 0);
1359 #endif
1360 
1361 	SUCCEED;
1362 }
1363 
1364 /*
1365  * Test 17 - lf_findoverlap() case 0
1366  *
1367  * No overlap.
1368  */
1369 static int
1370 test17(int fd)
1371 {
1372 	struct flock fl;
1373 	int nfd, res;
1374 
1375 	/* First lock. */
1376 	{
1377 		nfd = dup(fd);
1378 		FAIL(nfd == -1);
1379 
1380 		fl.l_start = 0;
1381 		fl.l_len = 100;
1382 		fl.l_pid = 0;
1383 		fl.l_type = F_RDLCK;
1384 		fl.l_whence = 0;
1385 		res = fcntl(fd, F_SETLK, &fl);
1386 		FAIL(res != 0);
1387 
1388 		close(nfd);
1389 	}
1390 
1391 	/* Insert at end. */
1392 	{
1393 		nfd = dup(fd);
1394 		FAIL(nfd == -1);
1395 
1396 		fl.l_start = 100;
1397 		fl.l_len = 100;
1398 		fl.l_pid = 0;
1399 		fl.l_type = F_RDLCK;
1400 		fl.l_whence = 0;
1401 		res = fcntl(fd, F_SETLK, &fl);
1402 		FAIL(res != 0);
1403 
1404 		fl.l_start = 200;
1405 		fl.l_len = 100;
1406 		fl.l_pid = 0;
1407 		fl.l_type = F_RDLCK;
1408 		fl.l_whence = 0;
1409 		res = fcntl(fd, F_SETLK, &fl);
1410 		FAIL(res != 0);
1411 
1412 		close(nfd);
1413 	}
1414 
1415 	/* Insert before overlap. */
1416 	{
1417 		nfd = dup(fd);
1418 		FAIL(nfd == -1);
1419 
1420 		fl.l_start = 300;
1421 		fl.l_len = 100;
1422 		fl.l_pid = 0;
1423 		fl.l_type = F_RDLCK;
1424 		fl.l_whence = 0;
1425 		res = fcntl(fd, F_SETLK, &fl);
1426 		FAIL(res != 0);
1427 
1428 		fl.l_start = 500;
1429 		fl.l_len = 100;
1430 		fl.l_pid = 0;
1431 		fl.l_type = F_RDLCK;
1432 		fl.l_whence = 0;
1433 		res = fcntl(fd, F_SETLK, &fl);
1434 		FAIL(res != 0);
1435 
1436 		fl.l_start = 400;
1437 		fl.l_len = 100;
1438 		fl.l_pid = 0;
1439 		fl.l_type = F_RDLCK;
1440 		fl.l_whence = 0;
1441 		res = fcntl(fd, F_SETLK, &fl);
1442 		FAIL(res != 0);
1443 
1444 		close(nfd);
1445 	}
1446 
1447 	SUCCEED;
1448 }
1449 
1450 /*
1451  * Test 18 - lf_findoverlap() case 1
1452  *
1453  * Overlap and lock are equal.
1454  */
1455 static int
1456 test18(int fd)
1457 {
1458 	struct flock fl;
1459 	int res;
1460 
1461 	fl.l_start = 0;
1462 	fl.l_len = 100;
1463 	fl.l_pid = 0;
1464 	fl.l_type = F_RDLCK;
1465 	fl.l_whence = 0;
1466 	res = fcntl(fd, F_SETLK, &fl);
1467 	FAIL(res != 0);
1468 	res = fcntl(fd, F_SETLK, &fl);
1469 	FAIL(res != 0);
1470 
1471 	SUCCEED;
1472 }
1473 
1474 /*
1475  * Test 19 - lf_findoverlap() case 2
1476  *
1477  * Overlap contains lock.
1478  */
1479 static int
1480 test19(int fd)
1481 {
1482 	struct flock fl;
1483 	int nfd, res;
1484 
1485 	/* Same type. */
1486 	{
1487 		nfd = dup(fd);
1488 		FAIL(nfd == -1);
1489 
1490 		fl.l_start = 0;
1491 		fl.l_len = 100;
1492 		fl.l_pid = 0;
1493 		fl.l_type = F_RDLCK;
1494 		fl.l_whence = 0;
1495 		res = fcntl(fd, F_SETLK, &fl);
1496 		FAIL(res != 0);
1497 
1498 		fl.l_start = 0;
1499 		fl.l_len = 50;
1500 		fl.l_pid = 0;
1501 		fl.l_type = F_RDLCK;
1502 		fl.l_whence = 0;
1503 		res = fcntl(fd, F_SETLK, &fl);
1504 		FAIL(res != 0);
1505 
1506 		close(nfd);
1507 	}
1508 
1509 	/* Different type, same start offset. */
1510 	{
1511 		nfd = dup(fd);
1512 		FAIL(nfd == -1);
1513 
1514 		fl.l_start = 100;
1515 		fl.l_len = 100;
1516 		fl.l_pid = 0;
1517 		fl.l_type = F_RDLCK;
1518 		fl.l_whence = 0;
1519 		res = fcntl(fd, F_SETLK, &fl);
1520 		FAIL(res != 0);
1521 
1522 		fl.l_start = 100;
1523 		fl.l_len = 50;
1524 		fl.l_pid = 0;
1525 		fl.l_type = F_WRLCK;
1526 		fl.l_whence = 0;
1527 		res = fcntl(fd, F_SETLK, &fl);
1528 		FAIL(res != 0);
1529 
1530 		close(nfd);
1531 	}
1532 
1533 	/* Split fallback. */
1534 	{
1535 		nfd = dup(fd);
1536 		FAIL(nfd == -1);
1537 
1538 		fl.l_start = 100;
1539 		fl.l_len = 100;
1540 		fl.l_pid = 0;
1541 		fl.l_type = F_RDLCK;
1542 		fl.l_whence = 0;
1543 		res = fcntl(fd, F_SETLK, &fl);
1544 		FAIL(res != 0);
1545 
1546 		fl.l_start = 110;
1547 		fl.l_len = 50;
1548 		fl.l_pid = 0;
1549 		fl.l_type = F_WRLCK;
1550 		fl.l_whence = 0;
1551 		res = fcntl(fd, F_SETLK, &fl);
1552 		FAIL(res != 0);
1553 
1554 		close(nfd);
1555 	}
1556 
1557 	SUCCEED;
1558 }
1559 
1560 /*
1561  * Test 20 - lf_findoverlap() case 3
1562  *
1563  * Lock contains overlap.
1564  */
1565 static int
1566 test20(int fd)
1567 {
1568 	struct flock fl;
1569 	int res;
1570 
1571 	fl.l_start = 0;
1572 	fl.l_len = 100;
1573 	fl.l_pid = 0;
1574 	fl.l_type = F_WRLCK;
1575 	fl.l_whence = 0;
1576 	res = fcntl(fd, F_SETLK, &fl);
1577 	FAIL(res != 0);
1578 
1579 	fl.l_start = 0;
1580 	fl.l_len = 200;
1581 	fl.l_pid = 0;
1582 	fl.l_type = F_WRLCK;
1583 	fl.l_whence = 0;
1584 	res = fcntl(fd, F_SETLK, &fl);
1585 	FAIL(res != 0);
1586 
1587 	SUCCEED;
1588 }
1589 
1590 /*
1591  * Test 21 - lf_findoverlap() case 4
1592  *
1593  * Overlap starts before lock.
1594  */
1595 static int
1596 test21(int fd)
1597 {
1598 	struct flock fl;
1599 	int res;
1600 
1601 	fl.l_start = 0;
1602 	fl.l_len = 100;
1603 	fl.l_pid = 0;
1604 	fl.l_type = F_WRLCK;
1605 	fl.l_whence = 0;
1606 	res = fcntl(fd, F_SETLK, &fl);
1607 	FAIL(res != 0);
1608 
1609 	fl.l_start = 50;
1610 	fl.l_len = 100;
1611 	fl.l_pid = 0;
1612 	fl.l_type = F_WRLCK;
1613 	fl.l_whence = 0;
1614 	res = fcntl(fd, F_SETLK, &fl);
1615 	FAIL(res != 0);
1616 
1617 	SUCCEED;
1618 }
1619 
1620 /*
1621  * Test 22 - lf_findoverlap() case 5
1622  *
1623  * Overlap ends after lock.
1624  */
1625 static int
1626 test22(int fd)
1627 {
1628 	struct flock fl;
1629 	int res;
1630 
1631 	fl.l_start = 10;
1632 	fl.l_len = 100;
1633 	fl.l_pid = 0;
1634 	fl.l_type = F_WRLCK;
1635 	fl.l_whence = 0;
1636 	res = fcntl(fd, F_SETLK, &fl);
1637 	FAIL(res != 0);
1638 
1639 	fl.l_start = 0;
1640 	fl.l_len = 50;
1641 	fl.l_pid = 0;
1642 	fl.l_type = F_WRLCK;
1643 	fl.l_whence = 0;
1644 	res = fcntl(fd, F_SETLK, &fl);
1645 	FAIL(res != 0);
1646 
1647 	SUCCEED;
1648 }
1649 
1650 /*
1651  * Test 23 - positive length overflow
1652  */
1653 static int
1654 test23(int fd)
1655 {
1656 	struct flock fl;
1657 	int res;
1658 
1659 	fl.l_pid = 0;
1660 	fl.l_type = F_WRLCK;
1661 	fl.l_whence = SEEK_SET;
1662 	fl.l_start = 2;
1663 	fl.l_len = LLONG_MAX;
1664 	res = fcntl(fd, F_SETLK, &fl);
1665 	FAIL(res != -1);
1666 	FAIL(errno != EOVERFLOW);
1667 
1668 	SUCCEED;
1669 }
1670 
1671 /*
1672  * Test 24 - negative length
1673  */
1674 static int
1675 test24(int fd)
1676 {
1677 	struct flock fl;
1678 	pid_t pid;
1679 	int res, status;
1680 
1681 	fl.l_pid = 0;
1682 	fl.l_type = F_WRLCK;
1683 	fl.l_whence = SEEK_SET;
1684 
1685 	/* Start offset plus length must be positive. */
1686 	fl.l_start = 0;
1687 	fl.l_len = LLONG_MIN;
1688 	res = fcntl(fd, F_SETLK, &fl);
1689 	FAIL(res != -1);
1690 	FAIL(errno != EINVAL);
1691 
1692 	/* Set exclusive lock on range [2,3] */
1693 	fl.l_start = 4;
1694 	fl.l_len = -2;
1695 	res = fcntl(fd, F_SETLK, &fl);
1696 	FAIL(res != 0);
1697 
1698 	/* Another process must not be able to lock the same range. */
1699 	pid = fork();
1700 	if (pid == -1)
1701 		err(1, "fork");
1702 	if (pid == 0) {
1703 		fl.l_start = 2;
1704 		fl.l_len = 2;
1705 		res = fcntl(fd, F_GETLK, &fl);
1706 		FAIL(res != 0);
1707 		FAIL(fl.l_type == F_UNLCK);
1708 		_exit(0);
1709 	}
1710 	status = safe_waitpid(pid);
1711 	FAIL(status != 0);
1712 
1713 	SUCCEED;
1714 }
1715 
1716 static struct test tests[] = {
1717 	{	test1,		0	},
1718 	{	test2,		0	},
1719 	{	test3,		1	},
1720 	{	test4,		0	},
1721 	{	test5,		1	},
1722 	{	test6,		1	},
1723 	{	test7,		0	},
1724 	{	test8,		0	},
1725 	{	test9,		0	},
1726 	{	test10,		0	},
1727 	{	test11,		1	},
1728 	{	test12,		0	},
1729 	{	test13,		1	},
1730 	{	test14,		0	},
1731 	{	test15,		1	},
1732 	{	test16,		0	},
1733 	{	test17,		0	},
1734 	{	test18,		0	},
1735 	{	test19,		0	},
1736 	{	test20,		0	},
1737 	{	test21,		0	},
1738 	{	test22,		0	},
1739 	{	test23,		0	},
1740 	{	test24,		0	},
1741 };
1742 
1743 static int test_count = sizeof(tests) / sizeof(tests[0]);
1744 
1745 int
1746 main(int argc, char *argv[])
1747 {
1748 	struct sigaction sa;
1749 	const char *errstr;
1750 	int c, fd, i;
1751 	int error = 0;
1752 	int testnum = 0;
1753 
1754 	while ((c = getopt(argc, argv, "v")) != -1)
1755 		switch (c) {
1756 		case 'v':
1757 			verbose = 1;
1758 			break;
1759 		default:
1760 			usage();
1761 		}
1762 	argc -= optind;
1763 	argv += optind;
1764 	if (argc > 1)
1765 		usage();
1766 	if (argc == 1) {
1767 		testnum = strtonum(argv[0], 1, test_count, &errstr);
1768 		if (testnum == 0)
1769 			errx(1, "test number %s", errstr);
1770 	}
1771 
1772 	fd = make_file(1024);
1773 
1774 	sa.sa_handler = ignore_alarm;
1775 	sigemptyset(&sa.sa_mask);
1776 	sa.sa_flags = 0;
1777 	sigaction(SIGALRM, &sa, 0);
1778 
1779 	for (i = 0; i < test_count; i++) {
1780 		if (testnum == 0 || testnum == i + 1)
1781 			error |= tests[i].testfn(fd);
1782 	}
1783 
1784 	return (error ? 1 : 0);
1785 }
1786