1f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o/* 2f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o * llseek.c -- stub calling the llseek system call 3f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o * 41c27cac2e848300a515cc994bc71ee48e2f3fa19Theodore Ts'o * Copyright (C) 1994, 1995, 1996, 1997 Theodore Ts'o. 519c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * 619c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * %Begin-Header% 7543547a52a20cb7e69d74921b2f691078fd55d83Theodore Ts'o * This file may be redistributed under the terms of the GNU Library 8543547a52a20cb7e69d74921b2f691078fd55d83Theodore Ts'o * General Public License, version 2. 919c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * %End-Header% 10f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o */ 11f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 12dc5f68cad3c8ee4c583acf9afbfdb7354cd3d6afTheodore Ts'o#define _LARGEFILE_SOURCE 13dc5f68cad3c8ee4c583acf9afbfdb7354cd3d6afTheodore Ts'o#define _LARGEFILE64_SOURCE 14dc5f68cad3c8ee4c583acf9afbfdb7354cd3d6afTheodore Ts'o 151d2ff46ae7533ffd038534b189f272d2a4122e4eTheodore Ts'o#if HAVE_SYS_TYPES_H 16f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o#include <sys/types.h> 171d2ff46ae7533ffd038534b189f272d2a4122e4eTheodore Ts'o#endif 18f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 19c555aebde40afdc0d15d674f2c81c0e05cfded3fTheodore Ts'o#if HAVE_ERRNO_H 20f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o#include <errno.h> 21c555aebde40afdc0d15d674f2c81c0e05cfded3fTheodore Ts'o#endif 224cbe8af4b0d0c72fb28bb500c1bd8a46b00fdde3Theodore Ts'o#if HAVE_UNISTD_H 23f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o#include <unistd.h> 244cbe8af4b0d0c72fb28bb500c1bd8a46b00fdde3Theodore Ts'o#endif 253cb6c5021d722e17b7105d1bc090880671f6fc6dTheodore Ts'o#ifdef __MSDOS__ 263cb6c5021d722e17b7105d1bc090880671f6fc6dTheodore Ts'o#include <io.h> 273cb6c5021d722e17b7105d1bc090880671f6fc6dTheodore Ts'o#endif 28f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o#include "et/com_err.h" 29d40259fd552d942903f2fd0b426c75a5c2516017Theodore Ts'o#include "ext2fs/ext2_io.h" 30f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 31f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o#ifdef __linux__ 32f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 33dc5f68cad3c8ee4c583acf9afbfdb7354cd3d6afTheodore Ts'o#if defined(HAVE_LSEEK64) && defined(HAVE_LSEEK64_PROTOTYPE) 34dc5f68cad3c8ee4c583acf9afbfdb7354cd3d6afTheodore Ts'o 35dc5f68cad3c8ee4c583acf9afbfdb7354cd3d6afTheodore Ts'o#define my_llseek lseek64 36dc5f68cad3c8ee4c583acf9afbfdb7354cd3d6afTheodore Ts'o 3748e6e81362f264aee4f3945c14928efaf71a06c9Theodore Ts'o#else 3848e6e81362f264aee4f3945c14928efaf71a06c9Theodore Ts'o#if defined(HAVE_LLSEEK) 3950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#include <syscall.h> 4050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o 41b0b9c4dece61ec03c655d50c2eade45ca427e069Theodore Ts'o#ifndef HAVE_LLSEEK_PROTOTYPE 42b0b9c4dece61ec03c655d50c2eade45ca427e069Theodore Ts'oextern long long llseek (int fd, long long offset, int origin); 431c27cac2e848300a515cc994bc71ee48e2f3fa19Theodore Ts'o#endif 441c27cac2e848300a515cc994bc71ee48e2f3fa19Theodore Ts'o 451c27cac2e848300a515cc994bc71ee48e2f3fa19Theodore Ts'o#define my_llseek llseek 461c27cac2e848300a515cc994bc71ee48e2f3fa19Theodore Ts'o 47dc5f68cad3c8ee4c583acf9afbfdb7354cd3d6afTheodore Ts'o#else /* ! HAVE_LLSEEK */ 4850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o 49c2dbc18a9425815b6e93eb8b95d05a1168fb6e23Theodore Ts'o#if SIZEOF_LONG == SIZEOF_LONG_LONG 5050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o 516c6a75dc1ed760f80417dd52a2a7b570fb738a0aJP Abgrall#define my_llseek lseek 5250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o 53c2dbc18a9425815b6e93eb8b95d05a1168fb6e23Theodore Ts'o#else /* SIZEOF_LONG != SIZEOF_LONG_LONG */ 5450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o 5550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#include <linux/unistd.h> 5650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o 57f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o#ifndef __NR__llseek 58f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o#define __NR__llseek 140 59f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o#endif 60f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 611c27cac2e848300a515cc994bc71ee48e2f3fa19Theodore Ts'o#ifndef __i386__ 62f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'ostatic int _llseek (unsigned int, unsigned long, 63f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o unsigned long, ext2_loff_t *, unsigned int); 64f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 65f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'ostatic _syscall5(int,_llseek,unsigned int,fd,unsigned long,offset_high, 66f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o unsigned long, offset_low,ext2_loff_t *,result, 67f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o unsigned int, origin) 681c27cac2e848300a515cc994bc71ee48e2f3fa19Theodore Ts'o#endif 69f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 701c27cac2e848300a515cc994bc71ee48e2f3fa19Theodore Ts'ostatic ext2_loff_t my_llseek (int fd, ext2_loff_t offset, int origin) 7150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o{ 7250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o ext2_loff_t result; 7350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o int retval; 7450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o 751c27cac2e848300a515cc994bc71ee48e2f3fa19Theodore Ts'o#ifndef __i386__ 761c27cac2e848300a515cc994bc71ee48e2f3fa19Theodore Ts'o retval = _llseek(fd, ((unsigned long long) offset) >> 32, 77efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o#else 781c27cac2e848300a515cc994bc71ee48e2f3fa19Theodore Ts'o retval = syscall(__NR__llseek, fd, (unsigned long long) (offset >> 32), 791c27cac2e848300a515cc994bc71ee48e2f3fa19Theodore Ts'o#endif 801c27cac2e848300a515cc994bc71ee48e2f3fa19Theodore Ts'o ((unsigned long long) offset) & 0xffffffff, 8150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o &result, origin); 8250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o return (retval == -1 ? (ext2_loff_t) retval : result); 8350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o} 8450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o 856c6a75dc1ed760f80417dd52a2a7b570fb738a0aJP Abgrall#endif /* SIZE_LONG == SIZEOF_LONG_LONG */ 8650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o 87dc5f68cad3c8ee4c583acf9afbfdb7354cd3d6afTheodore Ts'o#endif /* HAVE_LLSEEK */ 8848e6e81362f264aee4f3945c14928efaf71a06c9Theodore Ts'o#endif /* defined(HAVE_LSEEK64) && defined(HAVE_LSEEK64_PROTOTYPE) */ 8950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o 901c27cac2e848300a515cc994bc71ee48e2f3fa19Theodore Ts'oext2_loff_t ext2fs_llseek (int fd, ext2_loff_t offset, int origin) 91f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o{ 92e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#if SIZEOF_OFF_T >= SIZEOF_LONG_LONG 936c6a75dc1ed760f80417dd52a2a7b570fb738a0aJP Abgrall return my_llseek (fd, offset, origin); 94e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#else 95f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o ext2_loff_t result; 96f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o static int do_compat = 0; 97f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 98e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (do_compat) 99e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall goto fallback; 100efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 1011c27cac2e848300a515cc994bc71ee48e2f3fa19Theodore Ts'o result = my_llseek (fd, offset, origin); 10250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o if (result == -1 && errno == ENOSYS) { 103f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o /* 104f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o * Just in case this code runs on top of an old kernel 105f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o * which does not support the llseek system call 106f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o */ 107f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o do_compat++; 108e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall fallback: 109e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (offset < ((ext2_loff_t) 1 << ((sizeof(off_t)*8) -1))) 110e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall return lseek(fd, (off_t) offset, origin); 11150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o errno = EINVAL; 112e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall return -1; 113f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o } 114f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o return result; 115e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#endif 116f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o} 117f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 11850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#else /* !linux */ 119f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 12073f17cfc391221a5466e95c9dc1802564ce38973Theodore Ts'o#ifndef EINVAL 12173f17cfc391221a5466e95c9dc1802564ce38973Theodore Ts'o#define EINVAL EXT2_ET_INVALID_ARGUMENT 12273f17cfc391221a5466e95c9dc1802564ce38973Theodore Ts'o#endif 12373f17cfc391221a5466e95c9dc1802564ce38973Theodore Ts'o 124d163b0948731e6d84bd3efe75075a2d0a8009272Theodore Ts'oext2_loff_t ext2fs_llseek (int fd, ext2_loff_t offset, int origin) 125f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o{ 126488f3c2dad93af023e8db2394d9b2af6439048f0Theodore Ts'o#if defined(HAVE_LSEEK64) && defined(HAVE_LSEEK64_PROTOTYPE) 127488f3c2dad93af023e8db2394d9b2af6439048f0Theodore Ts'o return lseek64 (fd, offset, origin); 128488f3c2dad93af023e8db2394d9b2af6439048f0Theodore Ts'o#else 129f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o if ((sizeof(off_t) < sizeof(ext2_loff_t)) && 130f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o (offset >= ((ext2_loff_t) 1 << ((sizeof(off_t)*8) -1)))) { 13173f17cfc391221a5466e95c9dc1802564ce38973Theodore Ts'o errno = EINVAL; 132f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o return -1; 133f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o } 134f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o return lseek (fd, (off_t) offset, origin); 135488f3c2dad93af023e8db2394d9b2af6439048f0Theodore Ts'o#endif 136f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o} 137f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 13850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#endif /* linux */ 139f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 140f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 141