1/* Test for advisory record locking.
2 Copyright (C) 2023-2024 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (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 <https://www.gnu.org/licenses/>.
16*/
17
18#include <fcntl.h>
19#include <errno.h>
20#include <unistd.h>
21
22/* This is essentially the POSIX lockf. */
23
24static int
25fcntl_lockf (int fd, int cmd, off_t len)
26{
27 struct flock fl = {
28 .l_type = F_WRLCK,
29 .l_whence = SEEK_CUR,
30 .l_len = len
31 };
32
33 switch (cmd)
34 {
35 case F_TEST:
36 fl.l_type = F_RDLCK;
37 if (fcntl (fd: fd, F_GETLK, &fl) < 0)
38 return -1;
39 if (fl.l_type == F_UNLCK || fl.l_pid == getpid ())
40 return 0;
41 errno = EACCES;
42 return -1;
43
44 case F_ULOCK:
45 fl.l_type = F_UNLCK;
46 return fcntl (fd: fd, F_SETLK, &fl);
47
48 case F_LOCK:
49 return fcntl (fd: fd, F_SETLKW, &fl);
50
51 case F_TLOCK:
52 return fcntl (fd: fd, F_SETLK, &fl);
53 }
54
55 errno = EINVAL;
56 return -1;
57}
58
59static int
60fcntl64_lockf (int fd, int cmd, off64_t len64)
61 {
62 struct flock64 fl64 = {
63 .l_type = F_WRLCK,
64 .l_whence = SEEK_CUR,
65 .l_len = len64
66 };
67
68 switch (cmd)
69 {
70 case F_TEST:
71 fl64.l_type = F_RDLCK;
72 if (fcntl64 (fd: fd, F_GETLK64, &fl64) < 0)
73 return -1;
74 if (fl64.l_type == F_UNLCK || fl64.l_pid == getpid ())
75 return 0;
76 errno = EACCES;
77 return -1;
78
79 case F_ULOCK:
80 fl64.l_type = F_UNLCK;
81 return fcntl64 (fd: fd, F_SETLK64, &fl64);
82
83 case F_LOCK:
84 return fcntl64 (fd: fd, F_SETLKW64, &fl64);
85
86 case F_TLOCK:
87 return fcntl64 (fd: fd, F_SETLK64, &fl64);
88 }
89
90 errno = EINVAL;
91 return -1;
92}
93
94#define TST_LOCKFD "tst-fcntl-lock."
95#define LOCKF fcntl_lockf
96#define LOCKF64 fcntl64_lockf
97#include "tst-lockf.c"
98

source code of glibc/io/tst-fcntl-lock.c