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