]>
Commit | Line | Data |
---|---|---|
f3db3566 TT |
1 | /* |
2 | * llseek.c -- stub calling the llseek system call | |
3 | * | |
1c27cac2 | 4 | * Copyright (C) 1994, 1995, 1996, 1997 Theodore Ts'o. |
19c78dc0 TT |
5 | * |
6 | * %Begin-Header% | |
543547a5 TT |
7 | * This file may be redistributed under the terms of the GNU Library |
8 | * General Public License, version 2. | |
19c78dc0 | 9 | * %End-Header% |
f3db3566 TT |
10 | */ |
11 | ||
f1644c32 | 12 | #ifndef _LARGEFILE_SOURCE |
dc5f68ca | 13 | #define _LARGEFILE_SOURCE |
f1644c32 TT |
14 | #endif |
15 | #ifndef _LARGEFILE64_SOURCE | |
dc5f68ca | 16 | #define _LARGEFILE64_SOURCE |
f1644c32 | 17 | #endif |
dc5f68ca | 18 | |
d1154eb4 | 19 | #include "config.h" |
1d2ff46a | 20 | #if HAVE_SYS_TYPES_H |
f3db3566 | 21 | #include <sys/types.h> |
1d2ff46a | 22 | #endif |
f3db3566 | 23 | |
c555aebd | 24 | #if HAVE_ERRNO_H |
f3db3566 | 25 | #include <errno.h> |
c555aebd | 26 | #endif |
4cbe8af4 | 27 | #if HAVE_UNISTD_H |
f3db3566 | 28 | #include <unistd.h> |
4cbe8af4 | 29 | #endif |
3cb6c502 TT |
30 | #ifdef __MSDOS__ |
31 | #include <io.h> | |
32 | #endif | |
f3db3566 | 33 | #include "et/com_err.h" |
d40259fd | 34 | #include "ext2fs/ext2_io.h" |
f3db3566 TT |
35 | |
36 | #ifdef __linux__ | |
37 | ||
50e1e10f TT |
38 | #include <linux/unistd.h> |
39 | ||
1c27cac2 | 40 | static ext2_loff_t my_llseek (int fd, ext2_loff_t offset, int origin) |
50e1e10f | 41 | { |
24181bb2 MG |
42 | #if SIZEOF_OFF_T >= 8 |
43 | return lseek(fd, offset, origin); | |
44 | #elif HAVE_LSEEK64_PROTOTYPE | |
45 | return lseek64(fd, offset, origin); | |
46 | #elif HAVE_LLSEEK_PROTOTYPE | |
47 | return llseek(fd, offset, origin); | |
48 | #elif defined(__NR__llseek) | |
49 | loff_t result; | |
50e1e10f | 50 | int retval; |
24181bb2 MG |
51 | retval = syscall(__NR__llseek, fd, |
52 | (unsigned long)(offset >> 32), | |
53 | (unsigned long)(offset & 0xffffffff), | |
54 | &result, origin); | |
55 | return (retval == -1 ? retval : result); | |
efc6f628 | 56 | #else |
24181bb2 MG |
57 | errno = ENOSYS; |
58 | return -1; | |
1c27cac2 | 59 | #endif |
50e1e10f TT |
60 | } |
61 | ||
1c27cac2 | 62 | ext2_loff_t ext2fs_llseek (int fd, ext2_loff_t offset, int origin) |
f3db3566 | 63 | { |
f3db3566 | 64 | ext2_loff_t result; |
f3db3566 TT |
65 | static int do_compat = 0; |
66 | ||
274d46e1 PS |
67 | if (do_compat) |
68 | goto fallback; | |
efc6f628 | 69 | |
1c27cac2 | 70 | result = my_llseek (fd, offset, origin); |
50e1e10f | 71 | if (result == -1 && errno == ENOSYS) { |
f3db3566 TT |
72 | /* |
73 | * Just in case this code runs on top of an old kernel | |
74 | * which does not support the llseek system call | |
75 | */ | |
76 | do_compat++; | |
274d46e1 PS |
77 | fallback: |
78 | if (offset < ((ext2_loff_t) 1 << ((sizeof(off_t)*8) -1))) | |
79 | return lseek(fd, (off_t) offset, origin); | |
50e1e10f | 80 | errno = EINVAL; |
274d46e1 | 81 | return -1; |
f3db3566 | 82 | } |
f3db3566 TT |
83 | return result; |
84 | } | |
85 | ||
50e1e10f | 86 | #else /* !linux */ |
f3db3566 | 87 | |
73f17cfc TT |
88 | #ifndef EINVAL |
89 | #define EINVAL EXT2_ET_INVALID_ARGUMENT | |
90 | #endif | |
91 | ||
d163b094 | 92 | ext2_loff_t ext2fs_llseek (int fd, ext2_loff_t offset, int origin) |
f3db3566 | 93 | { |
488f3c2d TT |
94 | #if defined(HAVE_LSEEK64) && defined(HAVE_LSEEK64_PROTOTYPE) |
95 | return lseek64 (fd, offset, origin); | |
96 | #else | |
f3db3566 TT |
97 | if ((sizeof(off_t) < sizeof(ext2_loff_t)) && |
98 | (offset >= ((ext2_loff_t) 1 << ((sizeof(off_t)*8) -1)))) { | |
73f17cfc | 99 | errno = EINVAL; |
f3db3566 TT |
100 | return -1; |
101 | } | |
102 | return lseek (fd, (off_t) offset, origin); | |
488f3c2d | 103 | #endif |
f3db3566 TT |
104 | } |
105 | ||
50e1e10f | 106 | #endif /* linux */ |
f3db3566 TT |
107 | |
108 |