diff options
Diffstat (limited to 'libc/stdio/fseeko.c')
-rw-r--r-- | libc/stdio/fseeko.c | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/libc/stdio/fseeko.c b/libc/stdio/fseeko.c new file mode 100644 index 000000000..fed425730 --- /dev/null +++ b/libc/stdio/fseeko.c @@ -0,0 +1,89 @@ +/* Copyright (C) 2004 Manuel Novoa III <mjn3@codepoet.org> + * + * GNU Library General Public License (LGPL) version 2 or later. + * + * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details. + */ + +#include "_stdio.h" + +#if SEEK_SET != 0 || SEEK_CUR != 1 || SEEK_END != 2 +# error Assumption violated -- values of SEEK_SET, SEEK_CUR, SEEK_END +#endif + +#ifdef __DO_LARGEFILE +# ifndef __UCLIBC_HAS_LFS__ +# error large file support is not enabled! +# endif + +# define FSEEK __fseeko64 +# define OFFSET_TYPE __off64_t + +weak_alias(__fseeko64,fseeko64); + +#else + +# define FSEEK fseek +# define OFFSET_TYPE long int + +weak_alias(fseek,fseeko); + +#endif + + +int FSEEK(register FILE *stream, OFFSET_TYPE offset, int whence) +{ +#if defined(__UCLIBC_HAS_LFS__) && !defined(__DO_LARGEFILE) + + return __fseeko64(stream, offset, whence); + +#else + + __offmax_t pos = offset; + int retval = -1; + __STDIO_AUTO_THREADLOCK_VAR; + + if (((unsigned int) whence) > 2) { + __set_errno(EINVAL); + } else { + __STDIO_AUTO_THREADLOCK(stream); + + __STDIO_STREAM_VALIDATE(stream); + + if ((!__STDIO_STREAM_IS_WRITING(stream) + || !__STDIO_COMMIT_WRITE_BUFFER(stream)) + && ((whence != SEEK_CUR) + || (__stdio_adjust_position(stream, &pos) >= 0)) + && (__SEEK(stream, &pos, whence) >= 0) + ) { + + /* Clear reading/writing modes, EOF, and ungots. */ + stream->__modeflags &= + ~(__MASK_READING|__FLAG_WRITING|__FLAG_EOF); + + /* Make sure all pointers are reset. */ + __STDIO_STREAM_INIT_BUFREAD_BUFPOS(stream); + __STDIO_STREAM_DISABLE_GETC(stream); + __STDIO_STREAM_DISABLE_PUTC(stream); + + /* We reinitialize the mbstate object. Doing so is + * implementation defined behavior. */ +#ifdef __STDIO_MBSTATE + __INIT_MBSTATE(&(stream->__state)); +#endif +#ifdef __UCLIBC_HAS_WCHAR__ + stream->__ungot_width[0] = 0; +#endif + + retval = 0; + } + + __STDIO_STREAM_VALIDATE(stream); + + __STDIO_AUTO_THREADUNLOCK(stream); + } + + return retval; + +#endif +} |