1 /* $OpenBSD: lockf.c,v 1.1 2018/11/06 18:11:11 anton Exp $ */
2
3 /*
4 * Copyright (c) 2018 Anton Lindqvist <anton@openbsd.org>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19 #include <err.h>
20 #include <fcntl.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <unistd.h>
24
25 #include "util.h"
26
27 int verbose = 0;
28
29 /*
30 * Test 1 - F_LOCK positive length
31 */
32 static int
test1(int fd)33 test1(int fd)
34 {
35 struct flock fl;
36 pid_t pid;
37 int res;
38
39 fl.l_start = 0;
40 fl.l_len = 16;
41 fl.l_type = F_WRLCK;
42 fl.l_whence = SEEK_CUR;
43 res = fcntl(fd, F_SETLK, &fl);
44 FAIL(res != 0);
45
46 pid = fork();
47 if (pid == -1)
48 err(1, "fork");
49 if (pid == 0) {
50 res = fcntl(fd, F_SETLK, &fl);
51 FAIL(res != -1);
52 FAIL(fl.l_type != F_WRLCK);
53 _exit(0);
54 }
55 res = safe_waitpid(pid);
56 FAIL(res != 0);
57
58 SUCCEED;
59 }
60
61 /*
62 * Test 2 - F_LOCK negative length
63 */
64 static int
test2(int fd)65 test2(int fd)
66 {
67 struct flock fl;
68 pid_t pid;
69 off_t len = 16;
70 int res;
71
72 if (lseek(fd, len, SEEK_SET) == -1)
73 err(1, "lseek");
74
75 fl.l_start = 0;
76 fl.l_len = -len;
77 fl.l_type = F_WRLCK;
78 fl.l_whence = SEEK_CUR;
79 res = fcntl(fd, F_SETLK, &fl);
80 FAIL(res != 0);
81
82 pid = fork();
83 if (pid == -1)
84 err(1, "fork");
85 if (pid == 0) {
86 if (lseek(fd, 0, SEEK_SET) == -1)
87 err(1, "lseek");
88
89 fl.l_start = 0;
90 fl.l_len = len;
91 fl.l_whence = SEEK_SET;
92 res = fcntl(fd, F_GETLK, &fl);
93 FAIL(res != 0);
94 FAIL(fl.l_type != F_WRLCK);
95 _exit(0);
96 }
97 res = safe_waitpid(pid);
98 FAIL(res != 0);
99
100 SUCCEED;
101 }
102
103 static struct test tests[] = {
104 { test1, 0 },
105 { test2, 0 },
106 };
107
108 static int test_count = sizeof(tests) / sizeof(tests[0]);
109
110 int
main(int argc,char * argv[])111 main(int argc, char *argv[])
112 {
113 const char *errstr;
114 int c, error, fd, i;
115 int testnum = 0;
116
117 while ((c = getopt(argc, argv, "v")) != -1)
118 switch (c) {
119 case 'v':
120 verbose = 1;
121 break;
122 default:
123 usage();
124 }
125 argc -= optind;
126 argv += optind;
127 if (argc > 1)
128 usage();
129 if (argc == 1) {
130 testnum = strtonum(argv[0], 1, test_count, &errstr);
131 if (testnum == 0)
132 errx(1, "test number %s", errstr);
133 }
134
135 fd = make_file(1024);
136
137 error = 0;
138 for (i = 0; i < test_count; i++) {
139 if (testnum == 0 || i + 1 == testnum)
140 error |= tests[i].testfn(fd);
141 }
142
143 return (error ? 1 : 0);
144 }
145