summaryrefslogtreecommitdiffstats
path: root/disk-utils/llseek.c
diff options
context:
space:
mode:
Diffstat (limited to 'disk-utils/llseek.c')
-rw-r--r--disk-utils/llseek.c83
1 files changed, 54 insertions, 29 deletions
diff --git a/disk-utils/llseek.c b/disk-utils/llseek.c
index 3e59ec953..dcbfb2a45 100644
--- a/disk-utils/llseek.c
+++ b/disk-utils/llseek.c
@@ -11,26 +11,39 @@
#include <errno.h>
#include <unistd.h>
-#include <linux/unistd.h>
+
#ifndef FOR_UTIL_LINUX
+
#include "et/com_err.h"
#include "ext2fs/io.h"
-#endif
-#ifdef FOR_UTIL_LINUX
+#else /* FOR_UTIL_LINUX */
+
#if defined(__GNUC__) || defined(HAS_LONG_LONG)
-typedef long long ext2_loff_t;
+typedef long long ext2_loff_t;
#else
-typedef long ext2_loff_t;
+typedef long ext2_loff_t;
#endif
-extern ext2_loff_t ext2_llseek(unsigned int fd,
- ext2_loff_t offset,
- unsigned int origin);
-#endif
+ext2_loff_t ext2_llseek (unsigned int, ext2_loff_t, unsigned int);
+
+#endif /* FOR_UTIL_LINUX */
#ifdef __linux__
+#ifdef HAVE_LLSEEK
+#include <syscall.h>
+
+#else /* HAVE_LLSEEK */
+
+#ifdef __alpha__
+
+#define my_llseek lseek
+
+#elif __i386__
+
+#include <linux/unistd.h>
+
#ifndef __NR__llseek
#define __NR__llseek 140
#endif
@@ -42,54 +55,66 @@ static _syscall5(int,_llseek,unsigned int,fd,unsigned long,offset_high,
unsigned long, offset_low,ext2_loff_t *,result,
unsigned int, origin)
+static ext2_loff_t my_llseek (unsigned int fd, ext2_loff_t offset,
+ unsigned int origin)
+{
+ ext2_loff_t result;
+ int retval;
+
+ retval = _llseek (fd, ((unsigned long long) offset) >> 32,
+ ((unsigned long long) offset) & 0xffffffff,
+ &result, origin);
+ return (retval == -1 ? (ext2_loff_t) retval : result);
+}
+
+#else
+
+#error "llseek() is not available"
+
+#endif /* __alpha__ */
+
+#endif /* HAVE_LLSEEK */
+
ext2_loff_t ext2_llseek (unsigned int fd, ext2_loff_t offset,
unsigned int origin)
{
- unsigned long offset_high;
- unsigned long offset_low;
ext2_loff_t result;
- int retval;
static int do_compat = 0;
+ if ((sizeof(off_t) >= sizeof(ext2_loff_t)) ||
+ (offset < ((ext2_loff_t) 1 << ((sizeof(off_t)*8) -1))))
+ return lseek(fd, (off_t) offset, origin);
+
if (do_compat) {
- compat_lseek:
- if ((sizeof(off_t) < sizeof(ext2_loff_t)) &&
- (offset >= ((ext2_loff_t) 1 << ((sizeof(off_t)*8) -1)))) {
- errno = -EINVAL;
- return -1;
- }
- return lseek (fd, (off_t) offset, origin);
+ errno = EINVAL;
+ return -1;
}
- offset_high = ((unsigned long long) offset) >> 32;
- offset_low = ((unsigned long long) offset) & 0xffffffff;
- retval = _llseek (fd, offset_high, offset_low, &result, origin);
- if (retval == -1 && errno == ENOSYS) {
+ result = my_llseek (fd, offset, origin);
+ if (result == -1 && errno == ENOSYS) {
/*
* Just in case this code runs on top of an old kernel
* which does not support the llseek system call
*/
do_compat++;
- goto compat_lseek;
+ errno = EINVAL;
}
- if (retval == -1)
- result = -1;
return result;
}
-#else
+#else /* !linux */
ext2_loff_t ext2_llseek (unsigned int fd, ext2_loff_t offset,
unsigned int origin)
{
if ((sizeof(off_t) < sizeof(ext2_loff_t)) &&
(offset >= ((ext2_loff_t) 1 << ((sizeof(off_t)*8) -1)))) {
- errno = -EINVAL;
+ errno = EINVAL;
return -1;
}
return lseek (fd, (off_t) offset, origin);
}
-#endif
+#endif /* linux */