xref: /openbsd/regress/sys/kern/flock/lockf.c (revision 274d7c50)
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
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
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
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