1 2 /* Test program to demonstrate valgrind breaking fcntl locks during 3 * mmap. Feed it a r/w file, such as its own source code. */ 4 5 /* See bug 280965. */ 6 7 #include <stdio.h> 8 #include <stdlib.h> 9 #include <unistd.h> 10 #include <fcntl.h> 11 #include <sys/mman.h> 12 #include <sys/types.h> 13 #include <sys/wait.h> 14 #include <err.h> 15 16 int main(int argc, char *argv[]) 17 { 18 struct flock fl; 19 const char *file = /* argv[1]; */ 20 "mmap_fcntl_bug.c"; 21 int fd, status; 22 off_t initial; 23 24 if (!file) 25 errx(1, "Usage: %s <normal-file>", argv[0]); 26 27 fd = open(file, O_RDWR); 28 if (fd < 0) 29 err(1, "Opening %s", file); 30 31 // reproduce bug 297991: mmap interferes with fd position 32 initial = lseek(fd, 123, SEEK_SET); 33 if (123 != initial) 34 err(1, "initial off_t differs from 123 (TEST FAILED)"); 35 if (lseek(fd, 0, SEEK_CUR) != 123) 36 err(1, "zero offset from initial differs from 123 (TEST FAILED)"); 37 38 fl.l_type = F_WRLCK; 39 fl.l_whence = SEEK_SET; 40 fl.l_start = 0; 41 fl.l_len = 1; 42 43 /* I'm assuming no one else tries to lock this! */ 44 if (fcntl(fd, F_SETLK, &fl) != 0) 45 err(1, "Locking %s", file); 46 47 /* If under valgrind, mmap re-opens and closes file, screwing us */ 48 if (mmap(NULL, getpagesize(), PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0) == MAP_FAILED) 49 err(1, "mmap of %s", file); 50 if (lseek(fd, 0, SEEK_CUR) != 123) 51 errx(1, "zero offset from initial after mmap differs from 123 (TEST FAILED)"); 52 53 switch (fork()) { 54 case 0: 55 /* Child. Lock should fail. */ 56 if (fcntl(fd, F_SETLK, &fl) == 0) 57 exit(1); 58 exit(0); 59 case -1: 60 err(1, "Fork failed"); 61 } 62 63 if (wait(&status) == -1) 64 err(1, "Child vanished?"); 65 66 if (!WIFEXITED(status)) 67 errx(1, "Child died with signal %i", WTERMSIG(status)); 68 69 switch (WEXITSTATUS(status)) { 70 case 1: 71 errx(1, "Child got lock, we must have dropped it (TEST FAILED)"); 72 case 0: 73 fprintf(stderr, "Child exited with zero (TEST PASSED).\n"); 74 return 0; 75 default: 76 errx(1, "Child weird exit status %i", WEXITSTATUS(status)); 77 } 78 } 79