summaryrefslogtreecommitdiff
path: root/libgfortran
diff options
context:
space:
mode:
Diffstat (limited to 'libgfortran')
-rw-r--r--libgfortran/ChangeLog12
-rw-r--r--libgfortran/io/file_pos.c19
-rw-r--r--libgfortran/io/io.h6
-rw-r--r--libgfortran/io/open.c22
-rw-r--r--libgfortran/io/transfer.c8
-rw-r--r--libgfortran/io/unix.c13
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)
{