From 25abf44844f7b9ebeb7e7e3f21b05adb903850a1 Mon Sep 17 00:00:00 2001 From: Hans-Peter Nilsson Date: Wed, 5 Mar 2008 01:50:33 +0000 Subject: [PATCH] re PR libfortran/35293 (truncation errors with gfortran.dg/streamio_11.f90, 3, 4 and 15.) 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 | 9 +++++++++ libgfortran/io/unix.c | 24 ++++++++++++++++++------ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index d3ace3f7df7b..816272e4e414 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,12 @@ +2008-03-05 Hans-Peter Nilsson + + 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 PR fortran/33197 diff --git a/libgfortran/io/unix.c b/libgfortran/io/unix.c index d33c11091a0c..b3645f0003de 100644 --- a/libgfortran/io/unix.c +++ b/libgfortran/io/unix.c @@ -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;