blob: 00fe3cdca058762a8c92a66d225806a2ebe6c3c4 [file] [log] [blame]
Theodore Ts'of3db3561997-04-26 13:34:30 +00001/*
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>
12#include <linux/unistd.h>
13#include "et/com_err.h"
14#include "ext2fs/io.h"
15
16#ifdef __linux__
17
18#ifndef __NR__llseek
19#define __NR__llseek 140
20#endif
21
22static int _llseek (unsigned int, unsigned long,
23 unsigned long, ext2_loff_t *, unsigned int);
24
25static _syscall5(int,_llseek,unsigned int,fd,unsigned long,offset_high,
26 unsigned long, offset_low,ext2_loff_t *,result,
27 unsigned int, origin)
28
29ext2_loff_t ext2_llseek (unsigned int fd, ext2_loff_t offset,
30 unsigned int origin)
31{
32 unsigned long offset_high;
33 unsigned long offset_low;
34 ext2_loff_t result;
35 int retval;
36 static int do_compat = 0;
37
38 if (do_compat) {
39 compat_lseek:
40 if ((sizeof(off_t) < sizeof(ext2_loff_t)) &&
41 (offset >= ((ext2_loff_t) 1 << ((sizeof(off_t)*8) -1)))) {
42 errno = -EINVAL;
43 return -1;
44 }
45 return lseek (fd, (off_t) offset, origin);
46 }
47
48 offset_high = ((unsigned long long) offset) >> 32;
49 offset_low = ((unsigned long long) offset) & 0xffffffff;
50 retval = _llseek (fd, offset_high, offset_low, &result, origin);
51 if (retval == -1 && errno == ENOSYS) {
52 /*
53 * Just in case this code runs on top of an old kernel
54 * which does not support the llseek system call
55 */
56 do_compat++;
57 goto compat_lseek;
58 }
59 if (retval == -1)
60 result = -1;
61 return result;
62}
63
64#else
65
66ext2_loff_t ext2_llseek (unsigned int fd, ext2_loff_t offset,
67 unsigned int origin)
68{
69 if ((sizeof(off_t) < sizeof(ext2_loff_t)) &&
70 (offset >= ((ext2_loff_t) 1 << ((sizeof(off_t)*8) -1)))) {
71 errno = -EINVAL;
72 return -1;
73 }
74 return lseek (fd, (off_t) offset, origin);
75}
76
77#endif
78
79