Add a little program that allows one to test posix range locks.
[dragonfly.git] / test / debug / posixlock.c
1 /*
2  * Copyright (c) 2006 The DragonFly Project.  All rights reserved.
3  * 
4  * This code is derived from software contributed to The DragonFly Project
5  * by Matthew Dillon <dillon@backplane.com>
6  * 
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  * 3. Neither the name of The DragonFly Project nor the names of its
18  *    contributors may be used to endorse or promote products derived
19  *    from this software without specific, prior written permission.
20  * 
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
25  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  * 
34  * $DragonFly: src/test/debug/posixlock.c,v 1.1 2006/05/08 00:30:41 dillon Exp $
35  */
36
37 #include <sys/types.h>
38 #include <fcntl.h>
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <unistd.h>
42 #include <string.h>
43 #include <errno.h>
44
45 static void prompt(void);
46
47 int
48 main(int ac, char **av)
49 {
50     struct flock lk;
51     off_t save_start;
52     off_t save_len;
53     char c;
54     int r;
55     int fd;
56     char buf[256];
57
58     if ((fd = open("test", O_CREAT|O_RDWR, 0666)) < 0) {
59         perror("open");
60         exit(1);
61     }
62     prompt();
63     while (fgets(buf, sizeof(buf), stdin) != NULL) {
64         bzero(&lk, sizeof(lk));
65         c = '#';
66         sscanf(buf, "%c %lld %lld", &c, &lk.l_start, &lk.l_len);
67
68         save_start = lk.l_start;
69         save_len = lk.l_len;
70
71         switch(c) {
72         case 'l':
73             lk.l_type = F_WRLCK;
74             while ((r = fcntl(fd, F_GETLK, &lk)) == 0) {
75                 printf("%5d %c %lld %lld\n",
76                         (int)lk.l_pid,
77                         (lk.l_type == F_WRLCK) ? 'x' :
78                         (lk.l_type == F_RDLCK) ? 'r' :
79                         (lk.l_type == F_UNLCK) ? 'u' : '?',
80                         lk.l_start,
81                         lk.l_len
82                 );
83                 if (lk.l_len == 0)
84                         break;
85                 lk.l_start += lk.l_len;
86                 if (save_len)
87                         lk.l_len = save_len - (lk.l_start - save_start);
88                 else
89                         lk.l_len = 0;
90                 lk.l_type = F_WRLCK;
91             }
92             if (r < 0)
93                 printf("%s\n", strerror(errno));
94             break;
95         case 's':
96             lk.l_type = F_RDLCK;
97             if (fcntl(fd, F_SETLKW, &lk) == 0) {
98                 printf("ok\n");
99             } else {
100                 printf("%s\n", strerror(errno));
101             }
102             break;
103         case 'x':
104             lk.l_type = F_WRLCK;
105             if (fcntl(fd, F_SETLKW, &lk) == 0) {
106                 printf("ok\n");
107             } else {
108                 printf("%s\n", strerror(errno));
109             }
110             break;
111         case 'u':
112             lk.l_type = F_UNLCK;
113             if (fcntl(fd, F_SETLKW, &lk) == 0) {
114                 printf("ok\n");
115             } else {
116                 printf("%s\n", strerror(errno));
117             }
118             break;
119         case '?':
120                 printf(
121                         "l start len\tlist locks\n"
122                         "s start len\tobtain a read lock\n"
123                         "x start len\tobtain an exclusive lock\n"
124                         "u start len\tounlock a range\n"
125                 );
126                 break;
127         case '\n':
128         case '\0':
129         case '#':
130                 break;
131         default:
132                 printf("unknown command '%c'\n", c);
133                 break;
134         }
135         prompt();
136     }
137     return(0);
138 }
139
140 static
141 void
142 prompt(void)
143 {
144     printf("locker> ");
145     fflush(stdout);
146 }