[Libsysio-commit] HEAD: libsysio/src lseek.c
Brought to you by:
lward
From: Lee W. <lw...@us...> - 2005-08-02 21:57:24
|
Update of /cvsroot/libsysio/libsysio/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv468/src Modified Files: lseek.c Log Message: Changes to support better detection of overflow in 32/64 mixed compiles. Index: lseek.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/src/lseek.c,v retrieving revision 1.25 retrieving revision 1.26 diff -u -w -b -B -p -r1.25 -r1.26 --- lseek.c 14 Oct 2004 14:59:29 -0000 1.25 +++ lseek.c 2 Aug 2005 21:57:09 -0000 1.26 @@ -46,6 +46,7 @@ #include <assert.h> #include <sys/types.h> #include <sys/stat.h> +#include <fcntl.h> #include <sys/queue.h> #include "sysio.h" @@ -54,17 +55,31 @@ #include "sysio-symbols.h" +/* + * Test whether large file support on this file. + */ +#ifdef O_LARGEFILE +#define _SEEK_MAX_TEST(fil) \ + ((fil)->f_flags & O_LARGEFILE) +#else +#define _SEEK_MAX_TEST(fil) \ + (1) +#endif +/* + * Return max seek value for this file. + */ +#define _SEEK_MAX(fil) \ + (_SEEK_MAX_TEST(fil) ? _SYSIO_OFF_T_MAX : LONG_MAX) + static _SYSIO_OFF_T -_sysio_lseek(int fd, _SYSIO_OFF_T offset, int whence) +_sysio_lseek(struct file *fil, + _SYSIO_OFF_T offset, + int whence, + _SYSIO_OFF_T max) { - struct file *fil; _SYSIO_OFF_T off, pos; struct intnl_stat stbuf; - fil = _sysio_fd_find(fd); - if (!fil) - return -EBADF; - off = -1; switch (whence) { @@ -99,14 +114,8 @@ _sysio_lseek(int fd, _SYSIO_OFF_T offset pos = off + offset; if ((offset < 0 && -offset > off) || (offset > 0 && pos <= off)) return -EINVAL; - -#ifdef O_LARGEFILE - if (pos >= ((fil->f_flags & O_LARGEFILE) ? _SYSIO_OFF_T_MAX : LONG_MAX)) - return -EOVERFLOW; -#else - if (pos >= _SYSIO_OFF_T_MAX) + if (pos >= max) return -EOVERFLOW; -#endif pos = (fil->f_ino->i_ops.inop_pos)(fil->f_ino, pos); if (pos < 0) return pos; @@ -120,17 +129,18 @@ _sysio_lseek(int fd, _SYSIO_OFF_T offset extern off64_t SYSIO_INTERFACE_NAME(lseek64)(int fd, off64_t offset, int whence) { - _SYSIO_OFF_T off; - off_t rtn; + struct file *fil; + off64_t off; SYSIO_INTERFACE_DISPLAY_BLOCK; SYSIO_INTERFACE_ENTER; - off = _sysio_lseek(fd, offset, whence); - if (off < 0) - SYSIO_INTERFACE_RETURN((off_t )-1, (int )off); - rtn = (off64_t )off; - assert(rtn == off); - SYSIO_INTERFACE_RETURN(rtn, 0); + fil = _sysio_fd_find(fd); + if (!fil) + SYSIO_INTERFACE_RETURN((off64_t )-1, -EBADF); + off = _sysio_lseek(fil, offset, whence, _SEEK_MAX(fil)); + SYSIO_INTERFACE_RETURN(off < 0 ? (off64_t )-1 : off, + off < 0 ? (int )off : 0); + } #ifdef __GLIBC__ #undef __lseek64 @@ -149,12 +159,16 @@ sysio_sym_weak_alias(SYSIO_INTERFACE_NAM extern off_t SYSIO_INTERFACE_NAME(lseek)(int fd, off_t offset, int whence) { + struct file *fil; _SYSIO_OFF_T off; off_t rtn; SYSIO_INTERFACE_DISPLAY_BLOCK; SYSIO_INTERFACE_ENTER; - off = _sysio_lseek(fd, offset, whence); + fil = _sysio_fd_find(fd); + if (!fil) + SYSIO_INTERFACE_RETURN((off_t )-1, -EBADF); + off = _sysio_lseek(fil, offset, whence, LONG_MAX); if (off < 0) SYSIO_INTERFACE_RETURN((off_t )-1, (int )off); rtn = (off_t )off; @@ -177,6 +191,7 @@ SYSIO_INTERFACE_NAME(llseek)(unsigned in loff_t *result __IS_UNUSED, unsigned int whence __IS_UNUSED) { + struct file *fil; loff_t off; SYSIO_INTERFACE_DISPLAY_BLOCK; @@ -184,6 +199,9 @@ SYSIO_INTERFACE_NAME(llseek)(unsigned in * This is just plain goofy. */ SYSIO_INTERFACE_ENTER; + fil = _sysio_fd_find(fd); + if (!fil) + SYSIO_INTERFACE_RETURN(-1, -EBADF); #if !_LARGEFILE64_SOURCE if (offset_high) { /* @@ -197,7 +215,7 @@ SYSIO_INTERFACE_NAME(llseek)(unsigned in off <<= 32; off |= offset_low; #endif - off = _sysio_lseek(fd, off, whence); + off = _sysio_lseek(fil, off, whence, _SEEK_MAX(fil)); if (off < 0) SYSIO_INTERFACE_RETURN((off_t )-1, (int )off); *result = off; |