]>
Commit | Line | Data |
---|---|---|
a0948ffe KZ |
1 | /* |
2 | * llseek.c -- stub calling the llseek system call | |
3 | * | |
4 | * Copyright (C) 1994, 1995, 1996, 1997 Theodore Ts'o. | |
5 | * | |
6 | * %Begin-Header% | |
7 | * This file may be redistributed under the terms of the | |
8 | * GNU Lesser General Public License. | |
9 | * %End-Header% | |
10 | */ | |
11 | ||
d655ceac KZ |
12 | #ifndef _LARGEFILE_SOURCE |
13 | # define _LARGEFILE_SOURCE | |
14 | #endif | |
15 | ||
16 | #ifndef _LARGEFILE64_SOURCE | |
17 | # define _LARGEFILE64_SOURCE | |
18 | #endif | |
a0948ffe | 19 | |
fbc333fe | 20 | #ifdef HAVE_SYS_TYPES_H |
a0948ffe KZ |
21 | #include <sys/types.h> |
22 | #endif | |
23 | ||
fbc333fe | 24 | #ifdef HAVE_ERRNO_H |
a0948ffe KZ |
25 | #include <errno.h> |
26 | #endif | |
fbc333fe | 27 | #ifdef HAVE_UNISTD_H |
a0948ffe KZ |
28 | #include <unistd.h> |
29 | #endif | |
30 | #ifdef __MSDOS__ | |
31 | #include <io.h> | |
32 | #endif | |
33 | ||
34 | #include "blkidP.h" | |
35 | ||
36 | #ifdef __linux__ | |
37 | ||
2a7f8a8b | 38 | #if defined(HAVE_LSEEK64) && defined(HAVE_LSEEK64_PROTOTYPE) |
a0948ffe KZ |
39 | |
40 | #define my_llseek lseek64 | |
41 | ||
42 | #elif defined(HAVE_LLSEEK) | |
43 | #include <syscall.h> | |
44 | ||
45 | #ifndef HAVE_LLSEEK_PROTOTYPE | |
46 | extern long long llseek(int fd, long long offset, int origin); | |
47 | #endif | |
48 | ||
49 | #define my_llseek llseek | |
50 | ||
51 | #else /* ! HAVE_LLSEEK */ | |
52 | ||
53 | #if SIZEOF_LONG == SIZEOF_LONG_LONG | |
54 | ||
55 | #define llseek lseek | |
56 | ||
57 | #else /* SIZEOF_LONG != SIZEOF_LONG_LONG */ | |
58 | ||
59 | #include <linux/unistd.h> | |
60 | ||
61 | #ifndef __NR__llseek | |
62 | #define __NR__llseek 140 | |
63 | #endif | |
64 | ||
65 | #ifndef __i386__ | |
66 | static int _llseek(unsigned int, unsigned long, unsigned long, | |
67 | blkid_loff_t *, unsigned int); | |
68 | ||
69 | static _syscall5(int, _llseek, unsigned int, fd, unsigned long, offset_high, | |
70 | unsigned long, offset_low, blkid_loff_t *, result, | |
71 | unsigned int, origin) | |
72 | #endif | |
73 | ||
74 | static blkid_loff_t my_llseek(int fd, blkid_loff_t offset, int origin) | |
75 | { | |
76 | blkid_loff_t result; | |
77 | int retval; | |
78 | ||
79 | #ifndef __i386__ | |
80 | retval = _llseek(fd, ((unsigned long long) offset) >> 32, | |
81 | ((unsigned long long)offset) & 0xffffffff, | |
82 | &result, origin); | |
83 | #else | |
84 | retval = syscall(__NR__llseek, fd, ((unsigned long long) offset) >> 32, | |
85 | ((unsigned long long)offset) & 0xffffffff, | |
86 | &result, origin); | |
87 | #endif | |
88 | return (retval == -1 ? (blkid_loff_t) retval : result); | |
89 | } | |
90 | ||
91 | #endif /* __alpha__ || __ia64__ */ | |
92 | ||
93 | #endif /* HAVE_LLSEEK */ | |
94 | ||
95 | blkid_loff_t blkid_llseek(int fd, blkid_loff_t offset, int whence) | |
96 | { | |
97 | blkid_loff_t result; | |
98 | static int do_compat = 0; | |
99 | ||
100 | if ((sizeof(off_t) >= sizeof(blkid_loff_t)) || | |
101 | (offset < ((blkid_loff_t) 1 << ((sizeof(off_t)*8) -1)))) | |
102 | return lseek(fd, (off_t) offset, whence); | |
103 | ||
104 | if (do_compat) { | |
105 | errno = EOVERFLOW; | |
106 | return -1; | |
107 | } | |
108 | ||
109 | result = my_llseek(fd, offset, whence); | |
110 | if (result == -1 && errno == ENOSYS) { | |
111 | /* | |
112 | * Just in case this code runs on top of an old kernel | |
113 | * which does not support the llseek system call | |
114 | */ | |
115 | do_compat++; | |
116 | errno = EOVERFLOW; | |
117 | } | |
118 | return result; | |
119 | } | |
120 | ||
121 | #else /* !linux */ | |
122 | ||
123 | #ifndef EOVERFLOW | |
124 | #ifdef EXT2_ET_INVALID_ARGUMENT | |
125 | #define EOVERFLOW EXT2_ET_INVALID_ARGUMENT | |
126 | #else | |
127 | #define EOVERFLOW 112 | |
128 | #endif | |
129 | #endif | |
130 | ||
131 | blkid_loff_t blkid_llseek(int fd, blkid_loff_t offset, int origin) | |
132 | { | |
133 | #if defined(HAVE_LSEEK64) && defined(HAVE_LSEEK64_PROTOTYPE) | |
134 | return lseek64 (fd, offset, origin); | |
135 | #else | |
136 | if ((sizeof(off_t) < sizeof(blkid_loff_t)) && | |
137 | (offset >= ((blkid_loff_t) 1 << ((sizeof(off_t)*8) - 1)))) { | |
138 | errno = EOVERFLOW; | |
139 | return -1; | |
140 | } | |
141 | return lseek(fd, (off_t) offset, origin); | |
142 | #endif | |
143 | } | |
144 | ||
145 | #endif /* linux */ | |
146 | ||
147 |