1 /* Copyright (C) 1994-2022 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3 
4    The GNU C Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 2.1 of the License, or (at your option) any later version.
8 
9    The GNU C Library 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 GNU
12    Lesser General Public License for more details.
13 
14    You should have received a copy of the GNU Lesser General Public
15    License along with the GNU C Library; if not, see
16    <https://www.gnu.org/licenses/>.  */
17 
18 #include <bits/types.h>
19 
20 #ifndef __OFF_T_MATCHES_OFF64_T
21 
22 #include <unistd.h>
23 #include <fcntl.h>
24 #include <errno.h>
25 
26 /* lockf is a simplified interface to fcntl's locking facilities.  */
27 int
lockf(int fd,int cmd,off_t len)28 lockf (int fd, int cmd, off_t len)
29 {
30   /* lockf is always relative to the current file position.  */
31   struct flock fl = {
32     .l_type = F_WRLCK,
33     .l_whence = SEEK_CUR,
34     .l_len = len
35   };
36 
37   /* lockf() is a cancellation point but so is fcntl() if F_SETLKW is
38      used.  Therefore we don't have to care about cancellation here,
39      the fcntl() function will take care of it.  */
40   switch (cmd)
41     {
42     case F_TEST:
43       /* Test the lock: return 0 if FD is unlocked or locked by this process;
44 	 return -1, set errno to EACCES, if another process holds the lock.  */
45       fl.l_type = F_RDLCK;
46       if (__fcntl (fd, F_GETLK, &fl) < 0)
47 	return -1;
48       if (fl.l_type == F_UNLCK || fl.l_pid == __getpid ())
49 	return 0;
50       __set_errno (EACCES);
51       return -1;
52     case F_ULOCK:
53       fl.l_type = F_UNLCK;
54       return __fcntl (fd, F_SETLK, &fl);
55     case F_LOCK:
56       return __fcntl (fd, F_SETLKW, &fl);
57     case F_TLOCK:
58       return __fcntl (fd, F_SETLK, &fl);
59     }
60   __set_errno (EINVAL);
61   return -1;
62 }
63 #endif
64