summaryrefslogtreecommitdiff
path: root/libgfortran
diff options
context:
space:
mode:
authorjvdelisle <jvdelisle@138bc75d-0d04-0410-961f-82ee72b054a4>2007-01-06 00:14:38 +0000
committerjvdelisle <jvdelisle@138bc75d-0d04-0410-961f-82ee72b054a4>2007-01-06 00:14:38 +0000
commit352597f9a4ba003c51f29072865627304e4386da (patch)
treea8a46189a39b897342e7ac0bada35eb7b4ad16ee /libgfortran
parentf170d67f55d3a7c6d2025fb2d4e1e743c00cd83e (diff)
downloadgcc-352597f9a4ba003c51f29072865627304e4386da.tar.gz
2007-01-05 Jerry DeLisle <jvdelisle@gcc.gnu.org>
PR libgfortran/30162 * io/unix.c (fd_flush): Don't seek if file is not seekable, defined as s->file_length == -1. (fd_alloc_w_at): Do not adjust file_length if file is not seekable. (fd_seek): If not seekable, just return success. (fd_truncate): If not seekable, no need to truncate. Return failure if seek fails and the stream is not a pipe. (fd_to_stream): Make test for non-seekable file more robust. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@120512 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgfortran')
-rw-r--r--libgfortran/ChangeLog11
-rw-r--r--libgfortran/io/unix.c39
2 files changed, 39 insertions, 11 deletions
diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog
index 75476ca1002..5053e04e8a2 100644
--- a/libgfortran/ChangeLog
+++ b/libgfortran/ChangeLog
@@ -1,3 +1,14 @@
+2007-01-05 Jerry DeLisle <jvdelisle@gcc.gnu.org>
+
+ PR libgfortran/30162
+ * io/unix.c (fd_flush): Don't seek if file is not seekable, defined as
+ s->file_length == -1.
+ (fd_alloc_w_at): Do not adjust file_length if file is not seekable.
+ (fd_seek): If not seekable, just return success.
+ (fd_truncate): If not seekable, no need to truncate. Return failure if
+ seek fails and the stream is not a pipe.
+ (fd_to_stream): Make test for non-seekable file more robust.
+
2007-01-01 Steven G. Kargl <kargls@comcast.net>
* ChangeLog: Copied to ...
diff --git a/libgfortran/io/unix.c b/libgfortran/io/unix.c
index 57883e0f4e3..3419d72d75a 100644
--- a/libgfortran/io/unix.c
+++ b/libgfortran/io/unix.c
@@ -349,9 +349,9 @@ fd_flush (unix_stream * s)
size_t writelen;
if (s->ndirty == 0)
- return SUCCESS;;
-
- if (s->physical_offset != s->dirty_offset &&
+ return SUCCESS;
+
+ if (s->file_length != -1 && s->physical_offset != s->dirty_offset &&
lseek (s->fd, s->dirty_offset, SEEK_SET) < 0)
return FAILURE;
@@ -536,8 +536,10 @@ fd_alloc_w_at (unix_stream * s, int *len, gfc_offset where)
s->logical_offset = where + *len;
- if (where + *len > s->file_length)
- s->file_length = where + *len;
+ /* Don't increment file_length if the file is non-seekable. */
+
+ if (s->file_length != -1 && s->logical_offset > s->file_length)
+ s->file_length = s->logical_offset;
n = s->logical_offset - s->buffer_offset;
if (n > s->active)
@@ -562,6 +564,10 @@ fd_sfree (unix_stream * s)
static try
fd_seek (unix_stream * s, gfc_offset offset)
{
+
+ if (s->file_length == -1)
+ return SUCCESS;
+
if (s->physical_offset == offset) /* Are we lucky and avoid syscall? */
{
s->logical_offset = offset;
@@ -582,13 +588,19 @@ fd_seek (unix_stream * s, gfc_offset offset)
static try
fd_truncate (unix_stream * s)
{
+ /* Non-seekable files, like terminals and fifo's fail the lseek so just
+ return success, there is nothing to truncate. If its not a pipe there
+ is a real problem. */
if (lseek (s->fd, s->logical_offset, SEEK_SET) == -1)
- return FAILURE;
+ {
+ if (errno == ESPIPE)
+ return SUCCESS;
+ else
+ return FAILURE;
+ }
- /* non-seekable files, like terminals and fifo's fail the lseek.
- Using ftruncate on a seekable special file (like /dev/null)
- is undefined, so we treat it as if the ftruncate succeeded.
- */
+ /* Using ftruncate on a seekable special file (like /dev/null)
+ is undefined, so we treat it as if the ftruncate succeeded. */
#ifdef HAVE_FTRUNCATE
if (s->special_file || ftruncate (s->fd, s->logical_offset))
#else
@@ -1009,7 +1021,12 @@ fd_to_stream (int fd, int prot)
/* Get the current length of the file. */
fstat (fd, &statbuf);
- s->file_length = S_ISREG (statbuf.st_mode) ? statbuf.st_size : -1;
+
+ if (lseek (fd, 0, SEEK_CUR) == (off_t) -1)
+ s->file_length = -1;
+ else
+ s->file_length = S_ISREG (statbuf.st_mode) ? statbuf.st_size : -1;
+
s->special_file = !S_ISREG (statbuf.st_mode);
fd_open (s);