OSDN Git Service

Simplify handling of special files.
authorjb <jb@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 31 Oct 2011 14:45:50 +0000 (14:45 +0000)
committerjb <jb@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 31 Oct 2011 14:45:50 +0000 (14:45 +0000)
2011-10-31  Janne Blomqvist  <jb@gcc.gnu.org>

* io/file_pos.c (st_rewind): Handle regular and special files
identically.
* io/intrinsics.c (fseek_sub): Don't check whether we think the
file is seekable, just do what the caller says.
* io/transfer.c (skip_record): First try to seek, then fallback to
reading and throwing away what we read.
* io/unit.c (update_position): Don't check whether file is
seekable, just try to do what we're told.
(unit_truncate): Likewise.
* io/unix.c (struct unix_stream): Remove special_file flag.
(buf_flush): Remove code for handling unseekable files.
(buf_seek): Likewise.
(fd_to_stream): Use buffered IO only for regular files.
(file_length): Remove is_seekable() call.
(is_seekable): Remove function.
(is_special): Likewise.
* io/unix.h: Remove prototypes for is_seekable and is_special.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@180701 138bc75d-0d04-0410-961f-82ee72b054a4

libgfortran/ChangeLog
libgfortran/io/file_pos.c
libgfortran/io/intrinsics.c
libgfortran/io/transfer.c
libgfortran/io/unit.c
libgfortran/io/unix.c
libgfortran/io/unix.h

index 4546c27..35d398c 100644 (file)
@@ -1,3 +1,23 @@
+2011-10-31  Janne Blomqvist  <jb@gcc.gnu.org>
+
+       * io/file_pos.c (st_rewind): Handle regular and special files
+       identically.
+       * io/intrinsics.c (fseek_sub): Don't check whether we think the
+       file is seekable, just do what the caller says.
+       * io/transfer.c (skip_record): First try to seek, then fallback to
+       reading and throwing away what we read.
+       * io/unit.c (update_position): Don't check whether file is
+       seekable, just try to do what we're told.
+       (unit_truncate): Likewise.
+       * io/unix.c (struct unix_stream): Remove special_file flag.
+       (buf_flush): Remove code for handling unseekable files.
+       (buf_seek): Likewise.
+       (fd_to_stream): Use buffered IO only for regular files.
+       (file_length): Remove is_seekable() call.
+       (is_seekable): Remove function.
+       (is_special): Likewise.
+       * io/unix.h: Remove prototypes for is_seekable and is_special.
+
 2011-09-10  Thomas Koenig  <tkoenig@gcc.gnu.org>
 
        PR fortran/49479
index b034f38..2caf601 100644 (file)
@@ -407,20 +407,15 @@ st_rewind (st_parameter_filepos *fpp)
          if (sseek (u->s, 0, SEEK_SET) < 0)
            generate_error (&fpp->common, LIBERROR_OS, NULL);
 
-         /* Handle special files like /dev/null differently.  */
-         if (!is_special (u->s))
+         /* Set this for compatibilty with g77 for /dev/null.  */
+         if (file_length (u->s) == 0)
+           u->endfile = AT_ENDFILE;
+         else
            {
              /* 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  && stell (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;
index f48bd77..c1287d4 100644 (file)
@@ -246,7 +246,7 @@ fseek_sub (int * unit, GFC_IO_INT * offset, int * whence, int * status)
   gfc_unit * u = find_unit (*unit);
   ssize_t result = -1;
 
-  if (u != NULL && is_seekable(u->s))
+  if (u != NULL)
     {
       result = sseek(u->s, *offset, *whence);
 
index 12aca97..1e054f8 100644 (file)
@@ -2823,18 +2823,12 @@ skip_record (st_parameter_dt *dtp, ssize_t bytes)
   if (dtp->u.p.current_unit->bytes_left_subrecord == 0)
     return;
 
-  if (is_seekable (dtp->u.p.current_unit->s))
+  /* Direct access files do not generate END conditions,
+     only I/O errors.  */
+  if (sseek (dtp->u.p.current_unit->s, 
+            dtp->u.p.current_unit->bytes_left_subrecord, SEEK_CUR) < 0)
     {
-      /* Direct access files do not generate END conditions,
-        only I/O errors.  */
-      if (sseek (dtp->u.p.current_unit->s, 
-                dtp->u.p.current_unit->bytes_left_subrecord, SEEK_CUR) < 0)
-       generate_error (&dtp->common, LIBERROR_OS, NULL);
-
-      dtp->u.p.current_unit->bytes_left_subrecord = 0;
-    }
-  else
-    {                  /* Seek by reading data.  */
+      /* Seeking failed, fall back to seeking by reading data.  */
       while (dtp->u.p.current_unit->bytes_left_subrecord > 0)
        {
          rlength = 
@@ -2850,8 +2844,9 @@ skip_record (st_parameter_dt *dtp, ssize_t bytes)
 
          dtp->u.p.current_unit->bytes_left_subrecord -= readb;
        }
+      return;
     }
-
+  dtp->u.p.current_unit->bytes_left_subrecord = 0;
 }
 
 
index e8a9b84..d2fb6d0 100644 (file)
@@ -714,23 +714,21 @@ update_position (gfc_unit *u)
   /* If unit is not seekable, this makes no sense (and the standard is
      silent on this matter), and thus we don't change the position for
      a non-seekable file.  */
-  if (is_seekable (u->s))
-    {
-      gfc_offset cur = stell (u->s);
-      if (cur == 0)
-       u->flags.position = POSITION_REWIND;
-      else if (cur != -1 && (file_length (u->s) == cur))
-       u->flags.position = POSITION_APPEND;
-      else
-       u->flags.position = POSITION_ASIS;
-    }
+  gfc_offset cur = stell (u->s);
+  if (cur == -1)
+    return;
+  else if (cur == 0)
+    u->flags.position = POSITION_REWIND;
+  else if (file_length (u->s) == cur)
+    u->flags.position = POSITION_APPEND;
+  else
+    u->flags.position = POSITION_ASIS;
 }
 
 
-/* High level interface to truncate a file safely, i.e. flush format
-   buffers, check that it's a regular file, and generate error if that
-   occurs.  Just like POSIX ftruncate, returns 0 on success, -1 on
-   failure.  */
+/* High level interface to truncate a file, i.e. flush format buffers,
+   and generate an error or set some flags.  Just like POSIX
+   ftruncate, returns 0 on success, -1 on failure.  */
 
 int
 unit_truncate (gfc_unit * u, gfc_offset pos, st_parameter_common * common)
@@ -746,24 +744,12 @@ unit_truncate (gfc_unit * u, gfc_offset pos, st_parameter_common * common)
        fbuf_flush (u, u->mode);
     }
   
-  /* Don't try to truncate a special file, just pretend that it
-     succeeds.  */
-  if (is_special (u->s) || !is_seekable (u->s))
-    {
-      sflush (u->s);
-      return 0;
-    }
-
   /* struncate() should flush the stream buffer if necessary, so don't
      bother calling sflush() here.  */
   ret = struncate (u->s, pos);
 
   if (ret != 0)
-    {
-      generate_error (common, LIBERROR_OS, NULL);
-      u->endfile = NO_ENDFILE;
-      u->flags.position = POSITION_ASIS;
-    }
+    generate_error (common, LIBERROR_OS, NULL);
   else
     {
       u->endfile = AT_ENDFILE;
index 25cb559..00f7c72 100644 (file)
@@ -187,7 +187,7 @@ typedef struct
   gfc_offset buffer_offset;    /* File offset of the start of the buffer */
   gfc_offset physical_offset;  /* Current physical file offset */
   gfc_offset logical_offset;   /* Current logical file offset */
-  gfc_offset file_length;      /* Length of the file, -1 if not seekable. */
+  gfc_offset file_length;      /* Length of the file. */
 
   char *buffer;                 /* Pointer to the buffer.  */
   int fd;                       /* The POSIX file descriptor.  */
@@ -196,8 +196,6 @@ typedef struct
 
   int ndirty;                  /* Dirty bytes starting at buffer_offset */
 
-  int special_file;             /* =1 if the fd refers to a special file */
-
   /* Cached stat(2) values.  */
   dev_t st_dev;
   ino_t st_ino;
@@ -413,7 +411,7 @@ raw_init (unix_stream * s)
 Buffered I/O functions. These functions have the same semantics as the
 raw I/O functions above, except that they are buffered in order to
 improve performance. The buffer must be flushed when switching from
-reading to writing and vice versa.
+reading to writing and vice versa. Only supported for regular files.
 *********************************************************************/
 
 static int
@@ -427,7 +425,7 @@ buf_flush (unix_stream * s)
   if (s->ndirty == 0)
     return 0;
   
-  if (s->file_length != -1 && s->physical_offset != s->buffer_offset
+  if (s->physical_offset != s->buffer_offset
       && lseek (s->fd, s->buffer_offset, SEEK_SET) < 0)
     return -1;
 
@@ -435,8 +433,7 @@ buf_flush (unix_stream * s)
 
   s->physical_offset = s->buffer_offset + writelen;
 
-  /* Don't increment file_length if the file is non-seekable.  */
-  if (s->file_length != -1 && s->physical_offset > s->file_length)
+  if (s->physical_offset > s->file_length)
       s->file_length = s->physical_offset;
 
   s->ndirty -= writelen;
@@ -481,7 +478,7 @@ buf_read (unix_stream * s, void * buf, ssize_t nbyte)
       /* At this point we consider all bytes in the buffer discarded.  */
       to_read = nbyte - nread;
       new_logical = s->logical_offset + nread;
-      if (s->file_length != -1 && s->physical_offset != new_logical
+      if (s->physical_offset != new_logical
           && lseek (s->fd, new_logical, SEEK_SET) < 0)
         return -1;
       s->buffer_offset = s->physical_offset = new_logical;
@@ -539,7 +536,7 @@ buf_write (unix_stream * s, const void * buf, ssize_t nbyte)
         }
       else
        {
-         if (s->file_length != -1 && s->physical_offset != s->logical_offset)
+         if (s->physical_offset != s->logical_offset)
            {
              if (lseek (s->fd, s->logical_offset, SEEK_SET) < 0)
                return -1;
@@ -551,8 +548,7 @@ buf_write (unix_stream * s, const void * buf, ssize_t nbyte)
        }
     }
   s->logical_offset += nbyte;
-  /* Don't increment file_length if the file is non-seekable.  */
-  if (s->file_length != -1 && s->logical_offset > s->file_length)
+  if (s->logical_offset > s->file_length)
     s->file_length = s->logical_offset;
   return nbyte;
 }
@@ -560,11 +556,6 @@ buf_write (unix_stream * s, const void * buf, ssize_t nbyte)
 static gfc_offset
 buf_seek (unix_stream * s, gfc_offset offset, int whence)
 {
-  if (s->file_length == -1)
-    {
-      errno = ESPIPE;
-      return -1;
-    }
   switch (whence)
     {
     case SEEK_SET:
@@ -953,30 +944,18 @@ fd_to_stream (int fd)
 
   s->st_dev = statbuf.st_dev;
   s->st_ino = statbuf.st_ino;
-  s->special_file = !S_ISREG (statbuf.st_mode);
-
-  if (S_ISREG (statbuf.st_mode))
-    s->file_length = statbuf.st_size;
+  s->file_length = statbuf.st_size;
+
+  /* Only use buffered IO for regular files.  */
+  if (S_ISREG (statbuf.st_mode)
+      && !options.all_unbuffered
+      && !(options.unbuffered_preconnected && 
+          (s->fd == STDIN_FILENO 
+           || s->fd == STDOUT_FILENO 
+           || s->fd == STDERR_FILENO)))
+    buf_init (s);
   else
-    {
-      /* Some character special files are seekable but most are not,
-        so figure it out by trying to seek.  On Linux, /dev/null is
-        an example of such a special file.  */
-      s->file_length = lseek (fd, 0, SEEK_END);
-      if (s->file_length > 0)
-       lseek (fd, 0, SEEK_SET);
-    }
-
-  if (!(S_ISREG (statbuf.st_mode) || S_ISBLK (statbuf.st_mode))
-      || options.all_unbuffered
-      ||(options.unbuffered_preconnected && 
-         (s->fd == STDIN_FILENO 
-          || s->fd == STDOUT_FILENO 
-          || s->fd == STDERR_FILENO))
-      || isatty (s->fd))
     raw_init (s);
-  else
-    buf_init (s);
 
   return (stream *) s;
 }
@@ -1767,8 +1746,6 @@ gfc_offset
 file_length (stream * s)
 {
   gfc_offset curr, end;
-  if (!is_seekable (s))
-    return -1;
   curr = stell (s);
   if (curr == -1)
     return curr;
@@ -1778,27 +1755,6 @@ file_length (stream * s)
 }
 
 
-/* is_seekable()-- Return nonzero if the stream is seekable, zero if
- * it is not */
-
-int
-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.  */
-
-int
-is_special (stream *s)
-{
-  return ((unix_stream *) s)->special_file;
-}
-
-
 int
 stream_isatty (stream *s)
 {
index f7d6f08..08c83e4 100644 (file)
@@ -158,12 +158,6 @@ internal_proto(inquire_readwrite);
 extern gfc_offset file_length (stream *);
 internal_proto(file_length);
 
-extern int is_seekable (stream *);
-internal_proto(is_seekable);
-
-extern int is_special (stream *);
-internal_proto(is_special);
-
 extern void flush_if_preconnected (stream *);
 internal_proto(flush_if_preconnected);