1 /* 2 * Copyright 2005, Axel Dörfler, axeld@pinc-software.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include <OS.h> 8 9 #include <fcntl.h> 10 #include <unistd.h> 11 #include <stdint.h> 12 #include <stdio.h> 13 #include <string.h> 14 #include <errno.h> 15 16 17 bool gDone = false; 18 19 20 static int32 21 try_to_lock(void *_fd) 22 { 23 intptr_t fd = (intptr_t)_fd; 24 25 struct flock flock = { 26 F_RDLCK, // shared lock 27 SEEK_SET, 28 200, 29 0, // until the end of the file 30 0 31 }; 32 33 if (fcntl(fd, F_SETLK, &flock) == 0) { 34 fprintf(stderr, "a. Could lock file!\n"); 35 return -1; 36 } else 37 puts("test a passed."); 38 39 gDone = true; 40 41 // wait for lock to become free 42 43 if (fcntl(fd, F_SETLKW, &flock) == -1) { 44 fprintf(stderr, "b. Could not lock file: %s\n", strerror(errno)); 45 return -1; 46 } else 47 puts("test b passed."); 48 49 flock.l_type = F_UNLCK; 50 51 if (fcntl(fd, F_SETLK, &flock) == -1) { 52 fprintf(stderr, "c. Could not unlock file: %s\n", strerror(errno)); 53 return -1; 54 } else 55 puts("test c passed."); 56 57 return 0; 58 } 59 60 61 int 62 main(int argc, char **argv) 63 { 64 intptr_t fd = open("/etc/passwd", O_RDONLY); 65 if (fd < 0) { 66 fprintf(stderr, "could not open file: %s\n", strerror(errno)); 67 return -1; 68 } 69 70 struct flock flock = { 71 F_WRLCK, // exclusive lock 72 SEEK_SET, // lock whole file 73 0, 74 0, 75 0 76 }; 77 78 if (fcntl(fd, F_SETLK, &flock) == 0) { 79 fprintf(stderr, "0. Could lock file exclusively without write access!\n"); 80 return -1; 81 } else 82 puts("test 0 passed."); 83 84 flock.l_type = F_RDLCK; 85 // shared locks should be allowed 86 87 if (fcntl(fd, F_SETLK, &flock) == -1) { 88 fprintf(stderr, "1. Could not lock file: %s\n", strerror(errno)); 89 return -1; 90 } else 91 puts("test 1 passed."); 92 93 close(fd); 94 95 fd = open("/etc/passwd", O_RDWR); 96 if (fd < 0) { 97 fprintf(stderr, "could not open file: %s\n", strerror(errno)); 98 return -1; 99 } 100 101 flock.l_type = F_WRLCK; 102 flock.l_start = 100; 103 flock.l_len = 42; 104 105 if (fcntl(fd, F_SETLK, &flock) == -1) { 106 fprintf(stderr, "2. Could not lock file: %s\n", strerror(errno)); 107 return -1; 108 } else 109 puts("test 2 passed."); 110 111 flock.l_start = 200; 112 113 if (fcntl(fd, F_SETLK, &flock) == -1) { 114 fprintf(stderr, "3. Could not lock file: %s\n", strerror(errno)); 115 return -1; 116 } else 117 puts("test 3 passed."); 118 119 flock.l_start = 80; 120 121 if (fcntl(fd, F_SETLK, &flock) == 0) { 122 fprintf(stderr, "4. Could lock file exclusively on locked region!\n"); 123 return -1; 124 } else 125 puts("test 4 passed."); 126 127 flock.l_type = F_UNLCK; 128 flock.l_start = 100; 129 130 if (fcntl(fd, F_SETLK, &flock) == -1) { 131 fprintf(stderr, "5. Could not unlock file: %s\n", strerror(errno)); 132 return -1; 133 } else 134 puts("test 5 passed."); 135 136 flock.l_type = F_WRLCK; 137 flock.l_start = 80; 138 139 if (fcntl(fd, F_SETLK, &flock) == -1) { 140 fprintf(stderr, "6. Could not lock file: %s\n", strerror(errno)); 141 return -1; 142 } else 143 puts("test 6 passed."); 144 145 thread_id thread = spawn_thread(try_to_lock, "try", B_NORMAL_PRIORITY, (void *)fd); 146 if (thread < B_OK) { 147 fprintf(stderr, "Could not spawn thread: %s\n", strerror(thread)); 148 return -1; 149 } 150 resume_thread(thread); 151 152 while (!gDone) { 153 snooze(100000); // 0.1s 154 } 155 156 flock.l_type = F_UNLCK; 157 flock.l_start = 200; 158 159 if (fcntl(fd, F_SETLK, &flock) == -1) { 160 fprintf(stderr, "7. Could not unlock file: %s\n", strerror(errno)); 161 return -1; 162 } else 163 puts("test 7 passed."); 164 165 status_t returnCode; 166 wait_for_thread(thread, &returnCode); 167 168 close(fd); 169 return 0; 170 } 171