mmap_fcntl_bug.c revision 8f943afc22a6a683b78271836c8ddc462b4824a9
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 16int 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 23 if (!file) 24 errx(1, "Usage: %s <normal-file>", argv[0]); 25 26 fd = open(file, O_RDWR); 27 if (fd < 0) 28 err(1, "Opening %s", file); 29 30 fl.l_type = F_WRLCK; 31 fl.l_whence = SEEK_SET; 32 fl.l_start = 0; 33 fl.l_len = 1; 34 35 /* I'm assuming noone else tries to lock this! */ 36 if (fcntl(fd, F_SETLK, &fl) != 0) 37 err(1, "Locking %s", file); 38 39 /* If under valgrind, mmap re-opens and closes file, screwing us */ 40 if (mmap(NULL, getpagesize(), PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0) == MAP_FAILED) 41 err(1, "mmap of %s", file); 42 43 switch (fork()) { 44 case 0: 45 /* Child. Lock should fail. */ 46 if (fcntl(fd, F_SETLK, &fl) == 0) 47 exit(1); 48 exit(0); 49 case -1: 50 err(1, "Fork failed"); 51 } 52 53 if (wait(&status) == -1) 54 err(1, "Child vanished?"); 55 56 if (!WIFEXITED(status)) 57 errx(1, "Child died with signal %i", WTERMSIG(status)); 58 59 switch (WEXITSTATUS(status)) { 60 case 1: 61 errx(1, "Child got lock, we must have dropped it (TEST FAILED)"); 62 case 0: 63 fprintf(stderr, "Child exited with zero (TEST PASSED).\n"); 64 return 0; 65 default: 66 errx(1, "Child weird exit status %i", WEXITSTATUS(status)); 67 } 68} 69