about summary refs log tree commit diff
path: root/libio/fileops.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@gmail.com>2011-05-13 21:08:45 -0400
committerUlrich Drepper <drepper@gmail.com>2011-05-13 21:08:45 -0400
commitfcabc0f8b185f9e0a9289720be5ede6c39b3bf21 (patch)
treecaaf6f36c3e13a77ab677c5049dfa0f5922bf021 /libio/fileops.c
parent320a5dc07b907b1e640fd11ce49a04aa2b367711 (diff)
downloadglibc-fcabc0f8b185f9e0a9289720be5ede6c39b3bf21.tar.gz
glibc-fcabc0f8b185f9e0a9289720be5ede6c39b3bf21.tar.xz
glibc-fcabc0f8b185f9e0a9289720be5ede6c39b3bf21.zip
Fix file descriptor position after fclose
fclose should leave the file descriptor position after the last read
or written byte.
Diffstat (limited to 'libio/fileops.c')
-rw-r--r--libio/fileops.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/libio/fileops.c b/libio/fileops.c
index ea730ac95a..678e32a641 100644
--- a/libio/fileops.c
+++ b/libio/fileops.c
@@ -160,19 +160,25 @@ int
 _IO_new_file_close_it (fp)
      _IO_FILE *fp;
 {
-  int write_status, close_status;
   if (!_IO_file_is_open (fp))
     return EOF;
 
-  if ((fp->_flags & _IO_NO_WRITES) == 0
-      && (fp->_flags & _IO_CURRENTLY_PUTTING) != 0)
+  int write_status;
+  if (_IO_in_put_mode (fp))
     write_status = _IO_do_flush (fp);
-  else
-    write_status = 0;
+  else if (fp->_offset != _IO_pos_BAD && fp->_IO_read_base != NULL
+	   && !_IO_in_backup (fp))
+    {
+      off64_t o = _IO_SEEKOFF (fp, 0, _IO_seek_cur, 0);
+      if (o == WEOF)
+	write_status = EOF;
+      else
+	write_status = _IO_SYSSEEK (fp, o, SEEK_SET) < 0 ? EOF : 0;
+    }
 
   INTUSE(_IO_unsave_markers) (fp);
 
-  close_status = _IO_SYSCLOSE (fp);
+  int close_status = _IO_SYSCLOSE (fp);
 
   /* Free buffer. */
 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T