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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@123038
138bc75d-0d04-0410-961f-
82ee72b054a4
+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.
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;
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);
/* 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);
{ 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. */
u->current_record = 0;
u->last_record = 0;
-
- test_endfile (u); /* We might be at the end. */
break;
case POSITION_APPEND:
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;
break;
}
-
- if (dtp->u.p.current_unit->flags.access == ACCESS_SEQUENTIAL)
- test_endfile (dtp->u.p.current_unit);
}
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)
/* 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;
}
* 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)
{