]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/valgrind/src/valgrind-3.6.0-svn/memcheck/tests/file_locking.c
Inital import
[l4.git] / l4 / pkg / valgrind / src / valgrind-3.6.0-svn / memcheck / tests / file_locking.c
1 /** Test program for POSIX advisory record locking. See also #164669
2  *  (http://bugs.kde.org/show_bug.cgi?id=164669).
3  *  See also http://www.opengroup.org/onlinepubs/007908799/xsh/fcntl.html.
4  */
5
6
7 #include <assert.h>
8 #include <errno.h>
9 #include <fcntl.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include "tests/sys_mman.h"
13 #include <sys/stat.h>
14 #include <sys/types.h>
15 #include <sys/wait.h>
16 #include <unistd.h>
17 #include <unistd.h>
18
19
20 /** Lock an entire file exclusively.
21  *
22  *  @return 1 upon success, 0 upon failure.
23  */
24 static int lock_file(const int fd)
25 {
26   struct flock fl;
27
28   fl.l_type   = F_WRLCK;  /* exclusive lock */
29   fl.l_whence = SEEK_SET;
30   fl.l_start  = 0;
31   fl.l_len    = 0;        /* lock entire file */
32   fl.l_pid    = 0;
33   return fcntl(fd, F_SETLK, &fl) >= 0;
34 }
35
36 static int open_lock_and_map(const char* const process_name,
37                              const char* const filename)
38 {
39   int fd;
40   int flags;
41
42   fd = open(filename, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
43   if (fd < 0)
44   {
45     perror("open");
46     goto err1;
47   }
48
49   flags = fcntl(fd, F_GETFD);
50   assert(flags >= 0);
51   if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) < 0)
52     assert(0);
53
54   fprintf(stderr, "%s: about to lock file for writing.\n", process_name);
55   if (! lock_file(fd))
56   {
57     perror("fcntl");
58     goto err2;
59   }
60
61   fprintf(stderr, "%s: file locking attempt succeeded.\n", process_name);
62   if (mmap(NULL, 1, PROT_WRITE, MAP_SHARED, fd, 0) == 0)
63   {
64     perror("mmap");
65     goto err2;
66   }
67
68   goto out;
69
70 err2:
71   close(fd);
72 err1:
73 out:
74   return fd;
75 }
76
77 int main(int argc, char *argv[]) 
78 {
79   int fd1;
80   int fd2;
81   int exitcode = 1;
82   char filename[256];
83
84   snprintf(filename, sizeof(filename), "/tmp/valgrind-file-locking-test.%d",
85            getpid());
86
87   unlink(filename);
88
89   if ((fd1 = open_lock_and_map("parent", filename)) >= 0)
90   {
91     pid_t fork_result;
92
93     fork_result = fork();
94     switch (fork_result)
95     {
96     case -1:
97       perror("fork");
98       break;
99
100     case 0:
101       /* child */
102       fd2 = open_lock_and_map("child", filename);
103       if (fd2 >= 0)
104       {
105         close(fd2);
106       }
107       exit(0);
108       break;
109
110     default:
111       /* parent */
112       {
113         int child_status;
114         int wait_result;
115
116         wait_result = wait4(fork_result, &child_status, 0, 0);
117         assert(wait_result >= 0);
118       }
119     }
120   }
121
122   close(fd1);
123
124   unlink(filename);
125
126   fprintf(stderr, "Test finished.\n");
127
128   return exitcode;
129 }