xref: /haiku/src/tests/system/kernel/advisory_locking_test.cpp (revision 7749d0bb0c358a3279b1b9cc76d8376e900130a5)
1 /*
2  * Copyright 2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 
7 #include <fcntl.h>
8 #include <errno.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <unistd.h>
13 
14 
15 extern const char *__progname;
16 
17 const char* kTemporaryFile = "/tmp/axels-lock-test";
18 
19 
20 const char*
21 type_name(int type)
22 {
23 	return type == F_RDLCK ? "shared" : type == F_WRLCK
24 		? "exclusive" : "remove";
25 }
26 
27 
28 int
29 do_lock(int fd, int type, off_t start, off_t length)
30 {
31 	printf("%s lock %Ld:%Ld\n", type_name(type), start, length);
32 
33 	struct flock flock;
34 	flock.l_type = type;
35 	flock.l_whence = SEEK_SET;
36 	flock.l_start = start;
37 	flock.l_len = length;
38 	if (fcntl(fd, F_SETLK, &flock) != 0) {
39 		fprintf(stderr, "ERROR: %s lock %Ld:%Ld failed: %s\n", type_name(type),
40 			start, length, strerror(errno));
41 		return -1;
42 	}
43 
44 	return 0;
45 }
46 
47 
48 int
49 shared_lock(int fd, off_t start, off_t length)
50 {
51 	return do_lock(fd, F_RDLCK, start, length);
52 }
53 
54 
55 int
56 exclusive_lock(int fd, off_t start, off_t length)
57 {
58 	return do_lock(fd, F_WRLCK, start, length);
59 }
60 
61 
62 int
63 remove_lock(int fd, off_t start, off_t length)
64 {
65 	return do_lock(fd, F_UNLCK, start, length);
66 }
67 
68 
69 void
70 wait_for_enter()
71 {
72 	puts("wait for <enter>...");
73 	char buffer[64];
74 	fgets(buffer, sizeof(buffer), stdin);
75 }
76 
77 
78 void
79 usage()
80 {
81 	fprintf(stderr, "usage: %s [shared|exclusive|unlock <start> <length>] "
82 		"[wait] [...]\n", __progname);
83 	exit(1);
84 }
85 
86 
87 bool
88 is_command(const char* op, const char* command1, const char* command2)
89 {
90 	int length = strlen(op);
91 	if (length == 0)
92 		return false;
93 
94 	return command1 != NULL && !strncmp(op, command1, length)
95 		|| command2 != NULL && !strncmp(op, command2, length);
96 }
97 
98 
99 int
100 main(int argc, char** argv)
101 {
102 	int fd = open(kTemporaryFile, O_CREAT | O_RDWR, 0644);
103 	if (fd < 0) {
104 		fprintf(stderr, "Could not create lock file: %s\n", strerror(errno));
105 		return 1;
106 	}
107 
108 	while (argc > 1) {
109 		const char* op = argv[1];
110 		if (is_command(op, "wait", NULL)) {
111 			wait_for_enter();
112 			argv++;
113 			argc--;
114 			continue;
115 		}
116 		if (argc < 3)
117 			usage();
118 
119 		off_t start = strtoll(argv[2], NULL, 0);
120 		off_t length = strtoll(argv[3], NULL, 0);
121 		int type = 0;
122 		if (is_command(op, "read", "shared"))
123 			type = F_RDLCK;
124 		else if (is_command(op, "write", "exclusive"))
125 			type = F_WRLCK;
126 		else if (is_command(op, "unlock", "remove"))
127 			type = F_UNLCK;
128 		else
129 			usage();
130 
131 		do_lock(fd, type, start, length);
132 		argc -= 3;
133 		argv += 3;
134 	}
135 
136 	close(fd);
137 	return 0;
138 }
139 
140