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