diff options
Diffstat (limited to 'disk-utils/llseek.c')
-rw-r--r-- | disk-utils/llseek.c | 83 |
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 */ |