re PR libfortran/35293 (truncation errors with gfortran.dg/streamio_11.f90, 3, 4...
authorHans-Peter Nilsson <hp@axis.com>
Wed, 5 Mar 2008 01:50:33 +0000 (01:50 +0000)
committerHans-Peter Nilsson <hp@gcc.gnu.org>
Wed, 5 Mar 2008 01:50:33 +0000 (01:50 +0000)
PR libfortran/35293
* io/unix.c (fd_truncate): Fold s->special_file case into
success case of ftruncate/chsize call instead of the failure case.
Make failure case actually return failure.  Properly update stream
pointers on failure.  Call runtime_error for targets without
neither ftruncate nor chsize where such a call would be needed.

From-SVN: r132888

libgfortran/ChangeLog
libgfortran/io/unix.c

index d3ace3f..816272e 100644 (file)
@@ -1,3 +1,12 @@
+2008-03-05  Hans-Peter Nilsson  <hp@axis.com>
+
+       PR libfortran/35293
+       * io/unix.c (fd_truncate): Fold s->special_file case into
+       success case of ftruncate/chsize call instead of the failure case.
+       Make failure case actually return failure.  Properly update stream
+       pointers on failure.  Call runtime_error for targets without
+       neither ftruncate nor chsize where such a call would be needed.
+
 2008-03-03  Francois-Xavier Coudert  <fxcoudert@gcc.gnu.org>
 
        PR fortran/33197
index d33c110..b3645f0 100644 (file)
@@ -706,16 +706,28 @@ fd_truncate (unix_stream * s)
 
   /* Using ftruncate on a seekable special file (like /dev/null)
      is undefined, so we treat it as if the ftruncate succeeded.  */
+  if (!s->special_file
+      && (
 #ifdef HAVE_FTRUNCATE
-  if (s->special_file || ftruncate (s->fd, s->logical_offset))
+         ftruncate (s->fd, s->logical_offset) != 0
+#elif defined HAVE_CHSIZE
+         chsize (s->fd, s->logical_offset) != 0
 #else
-#ifdef HAVE_CHSIZE
-  if (s->special_file || chsize (s->fd, s->logical_offset))
-#endif
+         /* If we have neither, always fail and exit, noisily.  */
+         runtime_error ("required ftruncate or chsize support not present"), 1
 #endif
+         ))
     {
-      s->physical_offset = s->file_length = 0;
-      return SUCCESS;
+      /* The truncation failed and we need to handle this gracefully.
+        The file length remains the same, but the file-descriptor
+        offset needs adjustment per the successful lseek above.
+        (Similarly, the contents of the buffer isn't valid anymore.)
+        A ftruncate call does not affect the physical (file-descriptor)
+        offset, according to the ftruncate manual, so neither should a
+        failed call.  */
+      s->physical_offset = s->logical_offset;
+      s->active = 0;
+      return FAILURE;
     }
 
   s->physical_offset = s->file_length = s->logical_offset;