]> git.ipfire.org Git - thirdparty/e2fsprogs.git/blame - lib/ext2fs/llseek.c
Merge remote-tracking branch 'josch/libarchive' into josch-libarchive
[thirdparty/e2fsprogs.git] / lib / ext2fs / llseek.c
CommitLineData
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 40static 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 62ext2_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 92ext2_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