summaryrefslogtreecommitdiffstats
path: root/newlib/libc/stdio64/ftello64.c
diff options
context:
space:
mode:
Diffstat (limited to 'newlib/libc/stdio64/ftello64.c')
-rw-r--r--newlib/libc/stdio64/ftello64.c138
1 files changed, 138 insertions, 0 deletions
diff --git a/newlib/libc/stdio64/ftello64.c b/newlib/libc/stdio64/ftello64.c
new file mode 100644
index 000000000..c6b888cf4
--- /dev/null
+++ b/newlib/libc/stdio64/ftello64.c
@@ -0,0 +1,138 @@
+#ifdef __LARGE64_FILES
+
+/*
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley. The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/*
+FUNCTION
+<<ftello64>>---return position in a stream or file
+
+INDEX
+ ftello64
+
+ANSI_SYNOPSIS
+ #include <stdio.h>
+ _off64_t ftello64(FILE *<[fp]>);
+
+TRAD_SYNOPSIS
+ #include <stdio.h>
+ _off64_t ftello64(<[fp]>)
+ FILE *<[fp]>;
+
+DESCRIPTION
+Objects of type <<FILE>> can have a ``position'' that records how much
+of the file your program has already read. Many of the <<stdio>> functions
+depend on this position, and many change it as a side effect.
+
+The result of <<ftello64>> is the current position for a large file
+identified by <[fp]>. If you record this result, you can later
+use it with <<fseeko64>> to return the file to this
+position. The difference between <<ftello>> and <<ftello64>> is that
+<<ftello>> returns <<off_t>> and <<ftello64>> is designed to work
+for large files (>2GB) and returns <<_off64_t>>.
+
+In the current implementation, <<ftello64>> simply uses a character
+count to represent the file position; this is the same number that
+would be recorded by <<fgetpos64>>.
+
+The function exists only if the __LARGE64_FILES flag is defined.
+An error occurs if the <[fp]> was not opened via <<fopen64>>.
+
+RETURNS
+<<ftello64>> returns the file position, if possible. If it cannot do
+this, it returns <<-1>>. Failure occurs on streams that do not support
+positioning or not opened via <<fopen64>>; the global <<errno>> indicates
+this condition with the value <<ESPIPE>>.
+
+PORTABILITY
+<<ftello64>> is a glibc extension.
+
+No supporting OS subroutines are required.
+*/
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "%W% (Berkeley) %G%";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * ftello64: return current offset.
+ */
+
+#include <stdio.h>
+#include <errno.h>
+
+#include "local64.h"
+
+_off64_t
+_DEFUN (ftello64, (fp),
+ register FILE * fp)
+{
+ _fpos64_t pos;
+
+ _flockfile(fp);
+
+ /* Ensure stdio is set up. */
+
+ CHECK_INIT (fp);
+
+ if (fp->_seek64 == NULL)
+ {
+ fp->_data->_errno = ESPIPE;
+ _funlockfile(fp);
+ return -1L;
+ }
+
+ /* Find offset of underlying I/O object, then
+ adjust for buffered bytes. */
+ fflush(fp); /* may adjust seek offset on append stream */
+ if (fp->_flags & __SOFF)
+ pos = fp->_offset;
+ else
+ {
+ pos = (*fp->_seek64) (fp->_cookie, (_fpos64_t) 0, SEEK_CUR);
+ if (pos == -1L)
+ {
+ _funlockfile(fp);
+ return pos;
+ }
+ }
+ if (fp->_flags & __SRD)
+ {
+ /*
+ * Reading. Any unread characters (including
+ * those from ungetc) cause the position to be
+ * smaller than that in the underlying object.
+ */
+ pos -= fp->_r;
+ if (HASUB (fp))
+ pos -= fp->_ur;
+ }
+ else if (fp->_flags & __SWR && fp->_p != NULL)
+ {
+ /*
+ * Writing. Any buffered characters cause the
+ * position to be greater than that in the
+ * underlying object.
+ */
+ pos += fp->_p - fp->_bf._base;
+ }
+
+ _funlockfile(fp);
+ return pos;
+}
+
+#endif /* __LARGE64_FILES */