diff options
Diffstat (limited to 'libgfortran')
-rw-r--r-- | libgfortran/ChangeLog | 12 | ||||
-rw-r--r-- | libgfortran/io/file_pos.c | 19 | ||||
-rw-r--r-- | libgfortran/io/io.h | 6 | ||||
-rw-r--r-- | libgfortran/io/open.c | 22 | ||||
-rw-r--r-- | libgfortran/io/transfer.c | 8 | ||||
-rw-r--r-- | libgfortran/io/unix.c | 13 |
6 files changed, 43 insertions, 37 deletions
diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index 4000a3413ec..6512c687d84 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,15 @@ +2007-03-18 Jerry DeLisle <jvdelisle@gcc.gnu.org> + + PR libgfortran/31052 + * io/file_position (st_rewind): Fix comments. Remove use of + test_endfile. Don't seek if already at 0 position. Use new is_special + function to set endfile state. + * io/open.c (test_endfile): Delete this function. + * io/io.h: Delete prototype for test_endfile. Add prototype + for is_special. + * io/unix.c (is_special): New function. Fix whitespace. + * io/transfer.c (next_record_r): Remove use of test_endfile. + 2007-03-16 David Edelsohn <edelsohn@gnu.org> * runtime/main.c: Include "config.h" first. diff --git a/libgfortran/io/file_pos.c b/libgfortran/io/file_pos.c index 95f7d87c6fc..085921b04cc 100644 --- a/libgfortran/io/file_pos.c +++ b/libgfortran/io/file_pos.c @@ -306,14 +306,27 @@ st_rewind (st_parameter_filepos *fpp) u->mode = READING; u->last_record = 0; - if (sseek (u->s, 0) == FAILURE) + + if (file_position (u->s) != 0 && sseek (u->s, 0) == FAILURE) generate_error (&fpp->common, ERROR_OS, NULL); - u->endfile = NO_ENDFILE; + /* Handle special files like /dev/null differently. */ + if (!is_special (u->s)) + { + /* We are rewinding so we are not at the end. */ + u->endfile = NO_ENDFILE; + } + else + { + /* Set this for compatibilty with g77 for /dev/null. */ + if (file_length (u->s) == 0 && file_position (u->s) == 0) + u->endfile = AT_ENDFILE; + /* Future refinements on special files can go here. */ + } + u->current_record = 0; u->strm_pos = 1; u->read_bad = 0; - test_endfile (u); } /* Update position for INQUIRE. */ u->flags.position = POSITION_REWIND; diff --git a/libgfortran/io/io.h b/libgfortran/io/io.h index 8d8d592d40b..3ec9506abda 100644 --- a/libgfortran/io/io.h +++ b/libgfortran/io/io.h @@ -622,6 +622,9 @@ internal_proto(file_position); extern int is_seekable (stream *); internal_proto(is_seekable); +extern int is_special (stream *); +internal_proto(is_special); + extern int is_preconnected (stream *); internal_proto(is_preconnected); @@ -691,9 +694,6 @@ internal_proto(unlock_unit); /* open.c */ -extern void test_endfile (gfc_unit *); -internal_proto(test_endfile); - extern gfc_unit *new_unit (st_parameter_open *, gfc_unit *, unit_flags *); internal_proto(new_unit); diff --git a/libgfortran/io/open.c b/libgfortran/io/open.c index 783c5e84503..d22663d9d05 100644 --- a/libgfortran/io/open.c +++ b/libgfortran/io/open.c @@ -109,19 +109,6 @@ static const st_option convert_opt[] = { NULL, 0} }; -/* Given a unit, test to see if the file is positioned at the terminal - point, and if so, change state from NO_ENDFILE flag to AT_ENDFILE. - This prevents us from changing the state from AFTER_ENDFILE to - AT_ENDFILE. */ - -void -test_endfile (gfc_unit * u) -{ - if (u->endfile == NO_ENDFILE && file_length (u->s) == file_position (u->s)) - u->endfile = AT_ENDFILE; -} - - /* Change the modes of a file, those that are allowed * to be changed. */ @@ -208,8 +195,6 @@ edit_modes (st_parameter_open *opp, gfc_unit * u, unit_flags * flags) u->current_record = 0; u->last_record = 0; - - test_endfile (u); /* We might be at the end. */ break; case POSITION_APPEND: @@ -486,13 +471,6 @@ new_unit (st_parameter_open *opp, gfc_unit *u, unit_flags * flags) memmove (u->file, opp->file, opp->file_len); u->file_len = opp->file_len; - /* Curiously, the standard requires that the - position specifier be ignored for new files so a newly connected - file starts out that the initial point. We still need to figure - out if the file is at the end or not. */ - - test_endfile (u); - if (flags->status == STATUS_SCRATCH && opp->file != NULL) free_mem (opp->file); return u; diff --git a/libgfortran/io/transfer.c b/libgfortran/io/transfer.c index 2c1558e6b06..efa788cda52 100644 --- a/libgfortran/io/transfer.c +++ b/libgfortran/io/transfer.c @@ -2222,9 +2222,6 @@ next_record_r (st_parameter_dt *dtp) break; } - - if (dtp->u.p.current_unit->flags.access == ACCESS_SEQUENTIAL) - test_endfile (dtp->u.p.current_unit); } @@ -2684,10 +2681,7 @@ st_read (st_parameter_dt *dtp) data_transfer_init (dtp, 1); - /* Handle complications dealing with the endfile record. It is - significant that this is the only place where ERROR_END is - generated. Reading an end of file elsewhere is either end of - record or an I/O error. */ + /* Handle complications dealing with the endfile record. */ if (dtp->u.p.current_unit->flags.access == ACCESS_SEQUENTIAL) switch (dtp->u.p.current_unit->endfile) diff --git a/libgfortran/io/unix.c b/libgfortran/io/unix.c index b58df51ae36..4b9d87f4ee8 100644 --- a/libgfortran/io/unix.c +++ b/libgfortran/io/unix.c @@ -1872,7 +1872,7 @@ file_length (stream * s) /* file_position()-- Return the current position of the file */ gfc_offset -file_position (stream * s) +file_position (stream *s) { return ((unix_stream *) s)->logical_offset; } @@ -1882,13 +1882,22 @@ file_position (stream * s) * it is not */ int -is_seekable (stream * s) +is_seekable (stream *s) { /* By convention, if file_length == -1, the file is not seekable. */ return ((unix_stream *) s)->file_length!=-1; } + +/* is_special()-- Return nonzero if the stream is not a regular file. */ + +is_special (stream *s) +{ + return ((unix_stream *) s)->special_file; +} + + try flush (stream *s) { |