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 12f1644c324bd6bc0ed8f48275d64ccde4ce13a044Theodore Ts'o#ifndef _LARGEFILE_SOURCE 13dc5f68cad3c8ee4c583acf9afbfdb7354cd3d6afTheodore Ts'o#define _LARGEFILE_SOURCE 14f1644c324bd6bc0ed8f48275d64ccde4ce13a044Theodore Ts'o#endif 15f1644c324bd6bc0ed8f48275d64ccde4ce13a044Theodore Ts'o#ifndef _LARGEFILE64_SOURCE 16dc5f68cad3c8ee4c583acf9afbfdb7354cd3d6afTheodore Ts'o#define _LARGEFILE64_SOURCE 17f1644c324bd6bc0ed8f48275d64ccde4ce13a044Theodore Ts'o#endif 18dc5f68cad3c8ee4c583acf9afbfdb7354cd3d6afTheodore Ts'o 19d1154eb460efe588eaed3d439c1caaca149fa362Theodore Ts'o#include "config.h" 201d2ff46ae7533ffd038534b189f272d2a4122e4eTheodore Ts'o#if HAVE_SYS_TYPES_H 21f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o#include <sys/types.h> 221d2ff46ae7533ffd038534b189f272d2a4122e4eTheodore Ts'o#endif 23f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 24c555aebde40afdc0d15d674f2c81c0e05cfded3fTheodore Ts'o#if HAVE_ERRNO_H 25f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o#include <errno.h> 26c555aebde40afdc0d15d674f2c81c0e05cfded3fTheodore Ts'o#endif 274cbe8af4b0d0c72fb28bb500c1bd8a46b00fdde3Theodore Ts'o#if HAVE_UNISTD_H 28f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o#include <unistd.h> 294cbe8af4b0d0c72fb28bb500c1bd8a46b00fdde3Theodore Ts'o#endif 303cb6c5021d722e17b7105d1bc090880671f6fc6dTheodore Ts'o#ifdef __MSDOS__ 313cb6c5021d722e17b7105d1bc090880671f6fc6dTheodore Ts'o#include <io.h> 323cb6c5021d722e17b7105d1bc090880671f6fc6dTheodore Ts'o#endif 33f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o#include "et/com_err.h" 34d40259fd552d942903f2fd0b426c75a5c2516017Theodore Ts'o#include "ext2fs/ext2_io.h" 35f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 36f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o#ifdef __linux__ 37f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 38dc5f68cad3c8ee4c583acf9afbfdb7354cd3d6afTheodore Ts'o#if defined(HAVE_LSEEK64) && defined(HAVE_LSEEK64_PROTOTYPE) 39dc5f68cad3c8ee4c583acf9afbfdb7354cd3d6afTheodore Ts'o 40dc5f68cad3c8ee4c583acf9afbfdb7354cd3d6afTheodore Ts'o#define my_llseek lseek64 41dc5f68cad3c8ee4c583acf9afbfdb7354cd3d6afTheodore Ts'o 4248e6e81362f264aee4f3945c14928efaf71a06c9Theodore Ts'o#else 4348e6e81362f264aee4f3945c14928efaf71a06c9Theodore Ts'o#if defined(HAVE_LLSEEK) 44599915f080dc0f62a3e800c5bc8fe31ae8b45707Theodore Ts'o#include <sys/syscall.h> 4550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o 46b0b9c4dece61ec03c655d50c2eade45ca427e069Theodore Ts'o#ifndef HAVE_LLSEEK_PROTOTYPE 47b0b9c4dece61ec03c655d50c2eade45ca427e069Theodore Ts'oextern long long llseek (int fd, long long offset, int origin); 481c27cac2e848300a515cc994bc71ee48e2f3fa19Theodore Ts'o#endif 491c27cac2e848300a515cc994bc71ee48e2f3fa19Theodore Ts'o 501c27cac2e848300a515cc994bc71ee48e2f3fa19Theodore Ts'o#define my_llseek llseek 511c27cac2e848300a515cc994bc71ee48e2f3fa19Theodore Ts'o 52dc5f68cad3c8ee4c583acf9afbfdb7354cd3d6afTheodore Ts'o#else /* ! HAVE_LLSEEK */ 5350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o 54c2dbc18a9425815b6e93eb8b95d05a1168fb6e23Theodore Ts'o#if SIZEOF_LONG == SIZEOF_LONG_LONG 5550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o 565efe492d19ae6fc876b504a53621169f63f1ce96JP Abgrall#define my_llseek lseek 5750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o 58c2dbc18a9425815b6e93eb8b95d05a1168fb6e23Theodore Ts'o#else /* SIZEOF_LONG != SIZEOF_LONG_LONG */ 5950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o 6050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#include <linux/unistd.h> 6150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o 62f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o#ifndef __NR__llseek 63f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o#define __NR__llseek 140 64f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o#endif 65f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 661c27cac2e848300a515cc994bc71ee48e2f3fa19Theodore Ts'o#ifndef __i386__ 67f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'ostatic int _llseek (unsigned int, unsigned long, 68f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o unsigned long, ext2_loff_t *, unsigned int); 69f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 70f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'ostatic _syscall5(int,_llseek,unsigned int,fd,unsigned long,offset_high, 71f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o unsigned long, offset_low,ext2_loff_t *,result, 72f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o unsigned int, origin) 731c27cac2e848300a515cc994bc71ee48e2f3fa19Theodore Ts'o#endif 74f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 751c27cac2e848300a515cc994bc71ee48e2f3fa19Theodore Ts'ostatic ext2_loff_t my_llseek (int fd, ext2_loff_t offset, int origin) 7650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o{ 7750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o ext2_loff_t result; 7850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o int retval; 7950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o 801c27cac2e848300a515cc994bc71ee48e2f3fa19Theodore Ts'o#ifndef __i386__ 811c27cac2e848300a515cc994bc71ee48e2f3fa19Theodore Ts'o retval = _llseek(fd, ((unsigned long long) offset) >> 32, 82efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o#else 831c27cac2e848300a515cc994bc71ee48e2f3fa19Theodore Ts'o retval = syscall(__NR__llseek, fd, (unsigned long long) (offset >> 32), 841c27cac2e848300a515cc994bc71ee48e2f3fa19Theodore Ts'o#endif 851c27cac2e848300a515cc994bc71ee48e2f3fa19Theodore Ts'o ((unsigned long long) offset) & 0xffffffff, 8650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o &result, origin); 8750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o return (retval == -1 ? (ext2_loff_t) retval : result); 8850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o} 8950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o 905efe492d19ae6fc876b504a53621169f63f1ce96JP Abgrall#endif /* SIZE_LONG == SIZEOF_LONG_LONG */ 9150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o 92dc5f68cad3c8ee4c583acf9afbfdb7354cd3d6afTheodore Ts'o#endif /* HAVE_LLSEEK */ 9348e6e81362f264aee4f3945c14928efaf71a06c9Theodore Ts'o#endif /* defined(HAVE_LSEEK64) && defined(HAVE_LSEEK64_PROTOTYPE) */ 9450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o 951c27cac2e848300a515cc994bc71ee48e2f3fa19Theodore Ts'oext2_loff_t ext2fs_llseek (int fd, ext2_loff_t offset, int origin) 96f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o{ 97274d46e1d35af423d0292d63c4d0ad7a03be82baPhillip Susi#if SIZEOF_OFF_T >= SIZEOF_LONG_LONG 985efe492d19ae6fc876b504a53621169f63f1ce96JP Abgrall return my_llseek (fd, offset, origin); 99274d46e1d35af423d0292d63c4d0ad7a03be82baPhillip Susi#else 100f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o ext2_loff_t result; 101f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o static int do_compat = 0; 102f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 103274d46e1d35af423d0292d63c4d0ad7a03be82baPhillip Susi if (do_compat) 104274d46e1d35af423d0292d63c4d0ad7a03be82baPhillip Susi goto fallback; 105efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 1061c27cac2e848300a515cc994bc71ee48e2f3fa19Theodore Ts'o result = my_llseek (fd, offset, origin); 10750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o if (result == -1 && errno == ENOSYS) { 108f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o /* 109f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o * Just in case this code runs on top of an old kernel 110f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o * which does not support the llseek system call 111f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o */ 112f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o do_compat++; 113274d46e1d35af423d0292d63c4d0ad7a03be82baPhillip Susi fallback: 114274d46e1d35af423d0292d63c4d0ad7a03be82baPhillip Susi if (offset < ((ext2_loff_t) 1 << ((sizeof(off_t)*8) -1))) 115274d46e1d35af423d0292d63c4d0ad7a03be82baPhillip Susi return lseek(fd, (off_t) offset, origin); 11650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o errno = EINVAL; 117274d46e1d35af423d0292d63c4d0ad7a03be82baPhillip Susi return -1; 118f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o } 119f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o return result; 120274d46e1d35af423d0292d63c4d0ad7a03be82baPhillip Susi#endif 121f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o} 122f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 12350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#else /* !linux */ 124f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 12573f17cfc391221a5466e95c9dc1802564ce38973Theodore Ts'o#ifndef EINVAL 12673f17cfc391221a5466e95c9dc1802564ce38973Theodore Ts'o#define EINVAL EXT2_ET_INVALID_ARGUMENT 12773f17cfc391221a5466e95c9dc1802564ce38973Theodore Ts'o#endif 12873f17cfc391221a5466e95c9dc1802564ce38973Theodore Ts'o 129d163b0948731e6d84bd3efe75075a2d0a8009272Theodore Ts'oext2_loff_t ext2fs_llseek (int fd, ext2_loff_t offset, int origin) 130f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o{ 131488f3c2dad93af023e8db2394d9b2af6439048f0Theodore Ts'o#if defined(HAVE_LSEEK64) && defined(HAVE_LSEEK64_PROTOTYPE) 132488f3c2dad93af023e8db2394d9b2af6439048f0Theodore Ts'o return lseek64 (fd, offset, origin); 133488f3c2dad93af023e8db2394d9b2af6439048f0Theodore Ts'o#else 134f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o if ((sizeof(off_t) < sizeof(ext2_loff_t)) && 135f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o (offset >= ((ext2_loff_t) 1 << ((sizeof(off_t)*8) -1)))) { 13673f17cfc391221a5466e95c9dc1802564ce38973Theodore Ts'o errno = EINVAL; 137f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o return -1; 138f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o } 139f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o return lseek (fd, (off_t) offset, origin); 140488f3c2dad93af023e8db2394d9b2af6439048f0Theodore Ts'o#endif 141f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o} 142f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 14350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#endif /* linux */ 144f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 145f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 146