1
/* Copyright (C) 1994,1996,1997,1998,1999,2000,2003,2006
2
Free Software Foundation, Inc.
1
/* Copyright (C) 1994-2012 Free Software Foundation, Inc.
3
2
This file is part of the GNU C Library.
5
4
The GNU C Library is free software; you can redistribute it and/or
23
22
#include <string.h>
24
23
#include <sysdep.h>
26
#include <kernel-features.h>
28
25
/* lockf is a simplified interface to fcntl's locking facilities. */
31
# if __ASSUME_FCNTL64 == 0
32
/* This variable is shared with all files that check for fcntl64. The
33
declaration is in fcntl.c. */
34
extern int __have_no_fcntl64;
39
28
lockf64 (int fd, int cmd, off64_t len64)
41
#if __ASSUME_FCNTL64 == 0
43
off_t len = (off_t) len64;
46
30
struct flock64 fl64;
50
#if __ASSUME_FCNTL64 == 0
51
memset ((char *) &fl, '\0', sizeof (fl));
53
/* lockf is always relative to the current file position. */
54
fl.l_whence = SEEK_CUR;
59
# if __ASSUME_FCNTL64 == 0
60
if (!__have_no_fcntl64)
63
memset ((char *) &fl64, '\0', sizeof (fl64));
64
fl64.l_whence = SEEK_CUR;
67
# if __ASSUME_FCNTL64 == 0
72
#if __ASSUME_FCNTL64 == 0 && !defined __NR_fcntl64
73
if (len64 != (off64_t) len)
75
/* We can't represent the length. */
76
__set_errno (EOVERFLOW);
33
memset ((char *) &fl64, '\0', sizeof (fl64));
34
fl64.l_whence = SEEK_CUR;
83
41
/* Test the lock: return 0 if FD is unlocked or locked by this process;
84
42
return -1, set errno to EACCES, if another process holds the lock. */
85
#if __ASSUME_FCNTL64 > 0
86
43
fl64.l_type = F_RDLCK;
87
44
if (INLINE_SYSCALL (fcntl64, 3, fd, F_GETLK64, &fl64) < 0)
91
48
__set_errno (EACCES);
95
if (!__have_no_fcntl64)
99
fl64.l_type = F_RDLCK;
100
res = INLINE_SYSCALL (fcntl64, 3, fd, F_GETLK64, &fl64);
101
/* If errno == ENOSYS try the 32bit interface if len64 can
102
be represented with 32 bits. */
106
if (fl64.l_type == F_UNLCK || fl64.l_pid == __getpid ())
108
__set_errno (EACCES);
111
else if (errno == ENOSYS)
112
__have_no_fcntl64 = 1;
114
/* res < 0 && errno != ENOSYS. */
116
if (len64 != (off64_t) len)
118
/* We can't represent the length. */
119
__set_errno (EOVERFLOW);
125
if (__fcntl (fd, F_GETLK, &fl) < 0)
127
if (fl.l_type == F_UNLCK || fl.l_pid == __getpid ())
129
__set_errno (EACCES);
133
#if __ASSUME_FCNTL64 == 0
138
51
fl64.l_type = F_UNLCK;
139
52
cmd64 = F_SETLK64;
143
#if __ASSUME_FCNTL64 == 0
148
55
fl64.l_type = F_WRLCK;
149
56
cmd64 = F_SETLKW64;
153
#if __ASSUME_FCNTL64 == 0
158
59
fl64.l_type = F_WRLCK;
159
60
cmd64 = F_SETLK64;
164
64
__set_errno (EINVAL);
167
#if __ASSUME_FCNTL64 > 0
168
67
return INLINE_SYSCALL (fcntl64, 3, fd, cmd64, &fl64);
172
if (!__have_no_fcntl64)
174
int res = INLINE_SYSCALL (fcntl64, 3, fd, cmd64, &fl64);
176
/* If errno == ENOSYS try the 32bit interface if len64 can
177
be represented with 32 bits. */
178
if (res == 0 || errno != ENOSYS)
181
__have_no_fcntl64 = 1;
183
if (len64 != (off64_t) len)
185
/* We can't represent the length. */
186
__set_errno (EOVERFLOW);
191
return __fcntl (fd, cmd, &fl);