summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2014-03-31 09:47:28 -0600
committerGregory Nutt <gnutt@nuttx.org>2014-03-31 09:47:28 -0600
commitb4b12a6653bf66340b0b62357d07a2655bbb0c2e (patch)
tree4acab6a78d56c80f1a4c925110da46625eacdc20
parentd32187047743c8cd8ecf76ba06cd71ca8ff9e04d (diff)
downloadnuttx-b4b12a6653bf66340b0b62357d07a2655bbb0c2e.tar.gz
nuttx-b4b12a6653bf66340b0b62357d07a2655bbb0c2e.tar.bz2
nuttx-b4b12a6653bf66340b0b62357d07a2655bbb0c2e.zip
Fix ftell() bug: It was not accounting for data buffered in memory. From Macs N
-rw-r--r--nuttx/ChangeLog3
-rw-r--r--nuttx/libc/stdio/lib_ftell.c41
2 files changed, 41 insertions, 3 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog
index 9a439dcb5..50e4f7be5 100644
--- a/nuttx/ChangeLog
+++ b/nuttx/ChangeLog
@@ -7092,3 +7092,6 @@
* libc/stdio/lib_ferror.c, lib_fread.c, lib_libfflush.c,
lib_libfread.c, and lib_libfwrite.c: Finish incomplete support
for ferror(). From Macs N (2014-3-14).
+ * libc/stdio/lib_ftell.c: Fix a logic error in ftell(). It was
+ simply using the file offset and did not take into account data
+ buffered in memory. From Macs N (2013-3-31).
diff --git a/nuttx/libc/stdio/lib_ftell.c b/nuttx/libc/stdio/lib_ftell.c
index c528c4702..85390c918 100644
--- a/nuttx/libc/stdio/lib_ftell.c
+++ b/nuttx/libc/stdio/lib_ftell.c
@@ -52,7 +52,7 @@
#include "lib_internal.h"
/****************************************************************************
- * Definitions
+ * Pre-processor Definitions
****************************************************************************/
/****************************************************************************
@@ -84,6 +84,41 @@
****************************************************************************/
/****************************************************************************
+ * Name: lib_getrdoffset
+ *
+ * Description:
+ * It is insufficient to simply use the file offset; we must also account
+ * for the data offset in the any buffered data. This function calculates
+ * that offset.
+ *
+ * Returned Value:
+ * The file position offset due to buffered data.
+ *
+ ****************************************************************************/
+
+#if CONFIG_STDIO_BUFFER_SIZE > 0
+static off_t lib_getrdoffset(FAR FILE *stream)
+{
+ off_t rdoffset = 0;
+ lib_take_semaphore(stream);
+
+ if (stream->fs_bufread != stream->fs_bufstart)
+ {
+#if CONFIG_NUNGET_CHARS > 0
+ rdoffset = stream->fs_bufread - stream->fs_bufpos + stream->fs_nungotten;
+#else
+ rdoffset = stream->fs_bufread - stream->fs_bufpos;
+#endif
+ }
+
+ lib_give_semaphore(stream);
+ return rdoffset;
+}
+#else
+# define lib_getrdoffset(stream) (0)
+#endif
+
+/****************************************************************************
* Public Functions
****************************************************************************/
@@ -95,7 +130,7 @@
* stream pointed to by stream.
*
* Returned Value:
- * Zero on succes; -1 on failure with errno set appropriately.
+ * Zero on success; -1 on failure with errno set appropriately.
*
****************************************************************************/
@@ -118,7 +153,7 @@ long ftell(FAR FILE *stream)
position = lseek(stream->fs_fd, 0, SEEK_CUR);
if (position != (off_t)-1)
{
- return (long)position;
+ return (long)(position - lib_getrdoffset(stream));
}
else
{