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 %lld:%lld\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 %lld:%lld 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