]> git.ipfire.org Git - thirdparty/glibc.git/blob - sysdeps/unix/sysv/linux/i386/fcntl.c
Define __have_no_fcntl64 static.
[thirdparty/glibc.git] / sysdeps / unix / sysv / linux / i386 / fcntl.c
1 /* Copyright (C) 2000 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 Library General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 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 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public
15 License along with the GNU C Library; see the file COPYING.LIB. If not,
16 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA. */
18
19 #include <errno.h>
20 #include <fcntl.h>
21 #include <stdarg.h>
22
23 #include <sysdep.h>
24 #include <sys/syscall.h>
25 #include "../kernel-features.h"
26
27
28 #if __ASSUME_FCNTL64 == 0
29 /* This variable is shared with all files that check for fcntl64. */
30 static int __have_no_fcntl64;
31 #endif
32
33 int
34 __libc_fcntl (int fd, int cmd, ...)
35 {
36 va_list ap;
37 void *arg;
38
39 va_start (ap, cmd);
40 arg = va_arg (ap, void *);
41 va_end (ap);
42
43 #if __ASSUME_FCNTL64 > 0
44 return INLINE_SYSCALL (fcntl64, 3, fd, cmd, arg);
45 #else
46 # ifdef __NR_fcntl64
47 if (! __have_no_fcntl64)
48 {
49 int result = INLINE_SYSCALL (fcntl64, 3, fd, cmd, arg);
50 if (result >= 0 || errno != ENOSYS)
51 return result;
52
53 __have_no_fcntl64 = 1;
54 }
55 # endif
56 switch (cmd)
57 {
58 case F_GETLK64:
59 /* Convert arg from flock64 to flock and back. */
60 {
61 struct flock fl;
62 struct flock64 *fl64 = arg;
63 int res;
64
65 fl.l_start = (off_t)fl64->l_start;
66 /* Check if we can represent the values with the smaller type. */
67 if ((off64_t) fl.l_start != fl64->l_start)
68 {
69 __set_errno (EOVERFLOW);
70 return -1;
71 }
72 fl.l_len = (off_t) fl64->l_len;
73 /* Check if we can represent the values with the smaller type. */
74 if ((off64_t) fl.l_len != fl64->l_len)
75 {
76 __set_errno (EOVERFLOW);
77 return -1;
78 }
79 fl.l_type = fl64->l_type;
80 fl.l_whence = fl64->l_whence;
81 fl.l_pid = fl64->l_pid;
82
83 res = INLINE_SYSCALL (fcntl, 3, fd, cmd, &fl);
84 if (res != 0)
85 return res;
86 /* Everything ok, convert back. */
87 fl64->l_type = fl.l_type;
88 fl64->l_whence = fl.l_whence;
89 fl64->l_start = fl.l_start;
90 fl64->l_len = fl.l_len;
91 fl64->l_pid = fl.l_pid;
92
93 return 0;
94 }
95 case F_SETLK64:
96 case F_SETLKW64:
97 /* Try to convert arg from flock64 to flock. */
98 {
99 struct flock fl;
100 struct flock64 *fl64 = arg;
101
102 fl.l_start = (off_t) fl64->l_start;
103 /* Check if we can represent the values with the smaller type. */
104 if ((off64_t) fl.l_start != fl64->l_start)
105 {
106 __set_errno (EOVERFLOW);
107 return -1;
108 }
109 fl.l_len = (off_t)fl64->l_len;
110 /* Check if we can represent the values with the smaller type. */
111 if ((off64_t) fl.l_len != fl64->l_len)
112 {
113 __set_errno (EOVERFLOW);
114 return -1;
115 }
116 fl.l_type = fl64->l_type;
117 fl.l_whence = fl64->l_whence;
118 fl.l_pid = fl64->l_pid;
119 return INLINE_SYSCALL (fcntl, 3, fd, cmd, &fl);
120 }
121 default:
122 return INLINE_SYSCALL (fcntl, 3, fd, cmd, arg);
123 }
124 return -1;
125 #endif /* __ASSUME_FCNTL64 */
126 }
127
128 weak_alias (__libc_fcntl, __fcntl)
129 weak_alias (__libc_fcntl, fcntl)