1 /* Test of flock() function.
2 Copyright (C) 2008-2020 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/>. */
21 #include "signature.h"
22 SIGNATURE_CHECK (flock
, int, (int, int));
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.
38 ASSERT (flock (fd
, LOCK_SH
) == 0);
40 fd2
= open (file
, O_RDWR
, 0644);
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);
51 test_exclusive (const char *file
, int fd
)
53 /* Should not be able to acquire more than one exclusive lock on a file. */
56 ASSERT (flock (fd
, LOCK_EX
) == 0);
58 fd2
= open (file
, O_RDWR
, 0644);
61 r
= flock (fd2
, LOCK_EX
| LOCK_NB
);
62 ASSERT (r
== -1); /* Was unable to acquire a second exclusive lock. */
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
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
);
86 ASSERT (flock (fd
, LOCK_UN
) == 0);
87 ASSERT (close (fd2
) == 0);
91 main (int argc
, char *argv
[])
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);
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
);
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);