This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 2/3 v2] Implement _ftell_r() with _ftello_r()


2012-11-22  Sebastian Huber <sebastian.huber@embedded-brains.de>

	* libc/stdio/ftell.c: Use _ftello_r().
	* libc/stdio/ftello.c: Copy implementation from previous
	_ftell_r().

This patch assumes sizeof(long) <= sizeof(off_t).
---
 newlib/libc/stdio/ftell.c  |   55 +-----------------
 newlib/libc/stdio/ftello.c |  140 ++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 138 insertions(+), 57 deletions(-)

diff --git a/newlib/libc/stdio/ftell.c b/newlib/libc/stdio/ftell.c
index 54a656c..5af0709 100644
--- a/newlib/libc/stdio/ftell.c
+++ b/newlib/libc/stdio/ftell.c
@@ -105,64 +105,13 @@ _DEFUN(_ftell_r, (ptr, fp),
 {
   _fpos_t pos;
 
-  /* Ensure stdio is set up.  */
-
-  CHECK_INIT (ptr, fp);
-
-  _newlib_flockfile_start (fp);
-
-  if (fp->_seek == NULL)
-    {
-      ptr->_errno = ESPIPE;
-      _newlib_flockfile_exit (fp);
-      return -1L;
-    }
-
-  /* Find offset of underlying I/O object, then adjust for buffered
-     bytes.  Flush a write stream, since the offset may be altered if
-     the stream is appending.  Do not flush a read stream, since we
-     must not lose the ungetc buffer.  */
-  if (fp->_flags & __SWR)
-    _fflush_r (ptr, fp);
-  if (fp->_flags & __SOFF)
-    pos = fp->_offset;
-  else
-    {
-      pos = fp->_seek (ptr, fp->_cookie, (_fpos_t) 0, SEEK_CUR);
-      if (pos == -1L)
-        {
-          _newlib_flockfile_exit (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;
-    }
-
-  _newlib_flockfile_end (fp);
+  pos = _ftello_r (ptr, fp);
   if ((long)pos != pos)
     {
       pos = -1;
       ptr->_errno = EOVERFLOW;
     }
-  return pos;
+  return (long)pos;
 }
 
 #ifndef _REENT_ONLY
diff --git a/newlib/libc/stdio/ftello.c b/newlib/libc/stdio/ftello.c
index 216d884..3a1885e 100644
--- a/newlib/libc/stdio/ftello.c
+++ b/newlib/libc/stdio/ftello.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, Red Hat Inc.
+ * Copyright (c) 1990 The Regents of the University of California.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted
@@ -15,17 +15,149 @@
  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
+/*
+FUNCTION
+<<ftell>>, <<ftello>>---return position in a stream or file
+
+INDEX
+	ftell
+INDEX
+	ftello
+INDEX
+	_ftell_r
+INDEX
+	_ftello_r
+
+ANSI_SYNOPSIS
+	#include <stdio.h>
+	long ftell(FILE *<[fp]>);
+	off_t ftello(FILE *<[fp]>);
+	long _ftell_r(struct _reent *<[ptr]>, FILE *<[fp]>);
+	off_t _ftello_r(struct _reent *<[ptr]>, FILE *<[fp]>);
+
+TRAD_SYNOPSIS
+	#include <stdio.h>
+	long ftell(<[fp]>)
+	FILE *<[fp]>;
+
+	off_t ftello(<[fp]>)
+	FILE *<[fp]>;
+
+	long _ftell_r(<[ptr]>, <[fp]>)
+	struct _reent *<[ptr]>;
+	FILE *<[fp]>;
+
+	off_t _ftello_r(<[ptr]>, <[fp]>)
+	struct _reent *<[ptr]>;
+	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 <<ftell>>/<<ftello>> is the current position for a file
+identified by <[fp]>.  If you record this result, you can later
+use it with <<fseek>>/<<fseeko>> to return the file to this
+position.  The difference between <<ftell>> and <<ftello>> is that
+<<ftell>> returns <<long>> and <<ftello>> returns <<off_t>>.
+
+In the current implementation, <<ftell>>/<<ftello>> simply uses a character
+count to represent the file position; this is the same number that
+would be recorded by <<fgetpos>>.
+
+RETURNS
+<<ftell>>/<<ftello>> return the file position, if possible.  If they cannot do
+this, they return <<-1L>>.  Failure occurs on streams that do not support
+positioning; the global <<errno>> indicates this condition with the
+value <<ESPIPE>>.
+
+PORTABILITY
+<<ftell>> is required by the ANSI C standard, but the meaning of its
+result (when successful) is not specified beyond requiring that it be
+acceptable as an argument to <<fseek>>.  In particular, other
+conforming C implementations may return a different result from
+<<ftell>> than what <<fgetpos>> records.
+
+<<ftello>> is defined by the Single Unix specification.
+
+No supporting OS subroutines are required.
+*/
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "%W% (Berkeley) %G%";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * ftello: return current offset.
+ */
+
 #include <_ansi.h>
 #include <reent.h>
 #include <stdio.h>
+#include <errno.h>
+#include "local.h"
 
 _off_t
 _DEFUN(_ftello_r, (ptr, fp),
        struct _reent * ptr _AND
        register FILE * fp)
 {
-  /* for now we simply cast since off_t should be long */
-  return (_off_t)_ftell_r (ptr, fp);
+  _fpos_t pos;
+
+  /* Ensure stdio is set up.  */
+
+  CHECK_INIT (ptr, fp);
+
+  _newlib_flockfile_start (fp);
+
+  if (fp->_seek == NULL)
+    {
+      ptr->_errno = ESPIPE;
+      _newlib_flockfile_exit (fp);
+      return -1L;
+    }
+
+  /* Find offset of underlying I/O object, then adjust for buffered
+     bytes.  Flush a write stream, since the offset may be altered if
+     the stream is appending.  Do not flush a read stream, since we
+     must not lose the ungetc buffer.  */
+  if (fp->_flags & __SWR)
+    _fflush_r (ptr, fp);
+  if (fp->_flags & __SOFF)
+    pos = fp->_offset;
+  else
+    {
+      pos = fp->_seek (ptr, fp->_cookie, (_fpos_t) 0, SEEK_CUR);
+      if (pos == -1L)
+        {
+          _newlib_flockfile_exit (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;
+    }
+
+  _newlib_flockfile_end (fp);
+  return pos;
 }
 
 #ifndef _REENT_ONLY
@@ -34,7 +166,7 @@ _off_t
 _DEFUN(ftello, (fp),
        register FILE * fp)
 {
-  return (_off_t)_ftell_r (_REENT, fp);
+  return _ftello_r (_REENT, fp);
 }
 
 #endif /* !_REENT_ONLY */
-- 
1.7.7


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]