flock: new module
[gnulib.git] / tests / test-flock.c
1 /* Test of flock() function.
2    Copyright (C) 2008 Free Software Foundation, Inc.
3
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 2 of the License, or
7    (at your option) any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <unistd.h>
20 #include <errno.h>
21
22 #include <sys/file.h>
23
24 #define ASSERT(expr) \
25   do                                                                    \
26     {                                                                   \
27       if (!(expr))                                                      \
28         {                                                               \
29           fprintf (stderr, "%s:%d: assertion failed, errno = %d\n",     \
30                    __FILE__, __LINE__, errno);                          \
31           fflush (stderr);                                              \
32           abort ();                                                     \
33         }                                                               \
34     }                                                                   \
35   while (0)
36
37 static void
38 test_shared (const char *file, int fd)
39 {
40   /* Should be able to acquire several shared locks on a file, through
41    * different file table entries.
42    */
43   int fd2, r;
44
45   ASSERT (flock (fd, LOCK_SH) == 0);
46
47   fd2 = open (file, O_RDWR, 0644);
48   ASSERT (fd2 >= 0);
49
50   r = flock (fd2, LOCK_SH | LOCK_NB);
51   ASSERT (r == 0);              /* Was able to acquire a second shared lock. */
52
53   ASSERT (flock (fd, LOCK_UN) == 0);
54   ASSERT (close (fd2) == 0);
55 }
56
57 static void
58 test_exclusive (const char *file, int fd)
59 {
60   /* Should not be able to acquire more than one exclusive lock on a file. */
61   int fd2, r;
62
63   ASSERT (flock (fd, LOCK_EX) == 0);
64
65   fd2 = open (file, O_RDWR, 0644);
66   ASSERT (fd2 >= 0);
67
68   r = flock (fd2, LOCK_SH | LOCK_NB);
69   ASSERT (r == -1);             /* Was unable to acquire a second exclusive lock. */
70
71   ASSERT (flock (fd, LOCK_UN) == 0);
72   ASSERT (close (fd2) == 0);
73 }
74
75 int
76 main (int argc, char *argv[])
77 {
78   int fd;
79   const char *file = "test-flock.txt";
80
81   /* Open a non-empty file for testing. */
82   fd = open (file, O_RDWR | O_CREAT | O_TRUNC, 0644);
83   ASSERT (fd >= 0);
84   ASSERT (write (fd, "hello", 5) == 5);
85
86   /* Some impossible operation codes which should never be accepted. */
87   ASSERT (flock (fd, LOCK_SH | LOCK_EX) == -1);
88   ASSERT (errno == EINVAL);
89   ASSERT (flock (fd, LOCK_SH | LOCK_UN) == -1);
90   ASSERT (errno == EINVAL);
91   ASSERT (flock (fd, LOCK_EX | LOCK_UN) == -1);
92   ASSERT (errno == EINVAL);
93   ASSERT (flock (fd, 0) == -1);
94   ASSERT (errno == EINVAL);
95
96   test_shared (file, fd);
97   test_exclusive (file, fd);
98
99   /* Close and remove the test file. */
100   ASSERT (close (fd) == 0);
101   ASSERT (unlink (file) == 0);
102
103   return 0;
104 }