]> git.ipfire.org Git - thirdparty/util-linux.git/blame - fdisk/llseek.c
Imported from util-linux-2.10s tarball.
[thirdparty/util-linux.git] / fdisk / llseek.c
CommitLineData
6dbe3af9
KZ
1/*
2 * llseek.c -- stub calling the llseek system call
3 *
4 * Copyright (C) 1994 Remy Card. This file may be redistributed
5 * under the terms of the GNU Public License.
6 */
7
8#include <sys/types.h>
9
10#include <errno.h>
11#include <unistd.h>
fd6b7a7f 12
6dbe3af9 13#if defined(__GNUC__) || defined(HAS_LONG_LONG)
fd6b7a7f 14typedef long long ext2_loff_t;
6dbe3af9 15#else
fd6b7a7f 16typedef long ext2_loff_t;
6dbe3af9
KZ
17#endif
18
2b6fc908 19extern ext2_loff_t ext2_llseek (unsigned int, ext2_loff_t, unsigned int);
6dbe3af9
KZ
20
21#ifdef __linux__
22
fd6b7a7f
KZ
23#ifdef HAVE_LLSEEK
24#include <syscall.h>
25
26#else /* HAVE_LLSEEK */
27
22853e4a 28#if defined(__alpha__) || defined(__ia64__)
fd6b7a7f
KZ
29
30#define my_llseek lseek
31
2b6fc908
KZ
32#else
33#include <linux/unistd.h> /* for __NR__llseek */
6dbe3af9
KZ
34
35static int _llseek (unsigned int, unsigned long,
36 unsigned long, ext2_loff_t *, unsigned int);
37
66ee8158
KZ
38#ifdef __NR__llseek
39
6dbe3af9
KZ
40static _syscall5(int,_llseek,unsigned int,fd,unsigned long,offset_high,
41 unsigned long, offset_low,ext2_loff_t *,result,
42 unsigned int, origin)
43
66ee8158
KZ
44#else
45
46/* no __NR__llseek on compilation machine - might give it explicitly */
47static int _llseek (unsigned int fd, unsigned long oh,
48 unsigned long ol, ext2_loff_t *result,
49 unsigned int origin) {
50 errno = ENOSYS;
51 return -1;
52}
53
54#endif
55
fd6b7a7f
KZ
56static ext2_loff_t my_llseek (unsigned int fd, ext2_loff_t offset,
57 unsigned int origin)
58{
59 ext2_loff_t result;
60 int retval;
61
62 retval = _llseek (fd, ((unsigned long long) offset) >> 32,
63 ((unsigned long long) offset) & 0xffffffff,
64 &result, origin);
65 return (retval == -1 ? (ext2_loff_t) retval : result);
66}
67
fd6b7a7f
KZ
68#endif /* __alpha__ */
69
70#endif /* HAVE_LLSEEK */
71
6dbe3af9
KZ
72ext2_loff_t ext2_llseek (unsigned int fd, ext2_loff_t offset,
73 unsigned int origin)
74{
6dbe3af9 75 ext2_loff_t result;
6dbe3af9
KZ
76 static int do_compat = 0;
77
2b6fc908
KZ
78 if (!do_compat) {
79 result = my_llseek (fd, offset, origin);
80 if (!(result == -1 && errno == ENOSYS))
81 return result;
fd6b7a7f 82
6dbe3af9
KZ
83 /*
84 * Just in case this code runs on top of an old kernel
85 * which does not support the llseek system call
86 */
2b6fc908
KZ
87 do_compat = 1;
88 /*
89 * Now try ordinary lseek.
90 */
6dbe3af9 91 }
2b6fc908
KZ
92
93 if ((sizeof(off_t) >= sizeof(ext2_loff_t)) ||
94 (offset < ((ext2_loff_t) 1 << ((sizeof(off_t)*8) -1))))
95 return lseek(fd, (off_t) offset, origin);
96
97 errno = EINVAL;
98 return -1;
6dbe3af9
KZ
99}
100
fd6b7a7f 101#else /* !linux */
6dbe3af9
KZ
102
103ext2_loff_t ext2_llseek (unsigned int fd, ext2_loff_t offset,
104 unsigned int origin)
105{
106 if ((sizeof(off_t) < sizeof(ext2_loff_t)) &&
107 (offset >= ((ext2_loff_t) 1 << ((sizeof(off_t)*8) -1)))) {
fd6b7a7f 108 errno = EINVAL;
6dbe3af9
KZ
109 return -1;
110 }
111 return lseek (fd, (off_t) offset, origin);
112}
113
fd6b7a7f 114#endif /* linux */
6dbe3af9
KZ
115
116