summaryrefslogtreecommitdiff
path: root/libc/stdio/fseeko.c
diff options
context:
space:
mode:
Diffstat (limited to 'libc/stdio/fseeko.c')
-rw-r--r--libc/stdio/fseeko.c89
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
+}