blob: 689b239edef27b6b28142616dac63889eb8b4679 [file] [log] [blame]
Theodore Ts'of3db3561997-04-26 13:34:30 +00001/*
2 * llseek.c -- stub calling the llseek system call
3 *
Theodore Ts'o1c27cac1997-08-14 17:20:42 +00004 * Copyright (C) 1994, 1995, 1996, 1997 Theodore Ts'o.
Theodore Ts'o19c78dc1997-04-29 16:17:09 +00005 *
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
Theodore Ts'o1d2ff461997-10-19 23:00:21 +000012#if HAVE_SYS_TYPES_H
Theodore Ts'of3db3561997-04-26 13:34:30 +000013#include <sys/types.h>
Theodore Ts'o1d2ff461997-10-19 23:00:21 +000014#endif
Theodore Ts'of3db3561997-04-26 13:34:30 +000015
16#include <errno.h>
Theodore Ts'o3cb6c501997-08-11 20:29:22 +000017#include <stdlib.h>
Theodore Ts'o4cbe8af1997-08-10 23:07:40 +000018#if HAVE_UNISTD_H
Theodore Ts'of3db3561997-04-26 13:34:30 +000019#include <unistd.h>
Theodore Ts'o4cbe8af1997-08-10 23:07:40 +000020#endif
Theodore Ts'o3cb6c501997-08-11 20:29:22 +000021#ifdef __MSDOS__
22#include <io.h>
23#endif
Theodore Ts'of3db3561997-04-26 13:34:30 +000024#include "et/com_err.h"
25#include "ext2fs/io.h"
26
27#ifdef __linux__
28
Theodore Ts'o50e1e101997-04-26 13:58:21 +000029#ifdef HAVE_LLSEEK
Theodore Ts'o4cbe8af1997-08-10 23:07:40 +000030#if HAVE_UNISTD_H
Theodore Ts'o50e1e101997-04-26 13:58:21 +000031#include <unistd.h>
Theodore Ts'o4cbe8af1997-08-10 23:07:40 +000032#endif
Theodore Ts'o50e1e101997-04-26 13:58:21 +000033#include <syscall.h>
34
Theodore Ts'o1c27cac1997-08-14 17:20:42 +000035#if (__GLIBC__ == 2)
Theodore Ts'obc75f2a1997-09-04 00:43:10 +000036ext2_loff_t llseek (int fd, ext2_loff_t offset, int origin);
Theodore Ts'o1c27cac1997-08-14 17:20:42 +000037#endif
38
39#define my_llseek llseek
40
Theodore Ts'o50e1e101997-04-26 13:58:21 +000041#else /* HAVE_LLSEEK */
42
43#ifdef __alpha__
44
45#define llseek lseek
46
47#else /* !__alpha__ */
48
49#include <linux/unistd.h>
50
Theodore Ts'of3db3561997-04-26 13:34:30 +000051#ifndef __NR__llseek
52#define __NR__llseek 140
53#endif
54
Theodore Ts'o1c27cac1997-08-14 17:20:42 +000055#ifndef __i386__
Theodore Ts'of3db3561997-04-26 13:34:30 +000056static int _llseek (unsigned int, unsigned long,
57 unsigned long, ext2_loff_t *, unsigned int);
58
59static _syscall5(int,_llseek,unsigned int,fd,unsigned long,offset_high,
60 unsigned long, offset_low,ext2_loff_t *,result,
61 unsigned int, origin)
Theodore Ts'o1c27cac1997-08-14 17:20:42 +000062#endif
Theodore Ts'of3db3561997-04-26 13:34:30 +000063
Theodore Ts'o1c27cac1997-08-14 17:20:42 +000064static ext2_loff_t my_llseek (int fd, ext2_loff_t offset, int origin)
Theodore Ts'o50e1e101997-04-26 13:58:21 +000065{
66 ext2_loff_t result;
67 int retval;
68
Theodore Ts'o1c27cac1997-08-14 17:20:42 +000069#ifndef __i386__
70 retval = _llseek(fd, ((unsigned long long) offset) >> 32,
71#else
72 retval = syscall(__NR__llseek, fd, (unsigned long long) (offset >> 32),
73#endif
74 ((unsigned long long) offset) & 0xffffffff,
Theodore Ts'o50e1e101997-04-26 13:58:21 +000075 &result, origin);
76 return (retval == -1 ? (ext2_loff_t) retval : result);
77}
78
79#endif /* HAVE_LLSEEK */
80
81#endif /* __alpha__ */
82
Theodore Ts'o1c27cac1997-08-14 17:20:42 +000083ext2_loff_t ext2fs_llseek (int fd, ext2_loff_t offset, int origin)
Theodore Ts'of3db3561997-04-26 13:34:30 +000084{
Theodore Ts'of3db3561997-04-26 13:34:30 +000085 ext2_loff_t result;
Theodore Ts'of3db3561997-04-26 13:34:30 +000086 static int do_compat = 0;
87
Theodore Ts'o50e1e101997-04-26 13:58:21 +000088 if ((sizeof(off_t) >= sizeof(ext2_loff_t)) ||
89 (offset < ((ext2_loff_t) 1 << ((sizeof(off_t)*8) -1))))
90 return lseek(fd, (off_t) offset, origin);
91
Theodore Ts'of3db3561997-04-26 13:34:30 +000092 if (do_compat) {
Theodore Ts'o50e1e101997-04-26 13:58:21 +000093 errno = EINVAL;
94 return -1;
Theodore Ts'of3db3561997-04-26 13:34:30 +000095 }
96
Theodore Ts'o1c27cac1997-08-14 17:20:42 +000097 result = my_llseek (fd, offset, origin);
Theodore Ts'o50e1e101997-04-26 13:58:21 +000098 if (result == -1 && errno == ENOSYS) {
Theodore Ts'of3db3561997-04-26 13:34:30 +000099 /*
100 * Just in case this code runs on top of an old kernel
101 * which does not support the llseek system call
102 */
103 do_compat++;
Theodore Ts'o50e1e101997-04-26 13:58:21 +0000104 errno = EINVAL;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000105 }
Theodore Ts'of3db3561997-04-26 13:34:30 +0000106 return result;
107}
108
Theodore Ts'o50e1e101997-04-26 13:58:21 +0000109#else /* !linux */
Theodore Ts'of3db3561997-04-26 13:34:30 +0000110
Theodore Ts'od163b091997-10-03 17:42:28 +0000111ext2_loff_t ext2fs_llseek (int fd, ext2_loff_t offset, int origin)
Theodore Ts'of3db3561997-04-26 13:34:30 +0000112{
113 if ((sizeof(off_t) < sizeof(ext2_loff_t)) &&
114 (offset >= ((ext2_loff_t) 1 << ((sizeof(off_t)*8) -1)))) {
Theodore Ts'o50e1e101997-04-26 13:58:21 +0000115 errno = EINVAL;
Theodore Ts'of3db3561997-04-26 13:34:30 +0000116 return -1;
117 }
118 return lseek (fd, (off_t) offset, origin);
119}
120
Theodore Ts'o50e1e101997-04-26 13:58:21 +0000121#endif /* linux */
Theodore Ts'of3db3561997-04-26 13:34:30 +0000122
123