usleep tests: Avoid failure due to known Cygwin 3.5.3 bug.
[gnulib.git] / tests / test-flock.c
blob8ff301d2069b169317c80b1b391ed37a716e3444
1 /* Test of flock() function.
2 Copyright (C) 2008-2024 Free Software Foundation, Inc.
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 3 of the License, or
7 (at your option) any later version.
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.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <https://www.gnu.org/licenses/>. */
17 #include <config.h>
19 #include <sys/file.h>
21 #include "signature.h"
22 SIGNATURE_CHECK (flock, int, (int, int));
24 #include <fcntl.h>
25 #include <unistd.h>
26 #include <errno.h>
28 #include "macros.h"
30 static void
31 test_shared (const char *file, int fd)
33 /* Should be able to acquire several shared locks on a file, through
34 * different file table entries.
36 int fd2, r;
38 ASSERT (flock (fd, LOCK_SH) == 0);
40 fd2 = open (file, O_RDWR, 0644);
41 ASSERT (fd2 >= 0);
43 r = flock (fd2, LOCK_SH | LOCK_NB);
44 ASSERT (r == 0); /* Was able to acquire a second shared lock. */
46 ASSERT (flock (fd, LOCK_UN) == 0);
47 ASSERT (close (fd2) == 0);
50 static void
51 test_exclusive (const char *file, int fd)
53 /* Should not be able to acquire more than one exclusive lock on a file. */
54 int fd2, r;
56 ASSERT (flock (fd, LOCK_EX) == 0);
58 fd2 = open (file, O_RDWR, 0644);
59 ASSERT (fd2 >= 0);
61 r = flock (fd2, LOCK_EX | LOCK_NB);
62 ASSERT (r == -1); /* Was unable to acquire a second exclusive lock. */
64 #if 0
65 /* The Linux manual page of flock(2) says:
66 "A process may only hold one type of lock (shared or exclusive) on a
67 file. Subsequent flock() calls on an already locked file will convert
68 an existing lock to the new lock mode."
69 So, the call below should convert the exclusive lock for fd to a shared
70 and thus succeeds. The fact that it doesn't but instead fails is
71 apparently a bug. */
72 /* The Solaris manual page of flock(2) says:
73 "More than one process may hold a shared lock for a file at any given
74 time, but multiple exclusive, or both shared and exclusive, locks may
75 not exist simultaneously on a file. ...
76 Requesting a lock on an object that is already locked normally causes
77 the caller to block until the lock may be acquired. If LOCK_NB is
78 included in operation, then this will not happen; instead, the call
79 will fail and the error EWOULDBLOCK will be returned."
80 So, the call below should fail and set errno to EWOULDBLOCK. The fact
81 that it succeeds is apparently a bug. */
82 r = flock (fd2, LOCK_SH | LOCK_NB);
83 ASSERT (r == -1);
84 #endif
86 ASSERT (flock (fd, LOCK_UN) == 0);
87 ASSERT (close (fd2) == 0);
90 int
91 main (int argc, char *argv[])
93 int fd;
94 const char *file = "test-flock.txt";
96 /* Open a non-empty file for testing. */
97 fd = open (file, O_RDWR | O_CREAT | O_TRUNC, 0644);
98 ASSERT (fd >= 0);
99 ASSERT (write (fd, "hello", 5) == 5);
101 #if defined __linux__ || defined __ANDROID__
102 /* Invalid operation codes are rejected by the Linux implementation and by
103 the gnulib replacement, but not by the Mac OS X implementation. */
104 ASSERT (flock (fd, LOCK_SH | LOCK_EX) == -1);
105 ASSERT (errno == EINVAL);
106 ASSERT (flock (fd, LOCK_SH | LOCK_UN) == -1);
107 ASSERT (errno == EINVAL);
108 ASSERT (flock (fd, LOCK_EX | LOCK_UN) == -1);
109 ASSERT (errno == EINVAL);
110 ASSERT (flock (fd, 0) == -1);
111 ASSERT (errno == EINVAL);
112 #endif
114 test_shared (file, fd);
115 test_exclusive (file, fd);
117 /* Close and remove the test file. */
118 ASSERT (close (fd) == 0);
119 ASSERT (unlink (file) == 0);
121 return test_exit_status;