1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
|
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
int lock_reg(int fd, int cmd, int type, off_t offset, int whence, off_t len)
{
struct flock lock;
lock.l_type = type;
lock.l_start = offset;
lock.l_whence = whence;
lock.l_len = len;
return fcntl(fd, cmd, &lock);
}
pid_t lock_test(int fd, int type, off_t offset, int whence, off_t len)
{
struct flock lock;
int ret;
lock.l_type = type;
lock.l_start = offset;
lock.l_whence = whence;
lock.l_len = len;
ret = fcntl(fd, F_GETLK, &lock);
if (ret<0) {
printf("lock_test: fcntl F_GETLK call returned %d\n", ret);
return ret;
}
if (lock.l_type==F_UNLCK)
return 0;
// Make sure we don't return a confusing PID (in case PID not set
// correctly by system).
return (lock.l_pid==0) ? 1 : lock.l_pid;
}
int main(int argc, char **argv) {
int ret = 0;
int fid;
if (argc<2) {
printf("Usage: checkLock filename\n"
"Checks for ability to get advisory write lock on file filename.\n"
"Returns 0 on success, 1 on failure.\n"
"--checkSetLock option: Print warning if setting lock fails.\n");
return -1;
}
if (0==strcmp("--checkSetLock",argv[1])) {
// Check setting lock
const char filename[] = "/proc/self/exe";
int fid = open(filename, O_RDONLY, 0);
if (fid>=0) {
ret = lock_reg(fid, F_SETLK, F_RDLCK, 0, SEEK_SET, 0);
if (ret<0) {
printf("WARNING: fcntl locks are not working.\nRunning processes are not"
" protected against overwrite from other computers.\n"
"fcntl call returned %d\n", ret);
return 0;
}
lock_reg(fid, F_SETLK, F_UNLCK, 0, SEEK_SET, 0);
close(fid);
}
return 0;
} else {
// Check whether lock is set on specified file
fid = open(argv[1], O_RDONLY, 0);
if (fid>0) {
ret = lock_test(fid, F_WRLCK, 0, SEEK_SET, 0);
if (ret==1) // special return code for unknown PID case
printf("checkLock: File %s is locked.\n", argv[1]);
else if (ret>0)
printf("checkLock: File %s is locked by PID %d\n", argv[1], ret);
close(fid);
} else {
if ( errno != ENOENT ) {
printf("File %s can't be opened: %s\n", argv[1], strerror(errno) );
ret = 1;
}
}
return (ret!=0 ? 1 : 0);
}
}
|