blob: 71a9d910a20c7cc5904a1ce083f322e38a60a1d6 [file] [log] [blame]
Theodore Ts'of3db3561997-04-26 13:34:30 +00001/*
2 * llseek.c -- stub calling the llseek system call
3 *
Theodore Ts'o19c78dc1997-04-29 16:17:09 +00004 * Copyright (C) 1994, 1995, 1996 Theodore Ts'o.
5 *
6 * %Begin-Header%
7 * This file may be redistributed under the terms of the GNU Public
8 * License.
9 * %End-Header%
Theodore Ts'of3db3561997-04-26 13:34:30 +000010 */
11
12#include <sys/types.h>
13
14#include <errno.h>
15#include <unistd.h>
Theodore Ts'of3db3561997-04-26 13:34:30 +000016#include "et/com_err.h"
17#include "ext2fs/io.h"
18
19#ifdef __linux__
20
Theodore Ts'o50e1e101997-04-26 13:58:21 +000021#ifdef HAVE_LLSEEK
22#include <unistd.h>
23#include <syscall.h>
24
25#else /* HAVE_LLSEEK */
26
27#ifdef __alpha__
28
29#define llseek lseek
30
31#else /* !__alpha__ */
32
33#include <linux/unistd.h>
34
Theodore Ts'of3db3561997-04-26 13:34:30 +000035#ifndef __NR__llseek
36#define __NR__llseek 140
37#endif
38
39static int _llseek (unsigned int, unsigned long,
40 unsigned long, ext2_loff_t *, unsigned int);
41
42static _syscall5(int,_llseek,unsigned int,fd,unsigned long,offset_high,
43 unsigned long, offset_low,ext2_loff_t *,result,
44 unsigned int, origin)
45
Theodore Ts'o50e1e101997-04-26 13:58:21 +000046static ext2_loff_t llseek (unsigned int fd, ext2_loff_t offset,
47 unsigned int origin)
48{
49 ext2_loff_t result;
50 int retval;
51
52 retval = _llseek (fd, ((unsigned long long) offset) >> 32,
53 ((unsigned long long) offset) & 0xffffffff,
54 &result, origin);
55 return (retval == -1 ? (ext2_loff_t) retval : result);
56}
57
58#endif /* HAVE_LLSEEK */
59
60#endif /* __alpha__ */
61
Theodore Ts'o19c78dc1997-04-29 16:17:09 +000062ext2_loff_t ext2fs_llseek (unsigned int fd, ext2_loff_t offset,
Theodore Ts'of3db3561997-04-26 13:34:30 +000063 unsigned int origin)
64{
Theodore Ts'of3db3561997-04-26 13:34:30 +000065 ext2_loff_t result;
Theodore Ts'of3db3561997-04-26 13:34:30 +000066 static int do_compat = 0;
67
Theodore Ts'o50e1e101997-04-26 13:58:21 +000068 if ((sizeof(off_t) >= sizeof(ext2_loff_t)) ||
69 (offset < ((ext2_loff_t) 1 << ((sizeof(off_t)*8) -1))))
70 return lseek(fd, (off_t) offset, origin);
71
Theodore Ts'of3db3561997-04-26 13:34:30 +000072 if (do_compat) {
Theodore Ts'o50e1e101997-04-26 13:58:21 +000073 errno = EINVAL;
74 return -1;
Theodore Ts'of3db3561997-04-26 13:34:30 +000075 }
76
Theodore Ts'o50e1e101997-04-26 13:58:21 +000077 result = llseek (fd, offset, origin);
78 if (result == -1 && errno == ENOSYS) {
Theodore Ts'of3db3561997-04-26 13:34:30 +000079 /*
80 * Just in case this code runs on top of an old kernel
81 * which does not support the llseek system call
82 */
83 do_compat++;
Theodore Ts'o50e1e101997-04-26 13:58:21 +000084 errno = EINVAL;
Theodore Ts'of3db3561997-04-26 13:34:30 +000085 }
Theodore Ts'of3db3561997-04-26 13:34:30 +000086 return result;
87}
88
Theodore Ts'o50e1e101997-04-26 13:58:21 +000089#else /* !linux */
Theodore Ts'of3db3561997-04-26 13:34:30 +000090
Theodore Ts'o19c78dc1997-04-29 16:17:09 +000091ext2_loff_t ext2fs_llseek (unsigned int fd, ext2_loff_t offset,
Theodore Ts'of3db3561997-04-26 13:34:30 +000092 unsigned int origin)
93{
94 if ((sizeof(off_t) < sizeof(ext2_loff_t)) &&
95 (offset >= ((ext2_loff_t) 1 << ((sizeof(off_t)*8) -1)))) {
Theodore Ts'o50e1e101997-04-26 13:58:21 +000096 errno = EINVAL;
Theodore Ts'of3db3561997-04-26 13:34:30 +000097 return -1;
98 }
99 return lseek (fd, (off_t) offset, origin);
100}
101
Theodore Ts'o50e1e101997-04-26 13:58:21 +0000102#endif /* linux */
Theodore Ts'of3db3561997-04-26 13:34:30 +0000103
104