This is the mail archive of the glibc-cvs@sourceware.org mailing list for the glibc 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]

GNU C Library master sources branch master updated. glibc-2.20-301-g24b9788


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, master has been updated
       via  24b9788285effddba3d52f174d483583cf820d19 (commit)
       via  fe8b4d98e9ac371238388469cb74011cb2120343 (commit)
       via  61b4f792e03facb456036b3f631d58d4f53b8075 (commit)
       via  be349d7042de84c3c5157a5c1fbcad580aed33e1 (commit)
      from  e3d6dba5dfe2e125b15ea1dd36c8dfa373bb4956 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=24b9788285effddba3d52f174d483583cf820d19

commit 24b9788285effddba3d52f174d483583cf820d19
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
Date:   Thu Dec 4 08:45:55 2014 +0530

    Fix up function definition style
    
    Don't use K&R style for function definitions.

diff --git a/ChangeLog b/ChangeLog
index 4cee7d7..c70a401 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2914-12-04  Siddhesh Poyarekar  <siddhesh@redhat.com>
 
+	* libio/fileops.c: Use IOS C style for function definitions.
+	* libio/iofopen.c: Likewise.
+	* libio/wfileops.c: Likewise.
+
 	[BZ #17653]
 	* libio/fileops.c (_IO_new_file_underflow): Unset cached
 	offset on EOF.
diff --git a/libio/fileops.c b/libio/fileops.c
index ee50b72..de519c5 100644
--- a/libio/fileops.c
+++ b/libio/fileops.c
@@ -139,8 +139,7 @@ extern struct __gconv_trans_data __libio_translit attribute_hidden;
 
 
 void
-_IO_new_file_init (fp)
-     struct _IO_FILE_plus *fp;
+_IO_new_file_init (struct _IO_FILE_plus *fp)
 {
   /* POSIX.1 allows another file handle to be used to change the position
      of our file descriptor.  Hence we actually don't know the actual
@@ -154,8 +153,7 @@ _IO_new_file_init (fp)
 libc_hidden_ver (_IO_new_file_init, _IO_file_init)
 
 int
-_IO_new_file_close_it (fp)
-     _IO_FILE *fp;
+_IO_new_file_close_it (_IO_FILE *fp)
 {
   int write_status;
   if (!_IO_file_is_open (fp))
@@ -197,9 +195,7 @@ _IO_new_file_close_it (fp)
 libc_hidden_ver (_IO_new_file_close_it, _IO_file_close_it)
 
 void
-_IO_new_file_finish (fp, dummy)
-     _IO_FILE *fp;
-     int dummy;
+_IO_new_file_finish (_IO_FILE *fp, int dummy)
 {
   if (_IO_file_is_open (fp))
     {
@@ -212,13 +208,8 @@ _IO_new_file_finish (fp, dummy)
 libc_hidden_ver (_IO_new_file_finish, _IO_file_finish)
 
 _IO_FILE *
-_IO_file_open (fp, filename, posix_mode, prot, read_write, is32not64)
-     _IO_FILE *fp;
-     const char *filename;
-     int posix_mode;
-     int prot;
-     int read_write;
-     int is32not64;
+_IO_file_open (_IO_FILE *fp, const char *filename, int posix_mode, int prot,
+	       int read_write, int is32not64)
 {
   int fdesc;
 #ifdef _LIBC
@@ -252,11 +243,8 @@ _IO_file_open (fp, filename, posix_mode, prot, read_write, is32not64)
 libc_hidden_def (_IO_file_open)
 
 _IO_FILE *
-_IO_new_file_fopen (fp, filename, mode, is32not64)
-     _IO_FILE *fp;
-     const char *filename;
-     const char *mode;
-     int is32not64;
+_IO_new_file_fopen (_IO_FILE *fp, const char *filename, const char *mode,
+		    int is32not64)
 {
   int oflags = 0, omode;
   int read_write;
@@ -426,9 +414,7 @@ _IO_new_file_fopen (fp, filename, mode, is32not64)
 libc_hidden_ver (_IO_new_file_fopen, _IO_file_fopen)
 
 _IO_FILE *
-_IO_new_file_attach (fp, fd)
-     _IO_FILE *fp;
-     int fd;
+_IO_new_file_attach (_IO_FILE *fp, int fd)
 {
   if (_IO_file_is_open (fp))
     return NULL;
@@ -448,10 +434,7 @@ _IO_new_file_attach (fp, fd)
 libc_hidden_ver (_IO_new_file_attach, _IO_file_attach)
 
 _IO_FILE *
-_IO_new_file_setbuf (fp, p, len)
-     _IO_FILE *fp;
-     char *p;
-     _IO_ssize_t len;
+_IO_new_file_setbuf (_IO_FILE *fp, char *p, _IO_ssize_t len)
 {
   if (_IO_default_setbuf (fp, p, len) == NULL)
     return NULL;
@@ -466,10 +449,7 @@ libc_hidden_ver (_IO_new_file_setbuf, _IO_file_setbuf)
 
 
 _IO_FILE *
-_IO_file_setbuf_mmap (fp, p, len)
-     _IO_FILE *fp;
-     char *p;
-     _IO_ssize_t len;
+_IO_file_setbuf_mmap (_IO_FILE *fp, char *p, _IO_ssize_t len)
 {
   _IO_FILE *result;
 
@@ -496,10 +476,7 @@ static _IO_size_t new_do_write (_IO_FILE *, const char *, _IO_size_t);
    Then mark FP as having empty buffers. */
 
 int
-_IO_new_do_write (fp, data, to_do)
-     _IO_FILE *fp;
-     const char *data;
-     _IO_size_t to_do;
+_IO_new_do_write (_IO_FILE *fp, const char *data, _IO_size_t to_do)
 {
   return (to_do == 0
 	  || (_IO_size_t) new_do_write (fp, data, to_do) == to_do) ? 0 : EOF;
@@ -508,10 +485,7 @@ libc_hidden_ver (_IO_new_do_write, _IO_do_write)
 
 static
 _IO_size_t
-new_do_write (fp, data, to_do)
-     _IO_FILE *fp;
-     const char *data;
-     _IO_size_t to_do;
+new_do_write (_IO_FILE *fp, const char *data, _IO_size_t to_do)
 {
   _IO_size_t count;
   if (fp->_flags & _IO_IS_APPENDING)
@@ -541,8 +515,7 @@ new_do_write (fp, data, to_do)
 }
 
 int
-_IO_new_file_underflow (fp)
-     _IO_FILE *fp;
+_IO_new_file_underflow (_IO_FILE *fp)
 {
   _IO_ssize_t count;
 #if 0
@@ -818,9 +791,7 @@ _IO_file_underflow_maybe_mmap (_IO_FILE *fp)
 
 
 int
-_IO_new_file_overflow (f, ch)
-      _IO_FILE *f;
-      int ch;
+_IO_new_file_overflow (_IO_FILE *f, int ch)
 {
   if (f->_flags & _IO_NO_WRITES) /* SET ERROR */
     {
@@ -881,8 +852,7 @@ _IO_new_file_overflow (f, ch)
 libc_hidden_ver (_IO_new_file_overflow, _IO_file_overflow)
 
 int
-_IO_new_file_sync (fp)
-     _IO_FILE *fp;
+_IO_new_file_sync (_IO_FILE *fp)
 {
   _IO_ssize_t delta;
   int retval = 0;
@@ -1000,11 +970,7 @@ do_ftell (_IO_FILE *fp)
 }
 
 _IO_off64_t
-_IO_new_file_seekoff (fp, offset, dir, mode)
-     _IO_FILE *fp;
-     _IO_off64_t offset;
-     int dir;
-     int mode;
+_IO_new_file_seekoff (_IO_FILE *fp, _IO_off64_t offset, int dir, int mode)
 {
   _IO_off64_t result;
   _IO_off64_t delta, new_offset;
@@ -1160,11 +1126,7 @@ resync:
 libc_hidden_ver (_IO_new_file_seekoff, _IO_file_seekoff)
 
 _IO_off64_t
-_IO_file_seekoff_mmap (fp, offset, dir, mode)
-     _IO_FILE *fp;
-     _IO_off64_t offset;
-     int dir;
-     int mode;
+_IO_file_seekoff_mmap (_IO_FILE *fp, _IO_off64_t offset, int dir, int mode)
 {
   _IO_off64_t result;
 
@@ -1235,10 +1197,7 @@ _IO_file_seekoff_maybe_mmap (_IO_FILE *fp, _IO_off64_t offset, int dir,
 }
 
 _IO_ssize_t
-_IO_file_read (fp, buf, size)
-     _IO_FILE *fp;
-     void *buf;
-     _IO_ssize_t size;
+_IO_file_read (_IO_FILE *fp, void *buf, _IO_ssize_t size)
 {
   return (__builtin_expect (fp->_flags2 & _IO_FLAGS2_NOTCANCEL, 0)
 	  ? read_not_cancel (fp->_fileno, buf, size)
@@ -1247,27 +1206,21 @@ _IO_file_read (fp, buf, size)
 libc_hidden_def (_IO_file_read)
 
 _IO_off64_t
-_IO_file_seek (fp, offset, dir)
-     _IO_FILE *fp;
-     _IO_off64_t offset;
-     int dir;
+_IO_file_seek (_IO_FILE *fp, _IO_off64_t offset, int dir)
 {
   return __lseek64 (fp->_fileno, offset, dir);
 }
 libc_hidden_def (_IO_file_seek)
 
 int
-_IO_file_stat (fp, st)
-     _IO_FILE *fp;
-     void *st;
+_IO_file_stat (_IO_FILE *fp, void *st)
 {
   return __fxstat64 (_STAT_VER, fp->_fileno, (struct stat64 *) st);
 }
 libc_hidden_def (_IO_file_stat)
 
 int
-_IO_file_close_mmap (fp)
-     _IO_FILE *fp;
+_IO_file_close_mmap (_IO_FILE *fp)
 {
   /* In addition to closing the file descriptor we have to unmap the file.  */
   (void) __munmap (fp->_IO_buf_base, fp->_IO_buf_end - fp->_IO_buf_base);
@@ -1278,8 +1231,7 @@ _IO_file_close_mmap (fp)
 }
 
 int
-_IO_file_close (fp)
-     _IO_FILE *fp;
+_IO_file_close (_IO_FILE *fp)
 {
   /* Cancelling close should be avoided if possible since it leaves an
      unrecoverable state behind.  */
@@ -1288,10 +1240,7 @@ _IO_file_close (fp)
 libc_hidden_def (_IO_file_close)
 
 _IO_ssize_t
-_IO_new_file_write (f, data, n)
-     _IO_FILE *f;
-     const void *data;
-     _IO_ssize_t n;
+_IO_new_file_write (_IO_FILE *f, const void *data, _IO_ssize_t n)
 {
   _IO_ssize_t to_do = n;
   while (to_do > 0)
@@ -1315,10 +1264,7 @@ _IO_new_file_write (f, data, n)
 }
 
 _IO_size_t
-_IO_new_file_xsputn (f, data, n)
-     _IO_FILE *f;
-     const void *data;
-     _IO_size_t n;
+_IO_new_file_xsputn (_IO_FILE *f, const void *data, _IO_size_t n)
 {
   const char *s = (const char *) data;
   _IO_size_t to_do = n;
@@ -1398,10 +1344,7 @@ _IO_new_file_xsputn (f, data, n)
 libc_hidden_ver (_IO_new_file_xsputn, _IO_file_xsputn)
 
 _IO_size_t
-_IO_file_xsgetn (fp, data, n)
-     _IO_FILE *fp;
-     void *data;
-     _IO_size_t n;
+_IO_file_xsgetn (_IO_FILE *fp, void *data, _IO_size_t n)
 {
   _IO_size_t want, have;
   _IO_ssize_t count;
@@ -1498,12 +1441,8 @@ _IO_file_xsgetn (fp, data, n)
 }
 libc_hidden_def (_IO_file_xsgetn)
 
-static _IO_size_t _IO_file_xsgetn_mmap (_IO_FILE *, void *, _IO_size_t);
 static _IO_size_t
-_IO_file_xsgetn_mmap (fp, data, n)
-     _IO_FILE *fp;
-     void *data;
-     _IO_size_t n;
+_IO_file_xsgetn_mmap (_IO_FILE *fp, void *data, _IO_size_t n)
 {
   _IO_size_t have;
   char *read_ptr = fp->_IO_read_ptr;
@@ -1557,12 +1496,8 @@ _IO_file_xsgetn_mmap (fp, data, n)
   return s - (char *) data;
 }
 
-static _IO_size_t _IO_file_xsgetn_maybe_mmap (_IO_FILE *, void *, _IO_size_t);
 static _IO_size_t
-_IO_file_xsgetn_maybe_mmap (fp, data, n)
-     _IO_FILE *fp;
-     void *data;
-     _IO_size_t n;
+_IO_file_xsgetn_maybe_mmap (_IO_FILE *fp, void *data, _IO_size_t n)
 {
   /* We only get here if this is the first attempt to read something.
      Decide which operations to use and then punt to the chosen one.  */
diff --git a/libio/iofopen.c b/libio/iofopen.c
index 4fbf486..f2ccc89 100644
--- a/libio/iofopen.c
+++ b/libio/iofopen.c
@@ -35,8 +35,7 @@
 #endif
 
 _IO_FILE *
-__fopen_maybe_mmap (fp)
-     _IO_FILE *fp;
+__fopen_maybe_mmap (_IO_FILE *fp)
 {
 #ifdef _G_HAVE_MMAP
   if ((fp->_flags2 & _IO_FLAGS2_MMAP) && (fp->_flags & _IO_NO_WRITES))
@@ -58,10 +57,7 @@ __fopen_maybe_mmap (fp)
 
 
 _IO_FILE *
-__fopen_internal (filename, mode, is32)
-     const char *filename;
-     const char *mode;
-     int is32;
+__fopen_internal (const char *filename, const char *mode, int is32)
 {
   struct locked_FILE
   {
@@ -96,9 +92,7 @@ __fopen_internal (filename, mode, is32)
 }
 
 _IO_FILE *
-_IO_new_fopen (filename, mode)
-     const char *filename;
-     const char *mode;
+_IO_new_fopen (const char *filename, const char *mode)
 {
   return __fopen_internal (filename, mode, 1);
 }
diff --git a/libio/wfileops.c b/libio/wfileops.c
index 2a003b3..698ff8f 100644
--- a/libio/wfileops.c
+++ b/libio/wfileops.c
@@ -54,10 +54,7 @@
 /* Convert TO_DO wide character from DATA to FP.
    Then mark FP as having empty buffers. */
 int
-_IO_wdo_write (fp, data, to_do)
-     _IO_FILE *fp;
-     const wchar_t *data;
-     _IO_size_t to_do;
+_IO_wdo_write (_IO_FILE *fp, const wchar_t *data, _IO_size_t to_do)
 {
   struct _IO_codecvt *cc = fp->_codecvt;
 
@@ -131,8 +128,7 @@ libc_hidden_def (_IO_wdo_write)
 
 
 wint_t
-_IO_wfile_underflow (fp)
-     _IO_FILE *fp;
+_IO_wfile_underflow (_IO_FILE *fp)
 {
   struct _IO_codecvt *cd;
   enum __codecvt_result status;
@@ -428,9 +424,7 @@ _IO_wfile_underflow_maybe_mmap (_IO_FILE *fp)
 
 
 wint_t
-_IO_wfile_overflow (f, wch)
-     _IO_FILE *f;
-     wint_t wch;
+_IO_wfile_overflow (_IO_FILE *f, wint_t wch)
 {
   if (f->_flags & _IO_NO_WRITES) /* SET ERROR */
     {
@@ -502,8 +496,7 @@ _IO_wfile_overflow (f, wch)
 libc_hidden_def (_IO_wfile_overflow)
 
 wint_t
-_IO_wfile_sync (fp)
-     _IO_FILE *fp;
+_IO_wfile_sync (_IO_FILE *fp)
 {
   _IO_ssize_t delta;
   wint_t retval = 0;
@@ -767,11 +760,7 @@ do_ftell_wide (_IO_FILE *fp)
 }
 
 _IO_off64_t
-_IO_wfile_seekoff (fp, offset, dir, mode)
-     _IO_FILE *fp;
-     _IO_off64_t offset;
-     int dir;
-     int mode;
+_IO_wfile_seekoff (_IO_FILE *fp, _IO_off64_t offset, int dir, int mode)
 {
   _IO_off64_t result;
   _IO_off64_t delta, new_offset;
@@ -982,10 +971,7 @@ libc_hidden_def (_IO_wfile_seekoff)
 
 
 _IO_size_t
-_IO_wfile_xsputn (f, data, n)
-     _IO_FILE *f;
-     const void *data;
-     _IO_size_t n;
+_IO_wfile_xsputn (_IO_FILE *f, const void *data, _IO_size_t n)
 {
   const wchar_t *s = (const wchar_t *) data;
   _IO_size_t to_do = n;

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=fe8b4d98e9ac371238388469cb74011cb2120343

commit fe8b4d98e9ac371238388469cb74011cb2120343
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
Date:   Thu Dec 4 08:13:28 2014 +0530

    Reset cached offset when reading to end of stream (BZ #17653)
    
    POSIX allows applications to switch file handles when a read results
    in an end of file.  Unset the cached offset at this point so that it
    is queried again.

diff --git a/ChangeLog b/ChangeLog
index 1bd4b23..4cee7d7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
 2914-12-04  Siddhesh Poyarekar  <siddhesh@redhat.com>
 
+	[BZ #17653]
+	* libio/fileops.c (_IO_new_file_underflow): Unset cached
+	offset on EOF.
+	* libio/wfileops.c (_IO_wfile_underflow): Likewise.
+	* libio/tst-ftell-active-handler.c (fgets_func_t): New type.
+	(fgets_func): Function pointer to fgets and fgetws.
+	(do_ftell_test): Add test to verify ftell value after read
+	EOF.
+	(do_test): Set fgets_func.
+
 	* libio/tst-ftell-active-handler.c (do_ftruncate_test): Add
 	O_TRUNC flag for w and w+ modes.
 	(do_rewind_test): Likewise.
diff --git a/NEWS b/NEWS
index 7312b47..84c1353 100644
--- a/NEWS
+++ b/NEWS
@@ -13,7 +13,7 @@ Version 2.21
   16619, 16740, 16857, 17192, 17266, 17344, 17363, 17370, 17371, 17411,
   17460, 17475, 17485, 17501, 17506, 17508, 17522, 17555, 17570, 17571,
   17572, 17573, 17574, 17581, 17582, 17583, 17584, 17585, 17589, 17594,
-  17601, 17608, 17616, 17625, 17633, 17647, 17664, 17665, 17668.
+  17601, 17608, 17616, 17625, 17633, 17647, 17653, 17664, 17665, 17668.
 
 * CVE-2104-7817 The wordexp function could ignore the WRDE_NOCMD flag
   under certain input conditions resulting in the execution of a shell for
diff --git a/libio/fileops.c b/libio/fileops.c
index dca3591..ee50b72 100644
--- a/libio/fileops.c
+++ b/libio/fileops.c
@@ -615,7 +615,13 @@ _IO_new_file_underflow (fp)
   }
   fp->_IO_read_end += count;
   if (count == 0)
-    return EOF;
+    {
+      /* If a stream is read to EOF, the calling application may switch active
+	 handles.  As a result, our offset cache would no longer be valid, so
+	 unset it.  */
+      fp->_offset = _IO_pos_BAD;
+      return EOF;
+    }
   if (fp->_offset != _IO_pos_BAD)
     _IO_pos_adjust (fp->_offset, count);
   return *(unsigned char *) fp->_IO_read_ptr;
diff --git a/libio/tst-ftell-active-handler.c b/libio/tst-ftell-active-handler.c
index 72066b4..f69e169 100644
--- a/libio/tst-ftell-active-handler.c
+++ b/libio/tst-ftell-active-handler.c
@@ -86,7 +86,9 @@ static size_t data_len;
 static size_t file_len;
 
 typedef int (*fputs_func_t) (const void *data, FILE *fp);
+typedef void *(*fgets_func_t) (void *ws, int n, FILE *fp);
 fputs_func_t fputs_func;
+fgets_func_t fgets_func;
 
 /* This test verifies that the offset reported by ftell is correct after the
    file is truncated using ftruncate.  ftruncate does not change the file
@@ -290,20 +292,22 @@ do_ftell_test (const char *filename)
       int fd_mode;
       size_t old_off;
       size_t new_off;
+      size_t eof_off;
     } test_modes[] = {
 	  /* In w, w+ and r+ modes, the file position should be at the
 	     beginning of the file.  After the write, the offset should be
-	     updated to data_len.  */
-	  {"w", O_WRONLY | O_TRUNC, 0, data_len},
-	  {"w+", O_RDWR | O_TRUNC, 0, data_len},
-	  {"r+", O_RDWR, 0, data_len},
+	     updated to data_len.  We don't use eof_off in w and a modes since
+	     they don't allow reading.  */
+	  {"w", O_WRONLY | O_TRUNC, 0, data_len, 0},
+	  {"w+", O_RDWR | O_TRUNC, 0, data_len, 2 * data_len},
+	  {"r+", O_RDWR, 0, data_len, 3 * data_len},
 	  /* For the 'a' mode, the initial file position should be the
 	     current end of file. After the write, the offset has data_len
 	     added to the old value.  For a+ mode however, the initial file
 	     position is the file position of the underlying file descriptor,
 	     since it is initially assumed to be in read mode.  */
-	  {"a", O_WRONLY, data_len, 2 * data_len},
-	  {"a+", O_RDWR, 0, 3 * data_len},
+	  {"a", O_WRONLY, 3 * data_len, 4 * data_len, 5 * data_len},
+	  {"a+", O_RDWR, 0, 5 * data_len, 6 * data_len},
     };
   for (int j = 0; j < 2; j++)
     {
@@ -348,12 +352,44 @@ do_ftell_test (const char *filename)
 
 	  if (off != test_modes[i].new_off)
 	    {
-	      printf ("Incorrect new offset.  Expected %zu but got %ld\n",
+	      printf ("Incorrect new offset.  Expected %zu but got %ld",
 		      test_modes[i].new_off, off);
 	      ret |= 1;
 	    }
 	  else
-	    printf ("new offset = %ld\n", off);
+	    printf ("new offset = %ld", off);
+
+	  /* Read to the end, write some data to the fd and check if ftell can
+	     see the new ofset.  Do this test only for files that allow
+	     reading.  */
+	  if (test_modes[i].fd_mode != O_WRONLY)
+	    {
+	      char tmpbuf[data_len];
+
+	      rewind (fp);
+
+	      while (fgets_func (tmpbuf, sizeof (tmpbuf), fp) && !feof (fp));
+
+	      write_ret = write (fd, data, data_len);
+	      if (write_ret != data_len)
+		{
+		  printf ("write failed (%m)\n");
+		  ret |= 1;
+		}
+	      off = ftell (fp);
+
+	      if (off != test_modes[i].eof_off)
+		{
+		  printf (", Incorrect offset after read EOF.  "
+			  "Expected %zu but got %ld\n",
+			  test_modes[i].eof_off, off);
+		  ret |= 1;
+		}
+	      else
+		printf (", offset after EOF = %ld\n", off);
+	    }
+	  else
+	    putc ('\n', stdout);
 
 	  fclose (fp);
 	}
@@ -617,6 +653,7 @@ do_test (void)
   /* Tests for regular files.  */
   puts ("Regular mode:");
   fputs_func = (fputs_func_t) fputs;
+  fgets_func = (fgets_func_t) fgets;
   data = char_data;
   data_len = strlen (char_data);
   ret |= do_one_test (filename);
@@ -638,6 +675,7 @@ do_test (void)
       return 1;
     }
   fputs_func = (fputs_func_t) fputws;
+  fgets_func = (fgets_func_t) fgetws;
   data = wide_data;
   data_len = wcslen (wide_data);
   ret |= do_one_test (filename);
diff --git a/libio/wfileops.c b/libio/wfileops.c
index 71281c1..2a003b3 100644
--- a/libio/wfileops.c
+++ b/libio/wfileops.c
@@ -257,7 +257,10 @@ _IO_wfile_underflow (fp)
   if (count <= 0)
     {
       if (count == 0 && naccbuf == 0)
-	fp->_flags |= _IO_EOF_SEEN;
+	{
+	  fp->_flags |= _IO_EOF_SEEN;
+	  fp->_offset = _IO_pos_BAD;
+	}
       else
 	fp->_flags |= _IO_ERR_SEEN, count = 0;
     }

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=61b4f792e03facb456036b3f631d58d4f53b8075

commit 61b4f792e03facb456036b3f631d58d4f53b8075
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
Date:   Thu Dec 4 08:11:07 2014 +0530

    tst-ftell-active-handler: Open file with O_TRUNC for w modes
    
    The test case fails to truncate the file when a file is intended to be
    opened in w or w+ mode.  Add O_TRUNC to fix this.  The test still
    succeeds with this change.

diff --git a/ChangeLog b/ChangeLog
index 83048e1..1bd4b23 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2914-12-04  Siddhesh Poyarekar  <siddhesh@redhat.com>
 
+	* libio/tst-ftell-active-handler.c (do_ftruncate_test): Add
+	O_TRUNC flag for w and w+ modes.
+	(do_rewind_test): Likewise.
+	(do_ftell_test): Likewise.
+	(do_write_test): Likewise.
+
 	[BZ #17647]
 	* libio/fileops.c (do_ftell): Seek only when there are
 	unflushed writes.
diff --git a/libio/tst-ftell-active-handler.c b/libio/tst-ftell-active-handler.c
index 9f23c55..72066b4 100644
--- a/libio/tst-ftell-active-handler.c
+++ b/libio/tst-ftell-active-handler.c
@@ -104,8 +104,8 @@ do_ftruncate_test (const char *filename)
       int fd_mode;
     } test_modes[] = {
 	  {"r+", O_RDWR},
-	  {"w", O_WRONLY},
-	  {"w+", O_RDWR},
+	  {"w", O_WRONLY | O_TRUNC},
+	  {"w+", O_RDWR | O_TRUNC},
 	  {"a", O_WRONLY},
 	  {"a+", O_RDWR}
     };
@@ -189,8 +189,8 @@ do_rewind_test (const char *filename)
       size_t old_off;
       size_t new_off;
     } test_modes[] = {
-	  {"w", O_WRONLY, 0, data_len},
-	  {"w+", O_RDWR, 0, data_len},
+	  {"w", O_WRONLY | O_TRUNC, 0, data_len},
+	  {"w+", O_RDWR | O_TRUNC, 0, data_len},
 	  {"r+", O_RDWR, 0, data_len},
 	  /* The new offsets for 'a' and 'a+' modes have to factor in the
 	     previous writes since they always append to the end of the
@@ -294,8 +294,8 @@ do_ftell_test (const char *filename)
 	  /* In w, w+ and r+ modes, the file position should be at the
 	     beginning of the file.  After the write, the offset should be
 	     updated to data_len.  */
-	  {"w", O_WRONLY, 0, data_len},
-	  {"w+", O_RDWR, 0, data_len},
+	  {"w", O_WRONLY | O_TRUNC, 0, data_len},
+	  {"w+", O_RDWR | O_TRUNC, 0, data_len},
 	  {"r+", O_RDWR, 0, data_len},
 	  /* For the 'a' mode, the initial file position should be the
 	     current end of file. After the write, the offset has data_len
@@ -375,8 +375,8 @@ do_write_test (const char *filename)
       const char *mode;
       int fd_mode;
     } test_modes[] = {
-	  {"w", O_WRONLY},
-	  {"w+", O_RDWR},
+	  {"w", O_WRONLY | O_TRUNC},
+	  {"w+", O_RDWR | O_TRUNC},
 	  {"r+", O_RDWR}
     };
 

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=be349d7042de84c3c5157a5c1fbcad580aed33e1

commit be349d7042de84c3c5157a5c1fbcad580aed33e1
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
Date:   Thu Dec 4 08:08:37 2014 +0530

    ftell: seek to end only when there are unflushed bytes (BZ #17647)
    
    Currently we seek to end of file if there are unflushed writes or the
    stream is in write mode, to get the current offset for writing in
    append mode, which is the end of file.  The latter case (i.e. stream
    is in write mode, but no unflushed writes) is unnecessary since it
    will only happen when the stream has just been flushed, in which case
    the recorded offset ought to be reliable.
    
    Removing that case lets ftell give the correct offset when it follows
    an ftruncate.  The latter truncates the file, but does not change the
    file position, due to which it is permissible to call ftell without an
    intervening fseek call.
    
    Tested on x86_64 to verify that the added test case fails without the
    patch and succeeds with it, and that there are no additional
    regressions due to it.
    
    	[BZ #17647]
    	* libio/fileops.c (do_ftell): Seek only when there are
    	unflushed writes.
    	* libio/wfileops.c (do_ftell_wide): Likewise.
    	* libio/tst-ftell-active-handler.c (do_ftruncate_test): New
    	test case.
    	(do_one_test): Call it.

diff --git a/ChangeLog b/ChangeLog
index b064598..83048e1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2914-12-04  Siddhesh Poyarekar  <siddhesh@redhat.com>
+
+	[BZ #17647]
+	* libio/fileops.c (do_ftell): Seek only when there are
+	unflushed writes.
+	* libio/wfileops.c (do_ftell_wide): Likewise.
+	* libio/tst-ftell-active-handler.c (do_ftruncate_test): New
+	test case.
+	(do_one_test): Call it.
+
 2014-12-03  Joseph Myers  <joseph@codesourcery.com>
 
 	* conform/list-header-symbols.pl (%extra_syms): Add getdate_err
diff --git a/NEWS b/NEWS
index 581bc8b..7312b47 100644
--- a/NEWS
+++ b/NEWS
@@ -13,7 +13,7 @@ Version 2.21
   16619, 16740, 16857, 17192, 17266, 17344, 17363, 17370, 17371, 17411,
   17460, 17475, 17485, 17501, 17506, 17508, 17522, 17555, 17570, 17571,
   17572, 17573, 17574, 17581, 17582, 17583, 17584, 17585, 17589, 17594,
-  17601, 17608, 17616, 17625, 17633, 17664, 17665, 17668.
+  17601, 17608, 17616, 17625, 17633, 17647, 17664, 17665, 17668.
 
 * CVE-2104-7817 The wordexp function could ignore the WRDE_NOCMD flag
   under certain input conditions resulting in the execution of a shell for
diff --git a/libio/fileops.c b/libio/fileops.c
index e0d7b76..dca3591 100644
--- a/libio/fileops.c
+++ b/libio/fileops.c
@@ -943,15 +943,14 @@ do_ftell (_IO_FILE *fp)
      yet.  */
   if (fp->_IO_buf_base != NULL)
     {
-      bool was_writing = (fp->_IO_write_ptr > fp->_IO_write_base
-			  || _IO_in_put_mode (fp));
+      bool unflushed_writes = fp->_IO_write_ptr > fp->_IO_write_base;
 
       bool append_mode = (fp->_flags & _IO_IS_APPENDING) == _IO_IS_APPENDING;
 
       /* When we have unflushed writes in append mode, seek to the end of the
 	 file and record that offset.  This is the only time we change the file
 	 stream state and it is safe since the file handle is active.  */
-      if (was_writing && append_mode)
+      if (unflushed_writes && append_mode)
 	{
 	  result = _IO_SYSSEEK (fp, 0, _IO_seek_end);
 	  if (result == _IO_pos_BAD)
@@ -961,7 +960,7 @@ do_ftell (_IO_FILE *fp)
 	}
 
       /* Adjust for unflushed data.  */
-      if (!was_writing)
+      if (!unflushed_writes)
 	offset -= fp->_IO_read_end - fp->_IO_read_ptr;
       /* We don't trust _IO_read_end to represent the current file offset when
 	 writing in append mode because the value would have to be shifted to
diff --git a/libio/tst-ftell-active-handler.c b/libio/tst-ftell-active-handler.c
index e9dc7b3..9f23c55 100644
--- a/libio/tst-ftell-active-handler.c
+++ b/libio/tst-ftell-active-handler.c
@@ -88,6 +88,95 @@ static size_t file_len;
 typedef int (*fputs_func_t) (const void *data, FILE *fp);
 fputs_func_t fputs_func;
 
+/* This test verifies that the offset reported by ftell is correct after the
+   file is truncated using ftruncate.  ftruncate does not change the file
+   offset on truncation and hence, SEEK_CUR should continue to point to the
+   old offset and not be changed to the new offset.  */
+static int
+do_ftruncate_test (const char *filename)
+{
+  FILE *fp = NULL;
+  int fd;
+  int ret = 0;
+  struct test
+    {
+      const char *mode;
+      int fd_mode;
+    } test_modes[] = {
+	  {"r+", O_RDWR},
+	  {"w", O_WRONLY},
+	  {"w+", O_RDWR},
+	  {"a", O_WRONLY},
+	  {"a+", O_RDWR}
+    };
+
+  for (int j = 0; j < 2; j++)
+    {
+      for (int i = 0; i < sizeof (test_modes) / sizeof (struct test); i++)
+	{
+	  int fileret;
+	  printf ("\tftruncate: %s (file, \"%s\"): ",
+		  j == 0 ? "fopen" : "fdopen",
+		  test_modes[i].mode);
+
+	  if (j == 0)
+	    fileret = get_handles_fopen (filename, fd, fp, test_modes[i].mode);
+	  else
+	    fileret = get_handles_fdopen (filename, fd, fp,
+					  test_modes[i].fd_mode,
+					  test_modes[i].mode);
+
+	  if (fileret != 0)
+	    return fileret;
+
+	  /* Write some data.  */
+	  size_t written = fputs_func (data, fp);
+
+	  if (written == EOF)
+	    {
+	      printf ("fputs[1] failed to write data\n");
+	      ret |= 1;
+	    }
+
+	  /* Record the offset.  */
+	  long offset = ftell (fp);
+
+	  /* Flush data to allow switching active handles.  */
+	  if (fflush (fp))
+	    {
+	      printf ("Flush failed: %m\n");
+	      ret |= 1;
+	    }
+
+	  /* Now truncate the file.  */
+	  if (ftruncate (fd, 0) != 0)
+	    {
+	      printf ("Failed to truncate file: %m\n");
+	      ret |= 1;
+	    }
+
+	  /* ftruncate does not change the offset, so there is no need to call
+	     anything to be able to switch active handles.  */
+	  long new_offset = ftell (fp);
+
+	  /* The offset should remain unchanged since ftruncate does not update
+	     it.  */
+	  if (offset != new_offset)
+	    {
+	      printf ("Incorrect offset.  Expected %zu, but got %ld\n",
+		      offset, new_offset);
+
+	      ret |= 1;
+	    }
+	  else
+	    printf ("offset = %ld\n", offset);
+
+	  fclose (fp);
+	}
+    }
+
+  return ret;
+}
 /* Test that ftell output after a rewind is correct.  */
 static int
 do_rewind_test (const char *filename)
@@ -481,6 +570,7 @@ do_one_test (const char *filename)
   ret |= do_write_test (filename);
   ret |= do_append_test (filename);
   ret |= do_rewind_test (filename);
+  ret |= do_ftruncate_test (filename);
 
   return ret;
 }
diff --git a/libio/wfileops.c b/libio/wfileops.c
index 6a088b1..71281c1 100644
--- a/libio/wfileops.c
+++ b/libio/wfileops.c
@@ -626,16 +626,15 @@ do_ftell_wide (_IO_FILE *fp)
       const wchar_t *wide_read_base;
       const wchar_t *wide_read_ptr;
       const wchar_t *wide_read_end;
-      bool was_writing = ((fp->_wide_data->_IO_write_ptr
-			   > fp->_wide_data->_IO_write_base)
-			  || _IO_in_put_mode (fp));
+      bool unflushed_writes = (fp->_wide_data->_IO_write_ptr
+			       > fp->_wide_data->_IO_write_base);
 
       bool append_mode = (fp->_flags & _IO_IS_APPENDING) == _IO_IS_APPENDING;
 
       /* When we have unflushed writes in append mode, seek to the end of the
 	 file and record that offset.  This is the only time we change the file
 	 stream state and it is safe since the file handle is active.  */
-      if (was_writing && append_mode)
+      if (unflushed_writes && append_mode)
 	{
 	  result = _IO_SYSSEEK (fp, 0, _IO_seek_end);
 	  if (result == _IO_pos_BAD)
@@ -674,7 +673,7 @@ do_ftell_wide (_IO_FILE *fp)
       struct _IO_codecvt *cv = fp->_codecvt;
       int clen = (*cv->__codecvt_do_encoding) (cv);
 
-      if (!was_writing)
+      if (!unflushed_writes)
 	{
 	  if (clen > 0)
 	    {

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog                        |   30 ++++++++
 NEWS                             |    2 +-
 libio/fileops.c                  |  134 +++++++++------------------------
 libio/iofopen.c                  |   12 +--
 libio/tst-ftell-active-handler.c |  152 +++++++++++++++++++++++++++++++++++---
 libio/wfileops.c                 |   40 ++++-------
 6 files changed, 225 insertions(+), 145 deletions(-)


hooks/post-receive
-- 
GNU C Library master sources


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