xref: /sqlite-3.40.0/tool/showlocks.c (revision 0f40e8dd)
1 /*
2 ** This file implements a simple command-line utility that shows all of the
3 ** Posix Advisory Locks on a file.
4 **
5 ** Usage:
6 **
7 **     showlocks FILENAME
8 **
9 ** To compile:  gcc -o showlocks showlocks.c
10 */
11 #include <stdio.h>
12 #include <unistd.h>
13 #include <fcntl.h>
14 #include <stdlib.h>
15 #include <string.h>
16 
17 /* This utility only looks for locks in the first 2 billion bytes */
18 #define MX_LCK 2147483647
19 
20 /*
21 ** Print all locks on the inode of "fd" that occur in between
22 ** lwr and upr, inclusive.
23 */
showLocksInRange(int fd,off_t lwr,off_t upr)24 static int showLocksInRange(int fd, off_t lwr, off_t upr){
25   int cnt = 0;
26   struct flock x;
27   struct lockRange {
28     off_t lwr;
29     off_t upr;
30   } *aPending = 0;
31   int nAlloc = 1;
32   int nPending = 0;
33   int nDone = 0;
34 
35   nPending = 1;
36   aPending = malloc( sizeof(aPending[0]) );
37   if( aPending==0 ){
38     fprintf(stderr, "out of memory\n");
39     exit(1);
40   }
41   aPending[0].lwr = lwr;
42   aPending[0].upr = upr;
43 
44   for(nDone=0; nDone<nPending; nDone++){
45     lwr = aPending[nDone].lwr;
46     upr = aPending[nDone].upr;
47     if( lwr>=upr ) continue;
48     x.l_type = F_WRLCK;
49     x.l_whence = SEEK_SET;
50     x.l_start = lwr;
51     x.l_len = upr - lwr;
52     fcntl(fd, F_GETLK, &x);
53     if( x.l_type==F_UNLCK ) continue;
54     printf("start: %-12d len: %-5d pid: %-5d type: %s\n",
55          (int)x.l_start, (int)x.l_len,
56          x.l_pid, x.l_type==F_WRLCK ? "WRLCK" : "RDLCK");
57     cnt++;
58     if( nPending+2 > nAlloc ){
59       nAlloc = nAlloc*2 + 2;
60       aPending = realloc(aPending, sizeof(aPending[0])*nAlloc );
61     }
62     if( aPending==0 ){
63       fprintf(stderr, "unable to realloc for %d bytes\n",
64                       (int)sizeof(aPending[0])*(nPending+2));
65       exit(1);
66     }
67     if( lwr<x.l_start ){
68       aPending[nPending].lwr = lwr;
69       aPending[nPending].upr = x.l_start;
70       nPending++;
71     }
72     if( x.l_start+x.l_len<=upr ){
73       aPending[nPending].lwr = x.l_start + x.l_len;
74       aPending[nPending].upr = upr;
75       nPending++;
76     }
77   }
78   free(aPending);
79   return cnt;
80 }
81 
main(int argc,char ** argv)82 int main(int argc, char **argv){
83   int fd;
84   int cnt;
85 
86   if( argc!=2 ){
87     fprintf(stderr, "Usage: %s FILENAME\n", argv[0]);
88     return 1;
89   }
90   fd = open(argv[1], O_RDWR, 0);
91   if( fd<0 ){
92     fprintf(stderr, "%s: cannot open %s\n", argv[0], argv[1]);
93     return 1;
94   }
95   cnt = showLocksInRange(fd, 0, MX_LCK);
96   if( cnt==0 ) printf("no locks\n");
97   close(fd);
98   return 0;
99 }
100