diff options
author | jvdelisle <jvdelisle@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-01-06 00:14:38 +0000 |
---|---|---|
committer | jvdelisle <jvdelisle@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-01-06 00:14:38 +0000 |
commit | 352597f9a4ba003c51f29072865627304e4386da (patch) | |
tree | a8a46189a39b897342e7ac0bada35eb7b4ad16ee /libgfortran | |
parent | f170d67f55d3a7c6d2025fb2d4e1e743c00cd83e (diff) | |
download | gcc-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/ChangeLog | 11 | ||||
-rw-r--r-- | libgfortran/io/unix.c | 39 |
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); |