1 /* Copyright (C) 1994,1996,1997,1998,1999,2000,2003,2006
2 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20 #include <sys/types.h>
27 #include <kernel-features.h>
29 /* lockf is a simplified interface to fcntl's locking facilities. */
32 # if __ASSUME_FCNTL64 == 0
33 /* This variable is shared with all files that check for fcntl64. The
34 declaration is in fcntl.c. */
35 extern int __have_no_fcntl64
;
40 lockf64 (int fd
, int cmd
, off64_t len64
)
42 #if __ASSUME_FCNTL64 == 0
44 off_t len
= (off_t
) len64
;
51 #if __ASSUME_FCNTL64 == 0
52 memset ((char *) &fl
, '\0', sizeof (fl
));
54 /* lockf is always relative to the current file position. */
55 fl
.l_whence
= SEEK_CUR
;
60 # if __ASSUME_FCNTL64 == 0
61 if (!__have_no_fcntl64
)
64 memset ((char *) &fl64
, '\0', sizeof (fl64
));
65 fl64
.l_whence
= SEEK_CUR
;
68 # if __ASSUME_FCNTL64 == 0
73 #if __ASSUME_FCNTL64 == 0 && !defined __NR_fcntl64
74 if (len64
!= (off64_t
) len
)
76 /* We can't represent the length. */
77 __set_errno (EOVERFLOW
);
84 /* Test the lock: return 0 if FD is unlocked or locked by this process;
85 return -1, set errno to EACCES, if another process holds the lock. */
86 #if __ASSUME_FCNTL64 > 0
87 fl64
.l_type
= F_RDLCK
;
88 if (INLINE_SYSCALL (fcntl64
, 3, fd
, F_GETLK64
, &fl64
) < 0)
90 if (fl64
.l_type
== F_UNLCK
|| fl64
.l_pid
== __getpid ())
96 if (!__have_no_fcntl64
)
100 fl64
.l_type
= F_RDLCK
;
101 res
= INLINE_SYSCALL (fcntl64
, 3, fd
, F_GETLK64
, &fl64
);
102 /* If errno == ENOSYS try the 32bit interface if len64 can
103 be represented with 32 bits. */
107 if (fl64
.l_type
== F_UNLCK
|| fl64
.l_pid
== __getpid ())
109 __set_errno (EACCES
);
112 else if (errno
== ENOSYS
)
113 __have_no_fcntl64
= 1;
115 /* res < 0 && errno != ENOSYS. */
117 if (len64
!= (off64_t
) len
)
119 /* We can't represent the length. */
120 __set_errno (EOVERFLOW
);
126 if (__fcntl (fd
, F_GETLK
, &fl
) < 0)
128 if (fl
.l_type
== F_UNLCK
|| fl
.l_pid
== __getpid ())
130 __set_errno (EACCES
);
134 #if __ASSUME_FCNTL64 == 0
139 fl64
.l_type
= F_UNLCK
;
144 #if __ASSUME_FCNTL64 == 0
149 fl64
.l_type
= F_WRLCK
;
154 #if __ASSUME_FCNTL64 == 0
159 fl64
.l_type
= F_WRLCK
;
165 __set_errno (EINVAL
);
168 #if __ASSUME_FCNTL64 > 0
169 return INLINE_SYSCALL (fcntl64
, 3, fd
, cmd64
, &fl64
);
173 if (!__have_no_fcntl64
)
175 int res
= INLINE_SYSCALL (fcntl64
, 3, fd
, cmd64
, &fl64
);
177 /* If errno == ENOSYS try the 32bit interface if len64 can
178 be represented with 32 bits. */
179 if (res
== 0 || errno
!= ENOSYS
)
182 __have_no_fcntl64
= 1;
184 if (len64
!= (off64_t
) len
)
186 /* We can't represent the length. */
187 __set_errno (EOVERFLOW
);
192 return __fcntl (fd
, cmd
, &fl
);