blob: 8bfae64431462cdc7439b4199065f250bb2fd20a [file] [log] [blame]
sewardj5f2dcad2011-10-24 08:53:03 +00001
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;
philippe8050bb72012-04-13 23:07:29 +000022 off_t initial;
sewardj5f2dcad2011-10-24 08:53:03 +000023
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
philippe8050bb72012-04-13 23:07:29 +000031 // 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
sewardj5f2dcad2011-10-24 08:53:03 +000038 fl.l_type = F_WRLCK;
39 fl.l_whence = SEEK_SET;
40 fl.l_start = 0;
41 fl.l_len = 1;
42
florianad4e9792015-07-05 21:53:33 +000043 /* I'm assuming no one else tries to lock this! */
sewardj5f2dcad2011-10-24 08:53:03 +000044 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);
philippe8050bb72012-04-13 23:07:29 +000050 if (lseek(fd, 0, SEEK_CUR) != 123)
51 errx(1, "zero offset from initial after mmap differs from 123 (TEST FAILED)");
sewardj5f2dcad2011-10-24 08:53:03 +000052
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}