Home | History | Annotate | Line # | Download | only in io
unix.c revision 1.1.1.1
      1 /* Copyright (C) 2002-2019 Free Software Foundation, Inc.
      2    Contributed by Andy Vaught
      3    F2003 I/O support contributed by Jerry DeLisle
      4 
      5 This file is part of the GNU Fortran runtime library (libgfortran).
      6 
      7 Libgfortran is free software; you can redistribute it and/or modify
      8 it under the terms of the GNU General Public License as published by
      9 the Free Software Foundation; either version 3, or (at your option)
     10 any later version.
     11 
     12 Libgfortran is distributed in the hope that it will be useful,
     13 but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 GNU General Public License for more details.
     16 
     17 Under Section 7 of GPL version 3, you are granted additional
     18 permissions described in the GCC Runtime Library Exception, version
     19 3.1, as published by the Free Software Foundation.
     20 
     21 You should have received a copy of the GNU General Public License and
     22 a copy of the GCC Runtime Library Exception along with this program;
     23 see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     24 <http://www.gnu.org/licenses/>.  */
     25 
     26 /* Unix stream I/O module */
     27 
     28 #include "io.h"
     29 #include "unix.h"
     30 #include "async.h"
     31 #include <limits.h>
     32 
     33 #ifdef HAVE_UNISTD_H
     34 #include <unistd.h>
     35 #endif
     36 
     37 #include <sys/stat.h>
     38 #include <fcntl.h>
     39 
     40 #include <string.h>
     41 #include <errno.h>
     42 
     43 
     44 /* For mingw, we don't identify files by their inode number, but by a
     45    64-bit identifier created from a BY_HANDLE_FILE_INFORMATION. */
     46 #ifdef __MINGW32__
     47 
     48 #define WIN32_LEAN_AND_MEAN
     49 #include <windows.h>
     50 
     51 #if !defined(_FILE_OFFSET_BITS) || _FILE_OFFSET_BITS != 64
     52 #undef lseek
     53 #define lseek _lseeki64
     54 #undef fstat
     55 #define fstat _fstati64
     56 #undef stat
     57 #define stat _stati64
     58 #endif
     59 
     60 #ifndef HAVE_WORKING_STAT
     61 static uint64_t
     62 id_from_handle (HANDLE hFile)
     63 {
     64   BY_HANDLE_FILE_INFORMATION FileInformation;
     65 
     66   if (hFile == INVALID_HANDLE_VALUE)
     67       return 0;
     68 
     69   memset (&FileInformation, 0, sizeof(FileInformation));
     70   if (!GetFileInformationByHandle (hFile, &FileInformation))
     71     return 0;
     72 
     73   return ((uint64_t) FileInformation.nFileIndexLow)
     74 	 | (((uint64_t) FileInformation.nFileIndexHigh) << 32);
     75 }
     76 
     77 
     78 static uint64_t
     79 id_from_path (const char *path)
     80 {
     81   HANDLE hFile;
     82   uint64_t res;
     83 
     84   if (!path || !*path || access (path, F_OK))
     85     return (uint64_t) -1;
     86 
     87   hFile = CreateFile (path, 0, 0, NULL, OPEN_EXISTING,
     88 		      FILE_FLAG_BACKUP_SEMANTICS | FILE_ATTRIBUTE_READONLY,
     89 		      NULL);
     90   res = id_from_handle (hFile);
     91   CloseHandle (hFile);
     92   return res;
     93 }
     94 
     95 
     96 static uint64_t
     97 id_from_fd (const int fd)
     98 {
     99   return id_from_handle ((HANDLE) _get_osfhandle (fd));
    100 }
    101 
    102 #endif /* HAVE_WORKING_STAT */
    103 
    104 
    105 /* On mingw, we don't use umask in tempfile_open(), because it
    106    doesn't support the user/group/other-based permissions.  */
    107 #undef HAVE_UMASK
    108 
    109 #endif /* __MINGW32__ */
    110 
    111 
    112 /* These flags aren't defined on all targets (mingw32), so provide them
    113    here.  */
    114 #ifndef S_IRGRP
    115 #define S_IRGRP 0
    116 #endif
    117 
    118 #ifndef S_IWGRP
    119 #define S_IWGRP 0
    120 #endif
    121 
    122 #ifndef S_IROTH
    123 #define S_IROTH 0
    124 #endif
    125 
    126 #ifndef S_IWOTH
    127 #define S_IWOTH 0
    128 #endif
    129 
    130 
    131 #ifndef HAVE_ACCESS
    132 
    133 #ifndef W_OK
    134 #define W_OK 2
    135 #endif
    136 
    137 #ifndef R_OK
    138 #define R_OK 4
    139 #endif
    140 
    141 #ifndef F_OK
    142 #define F_OK 0
    143 #endif
    144 
    145 /* Fallback implementation of access() on systems that don't have it.
    146    Only modes R_OK, W_OK and F_OK are used in this file.  */
    147 
    148 static int
    149 fallback_access (const char *path, int mode)
    150 {
    151   int fd;
    152 
    153   if (mode & R_OK)
    154     {
    155       if ((fd = open (path, O_RDONLY)) < 0)
    156 	return -1;
    157       else
    158 	close (fd);
    159     }
    160 
    161   if (mode & W_OK)
    162     {
    163       if ((fd = open (path, O_WRONLY)) < 0)
    164 	return -1;
    165       else
    166 	close (fd);
    167     }
    168 
    169   if (mode == F_OK)
    170     {
    171       struct stat st;
    172       return stat (path, &st);
    173     }
    174 
    175   return 0;
    176 }
    177 
    178 #undef access
    179 #define access fallback_access
    180 #endif
    181 
    182 
    183 /* Fallback directory for creating temporary files.  P_tmpdir is
    184    defined on many POSIX platforms.  */
    185 #ifndef P_tmpdir
    186 #ifdef _P_tmpdir
    187 #define P_tmpdir _P_tmpdir  /* MinGW */
    188 #else
    189 #define P_tmpdir "/tmp"
    190 #endif
    191 #endif
    192 
    193 
    194 /* Unix and internal stream I/O module */
    195 
    196 static const int FORMATTED_BUFFER_SIZE_DEFAULT = 8192;
    197 static const int UNFORMATTED_BUFFER_SIZE_DEFAULT = 128*1024;
    198 
    199 typedef struct
    200 {
    201   stream st;
    202 
    203   gfc_offset buffer_offset;	/* File offset of the start of the buffer */
    204   gfc_offset physical_offset;	/* Current physical file offset */
    205   gfc_offset logical_offset;	/* Current logical file offset */
    206   gfc_offset file_length;	/* Length of the file. */
    207 
    208   char *buffer;                 /* Pointer to the buffer.  */
    209   ssize_t buffer_size;           /* Length of the buffer.  */
    210   int fd;                       /* The POSIX file descriptor.  */
    211 
    212   int active;			/* Length of valid bytes in the buffer */
    213 
    214   int ndirty;			/* Dirty bytes starting at buffer_offset */
    215 
    216   /* Cached stat(2) values.  */
    217   dev_t st_dev;
    218   ino_t st_ino;
    219 
    220   bool unbuffered;  /* Buffer should be flushed after each I/O statement.  */
    221 }
    222 unix_stream;
    223 
    224 
    225 /* fix_fd()-- Given a file descriptor, make sure it is not one of the
    226    standard descriptors, returning a non-standard descriptor.  If the
    227    user specifies that system errors should go to standard output,
    228    then closes standard output, we don't want the system errors to a
    229    file that has been given file descriptor 1 or 0.  We want to send
    230    the error to the invalid descriptor. */
    231 
    232 static int
    233 fix_fd (int fd)
    234 {
    235 #ifdef HAVE_DUP
    236   int input, output, error;
    237 
    238   input = output = error = 0;
    239 
    240   /* Unix allocates the lowest descriptors first, so a loop is not
    241      required, but this order is. */
    242   if (fd == STDIN_FILENO)
    243     {
    244       fd = dup (fd);
    245       input = 1;
    246     }
    247   if (fd == STDOUT_FILENO)
    248     {
    249       fd = dup (fd);
    250       output = 1;
    251     }
    252   if (fd == STDERR_FILENO)
    253     {
    254       fd = dup (fd);
    255       error = 1;
    256     }
    257 
    258   if (input)
    259     close (STDIN_FILENO);
    260   if (output)
    261     close (STDOUT_FILENO);
    262   if (error)
    263     close (STDERR_FILENO);
    264 #endif
    265 
    266   return fd;
    267 }
    268 
    269 
    270 /* If the stream corresponds to a preconnected unit, we flush the
    271    corresponding C stream.  This is bugware for mixed C-Fortran codes
    272    where the C code doesn't flush I/O before returning.  */
    273 void
    274 flush_if_preconnected (stream *s)
    275 {
    276   int fd;
    277 
    278   fd = ((unix_stream *) s)->fd;
    279   if (fd == STDIN_FILENO)
    280     fflush (stdin);
    281   else if (fd == STDOUT_FILENO)
    282     fflush (stdout);
    283   else if (fd == STDERR_FILENO)
    284     fflush (stderr);
    285 }
    286 
    287 
    288 /********************************************************************
    289 Raw I/O functions (read, write, seek, tell, truncate, close).
    290 
    291 These functions wrap the basic POSIX I/O syscalls. Any deviation in
    292 semantics is a bug, except the following: write restarts in case
    293 of being interrupted by a signal, and as the first argument the
    294 functions take the unix_stream struct rather than an integer file
    295 descriptor. Also, for POSIX read() and write() a nbyte argument larger
    296 than SSIZE_MAX is undefined; here the type of nbyte is ssize_t rather
    297 than size_t as for POSIX read/write.
    298 *********************************************************************/
    299 
    300 static int
    301 raw_flush (unix_stream *s  __attribute__ ((unused)))
    302 {
    303   return 0;
    304 }
    305 
    306 /* Write/read at most 2 GB - 4k chunks at a time. Linux never reads or
    307    writes more than this, and there are reports that macOS fails for
    308    larger than 2 GB as well.  */
    309 #define MAX_CHUNK 2147479552
    310 
    311 static ssize_t
    312 raw_read (unix_stream *s, void *buf, ssize_t nbyte)
    313 {
    314   /* For read we can't do I/O in a loop like raw_write does, because
    315      that will break applications that wait for interactive I/O.  We
    316      still can loop around EINTR, though.  This however causes a
    317      problem for large reads which must be chunked, see comment above.
    318      So assume that if the size is larger than the chunk size, we're
    319      reading from a file and not the terminal.  */
    320   if (nbyte <= MAX_CHUNK)
    321     {
    322       while (true)
    323 	{
    324 	  ssize_t trans = read (s->fd, buf, nbyte);
    325 	  if (trans == -1 && errno == EINTR)
    326 	    continue;
    327 	  return trans;
    328 	}
    329     }
    330   else
    331     {
    332       ssize_t bytes_left = nbyte;
    333       char *buf_st = buf;
    334       while (bytes_left > 0)
    335 	{
    336 	  ssize_t to_read = bytes_left < MAX_CHUNK ? bytes_left: MAX_CHUNK;
    337 	  ssize_t trans = read (s->fd, buf_st, to_read);
    338 	  if (trans == -1)
    339 	    {
    340 	      if (errno == EINTR)
    341 		continue;
    342 	      else
    343 		return trans;
    344 	    }
    345 	  buf_st += trans;
    346 	  bytes_left -= trans;
    347 	}
    348       return nbyte - bytes_left;
    349     }
    350 }
    351 
    352 static ssize_t
    353 raw_write (unix_stream *s, const void *buf, ssize_t nbyte)
    354 {
    355   ssize_t trans, bytes_left;
    356   char *buf_st;
    357 
    358   bytes_left = nbyte;
    359   buf_st = (char *) buf;
    360 
    361   /* We must write in a loop since some systems don't restart system
    362      calls in case of a signal.  Also some systems might fail outright
    363      if we try to write more than 2 GB in a single syscall, so chunk
    364      up large writes.  */
    365   while (bytes_left > 0)
    366     {
    367       ssize_t to_write = bytes_left < MAX_CHUNK ? bytes_left: MAX_CHUNK;
    368       trans = write (s->fd, buf_st, to_write);
    369       if (trans == -1)
    370 	{
    371 	  if (errno == EINTR)
    372 	    continue;
    373 	  else
    374 	    return trans;
    375 	}
    376       buf_st += trans;
    377       bytes_left -= trans;
    378     }
    379 
    380   return nbyte - bytes_left;
    381 }
    382 
    383 static gfc_offset
    384 raw_seek (unix_stream *s, gfc_offset offset, int whence)
    385 {
    386   while (true)
    387     {
    388       gfc_offset off = lseek (s->fd, offset, whence);
    389       if (off == (gfc_offset) -1 && errno == EINTR)
    390 	continue;
    391       return off;
    392     }
    393 }
    394 
    395 static gfc_offset
    396 raw_tell (unix_stream *s)
    397 {
    398   while (true)
    399     {
    400       gfc_offset off = lseek (s->fd, 0, SEEK_CUR);
    401       if (off == (gfc_offset) -1 && errno == EINTR)
    402 	continue;
    403       return off;
    404     }
    405 }
    406 
    407 static gfc_offset
    408 raw_size (unix_stream *s)
    409 {
    410   struct stat statbuf;
    411   if (TEMP_FAILURE_RETRY (fstat (s->fd, &statbuf)) == -1)
    412     return -1;
    413   if (S_ISREG (statbuf.st_mode))
    414     return statbuf.st_size;
    415   else
    416     return 0;
    417 }
    418 
    419 static int
    420 raw_truncate (unix_stream *s, gfc_offset length)
    421 {
    422 #ifdef __MINGW32__
    423   HANDLE h;
    424   gfc_offset cur;
    425 
    426   if (isatty (s->fd))
    427     {
    428       errno = EBADF;
    429       return -1;
    430     }
    431   h = (HANDLE) _get_osfhandle (s->fd);
    432   if (h == INVALID_HANDLE_VALUE)
    433     {
    434       errno = EBADF;
    435       return -1;
    436     }
    437   cur = lseek (s->fd, 0, SEEK_CUR);
    438   if (cur == -1)
    439     return -1;
    440   if (lseek (s->fd, length, SEEK_SET) == -1)
    441     goto error;
    442   if (!SetEndOfFile (h))
    443     {
    444       errno = EBADF;
    445       goto error;
    446     }
    447   if (lseek (s->fd, cur, SEEK_SET) == -1)
    448     return -1;
    449   return 0;
    450  error:
    451   lseek (s->fd, cur, SEEK_SET);
    452   return -1;
    453 #elif defined HAVE_FTRUNCATE
    454   if (TEMP_FAILURE_RETRY (ftruncate (s->fd, length)) == -1)
    455     return -1;
    456   return 0;
    457 #elif defined HAVE_CHSIZE
    458   return chsize (s->fd, length);
    459 #else
    460   runtime_error ("required ftruncate or chsize support not present");
    461   return -1;
    462 #endif
    463 }
    464 
    465 static int
    466 raw_close (unix_stream *s)
    467 {
    468   int retval;
    469 
    470   if (s->fd == -1)
    471     retval = -1;
    472   else if (s->fd != STDOUT_FILENO
    473       && s->fd != STDERR_FILENO
    474       && s->fd != STDIN_FILENO)
    475     {
    476       retval = close (s->fd);
    477       /* close() and EINTR is special, as the file descriptor is
    478 	 deallocated before doing anything that might cause the
    479 	 operation to be interrupted. Thus if we get EINTR the best we
    480 	 can do is ignore it and continue (otherwise if we try again
    481 	 the file descriptor may have been allocated again to some
    482 	 other file).  */
    483       if (retval == -1 && errno == EINTR)
    484 	retval = errno = 0;
    485     }
    486   else
    487     retval = 0;
    488   free (s);
    489   return retval;
    490 }
    491 
    492 static int
    493 raw_markeor (unix_stream *s __attribute__ ((unused)))
    494 {
    495   return 0;
    496 }
    497 
    498 static const struct stream_vtable raw_vtable = {
    499   .read = (void *) raw_read,
    500   .write = (void *) raw_write,
    501   .seek = (void *) raw_seek,
    502   .tell = (void *) raw_tell,
    503   .size = (void *) raw_size,
    504   .trunc = (void *) raw_truncate,
    505   .close = (void *) raw_close,
    506   .flush = (void *) raw_flush,
    507   .markeor = (void *) raw_markeor
    508 };
    509 
    510 static int
    511 raw_init (unix_stream *s)
    512 {
    513   s->st.vptr = &raw_vtable;
    514 
    515   s->buffer = NULL;
    516   return 0;
    517 }
    518 
    519 
    520 /*********************************************************************
    521 Buffered I/O functions. These functions have the same semantics as the
    522 raw I/O functions above, except that they are buffered in order to
    523 improve performance. The buffer must be flushed when switching from
    524 reading to writing and vice versa.
    525 *********************************************************************/
    526 
    527 static int
    528 buf_flush (unix_stream *s)
    529 {
    530   int writelen;
    531 
    532   /* Flushing in read mode means discarding read bytes.  */
    533   s->active = 0;
    534 
    535   if (s->ndirty == 0)
    536     return 0;
    537 
    538   if (s->physical_offset != s->buffer_offset
    539       && raw_seek (s, s->buffer_offset, SEEK_SET) < 0)
    540     return -1;
    541 
    542   writelen = raw_write (s, s->buffer, s->ndirty);
    543 
    544   s->physical_offset = s->buffer_offset + writelen;
    545 
    546   if (s->physical_offset > s->file_length)
    547       s->file_length = s->physical_offset;
    548 
    549   s->ndirty -= writelen;
    550   if (s->ndirty != 0)
    551     return -1;
    552 
    553   return 0;
    554 }
    555 
    556 static ssize_t
    557 buf_read (unix_stream *s, void *buf, ssize_t nbyte)
    558 {
    559   if (s->active == 0)
    560     s->buffer_offset = s->logical_offset;
    561 
    562   /* Is the data we want in the buffer?  */
    563   if (s->logical_offset + nbyte <= s->buffer_offset + s->active
    564       && s->buffer_offset <= s->logical_offset)
    565     {
    566       /* When nbyte == 0, buf can be NULL which would lead to undefined
    567 	 behavior if we called memcpy().  */
    568       if (nbyte != 0)
    569 	memcpy (buf, s->buffer + (s->logical_offset - s->buffer_offset),
    570 		nbyte);
    571     }
    572   else
    573     {
    574       /* First copy the active bytes if applicable, then read the rest
    575          either directly or filling the buffer.  */
    576       char *p;
    577       int nread = 0;
    578       ssize_t to_read, did_read;
    579       gfc_offset new_logical;
    580 
    581       p = (char *) buf;
    582       if (s->logical_offset >= s->buffer_offset
    583           && s->buffer_offset + s->active >= s->logical_offset)
    584         {
    585           nread = s->active - (s->logical_offset - s->buffer_offset);
    586           memcpy (buf, s->buffer + (s->logical_offset - s->buffer_offset),
    587                   nread);
    588           p += nread;
    589         }
    590       /* At this point we consider all bytes in the buffer discarded.  */
    591       to_read = nbyte - nread;
    592       new_logical = s->logical_offset + nread;
    593       if (s->physical_offset != new_logical
    594           && raw_seek (s, new_logical, SEEK_SET) < 0)
    595         return -1;
    596       s->buffer_offset = s->physical_offset = new_logical;
    597       if (to_read <= s->buffer_size/2)
    598         {
    599           did_read = raw_read (s, s->buffer, s->buffer_size);
    600 	  if (likely (did_read >= 0))
    601 	    {
    602 	      s->physical_offset += did_read;
    603 	      s->active = did_read;
    604 	      did_read = (did_read > to_read) ? to_read : did_read;
    605 	      memcpy (p, s->buffer, did_read);
    606 	    }
    607 	  else
    608 	    return did_read;
    609         }
    610       else
    611         {
    612           did_read = raw_read (s, p, to_read);
    613 	  if (likely (did_read >= 0))
    614 	    {
    615 	      s->physical_offset += did_read;
    616 	      s->active = 0;
    617 	    }
    618 	  else
    619 	    return did_read;
    620         }
    621       nbyte = did_read + nread;
    622     }
    623   s->logical_offset += nbyte;
    624   return nbyte;
    625 }
    626 
    627 static ssize_t
    628 buf_write (unix_stream *s, const void *buf, ssize_t nbyte)
    629 {
    630   if (nbyte == 0)
    631     return 0;
    632 
    633   if (s->ndirty == 0)
    634     s->buffer_offset = s->logical_offset;
    635 
    636   /* Does the data fit into the buffer?  As a special case, if the
    637      buffer is empty and the request is bigger than s->buffer_size/2,
    638      write directly. This avoids the case where the buffer would have
    639      to be flushed at every write.  */
    640   if (!(s->ndirty == 0 && nbyte > s->buffer_size/2)
    641       && s->logical_offset + nbyte <= s->buffer_offset + s->buffer_size
    642       && s->buffer_offset <= s->logical_offset
    643       && s->buffer_offset + s->ndirty >= s->logical_offset)
    644     {
    645       memcpy (s->buffer + (s->logical_offset - s->buffer_offset), buf, nbyte);
    646       int nd = (s->logical_offset - s->buffer_offset) + nbyte;
    647       if (nd > s->ndirty)
    648         s->ndirty = nd;
    649     }
    650   else
    651     {
    652       /* Flush, and either fill the buffer with the new data, or if
    653          the request is bigger than the buffer size, write directly
    654          bypassing the buffer.  */
    655       buf_flush (s);
    656       if (nbyte <= s->buffer_size/2)
    657         {
    658           memcpy (s->buffer, buf, nbyte);
    659           s->buffer_offset = s->logical_offset;
    660           s->ndirty += nbyte;
    661         }
    662       else
    663 	{
    664 	  if (s->physical_offset != s->logical_offset)
    665 	    {
    666 	      if (raw_seek (s, s->logical_offset, SEEK_SET) < 0)
    667 		return -1;
    668 	      s->physical_offset = s->logical_offset;
    669 	    }
    670 
    671 	  nbyte = raw_write (s, buf, nbyte);
    672 	  s->physical_offset += nbyte;
    673 	}
    674     }
    675   s->logical_offset += nbyte;
    676   if (s->logical_offset > s->file_length)
    677     s->file_length = s->logical_offset;
    678   return nbyte;
    679 }
    680 
    681 
    682 /* "Unbuffered" really means I/O statement buffering. For formatted
    683    I/O, the fbuf manages this, and then uses raw I/O. For unformatted
    684    I/O, buffered I/O is used, and the buffer is flushed at the end of
    685    each I/O statement, where this function is called.  Alternatively,
    686    the buffer is flushed at the end of the record if the buffer is
    687    more than half full; this prevents needless seeking back and forth
    688    when writing sequential unformatted.  */
    689 
    690 static int
    691 buf_markeor (unix_stream *s)
    692 {
    693   if (s->unbuffered || s->ndirty >= s->buffer_size / 2)
    694     return buf_flush (s);
    695   return 0;
    696 }
    697 
    698 static gfc_offset
    699 buf_seek (unix_stream *s, gfc_offset offset, int whence)
    700 {
    701   switch (whence)
    702     {
    703     case SEEK_SET:
    704       break;
    705     case SEEK_CUR:
    706       offset += s->logical_offset;
    707       break;
    708     case SEEK_END:
    709       offset += s->file_length;
    710       break;
    711     default:
    712       return -1;
    713     }
    714   if (offset < 0)
    715     {
    716       errno = EINVAL;
    717       return -1;
    718     }
    719   s->logical_offset = offset;
    720   return offset;
    721 }
    722 
    723 static gfc_offset
    724 buf_tell (unix_stream *s)
    725 {
    726   return buf_seek (s, 0, SEEK_CUR);
    727 }
    728 
    729 static gfc_offset
    730 buf_size (unix_stream *s)
    731 {
    732   return s->file_length;
    733 }
    734 
    735 static int
    736 buf_truncate (unix_stream *s, gfc_offset length)
    737 {
    738   int r;
    739 
    740   if (buf_flush (s) != 0)
    741     return -1;
    742   r = raw_truncate (s, length);
    743   if (r == 0)
    744     s->file_length = length;
    745   return r;
    746 }
    747 
    748 static int
    749 buf_close (unix_stream *s)
    750 {
    751   if (buf_flush (s) != 0)
    752     return -1;
    753   free (s->buffer);
    754   return raw_close (s);
    755 }
    756 
    757 static const struct stream_vtable buf_vtable = {
    758   .read = (void *) buf_read,
    759   .write = (void *) buf_write,
    760   .seek = (void *) buf_seek,
    761   .tell = (void *) buf_tell,
    762   .size = (void *) buf_size,
    763   .trunc = (void *) buf_truncate,
    764   .close = (void *) buf_close,
    765   .flush = (void *) buf_flush,
    766   .markeor = (void *) buf_markeor
    767 };
    768 
    769 static int
    770 buf_init (unix_stream *s, bool unformatted)
    771 {
    772   s->st.vptr = &buf_vtable;
    773 
    774   /* Try to guess a good value for the buffer size.  For formatted
    775      I/O, we use so many CPU cycles converting the data that there is
    776      more sense in converving memory and especially cache.  For
    777      unformatted, a bigger block can have a large impact in some
    778      environments.  */
    779 
    780   if (unformatted)
    781     {
    782       if (options.unformatted_buffer_size > 0)
    783 	s->buffer_size = options.unformatted_buffer_size;
    784       else
    785 	s->buffer_size = UNFORMATTED_BUFFER_SIZE_DEFAULT;
    786     }
    787   else
    788     {
    789       if (options.formatted_buffer_size > 0)
    790 	s->buffer_size = options.formatted_buffer_size;
    791       else
    792 	s->buffer_size = FORMATTED_BUFFER_SIZE_DEFAULT;
    793     }
    794 
    795   s->buffer = xmalloc (s->buffer_size);
    796   return 0;
    797 }
    798 
    799 
    800 /*********************************************************************
    801   memory stream functions - These are used for internal files
    802 
    803   The idea here is that a single stream structure is created and all
    804   requests must be satisfied from it.  The location and size of the
    805   buffer is the character variable supplied to the READ or WRITE
    806   statement.
    807 
    808 *********************************************************************/
    809 
    810 char *
    811 mem_alloc_r (stream *strm, size_t *len)
    812 {
    813   unix_stream *s = (unix_stream *) strm;
    814   gfc_offset n;
    815   gfc_offset where = s->logical_offset;
    816 
    817   if (where < s->buffer_offset || where > s->buffer_offset + s->active)
    818     return NULL;
    819 
    820   n = s->buffer_offset + s->active - where;
    821   if ((gfc_offset) *len > n)
    822     *len = n;
    823 
    824   s->logical_offset = where + *len;
    825 
    826   return s->buffer + (where - s->buffer_offset);
    827 }
    828 
    829 
    830 char *
    831 mem_alloc_r4 (stream *strm, size_t *len)
    832 {
    833   unix_stream *s = (unix_stream *) strm;
    834   gfc_offset n;
    835   gfc_offset where = s->logical_offset;
    836 
    837   if (where < s->buffer_offset || where > s->buffer_offset + s->active)
    838     return NULL;
    839 
    840   n = s->buffer_offset + s->active - where;
    841   if ((gfc_offset) *len > n)
    842     *len = n;
    843 
    844   s->logical_offset = where + *len;
    845 
    846   return s->buffer + (where - s->buffer_offset) * 4;
    847 }
    848 
    849 
    850 char *
    851 mem_alloc_w (stream *strm, size_t *len)
    852 {
    853   unix_stream *s = (unix_stream *)strm;
    854   gfc_offset m;
    855   gfc_offset where = s->logical_offset;
    856 
    857   m = where + *len;
    858 
    859   if (where < s->buffer_offset)
    860     return NULL;
    861 
    862   if (m > s->file_length)
    863     return NULL;
    864 
    865   s->logical_offset = m;
    866 
    867   return s->buffer + (where - s->buffer_offset);
    868 }
    869 
    870 
    871 gfc_char4_t *
    872 mem_alloc_w4 (stream *strm, size_t *len)
    873 {
    874   unix_stream *s = (unix_stream *)strm;
    875   gfc_offset m;
    876   gfc_offset where = s->logical_offset;
    877   gfc_char4_t *result = (gfc_char4_t *) s->buffer;
    878 
    879   m = where + *len;
    880 
    881   if (where < s->buffer_offset)
    882     return NULL;
    883 
    884   if (m > s->file_length)
    885     return NULL;
    886 
    887   s->logical_offset = m;
    888   return &result[where - s->buffer_offset];
    889 }
    890 
    891 
    892 /* Stream read function for character(kind=1) internal units.  */
    893 
    894 static ssize_t
    895 mem_read (stream *s, void *buf, ssize_t nbytes)
    896 {
    897   void *p;
    898   size_t nb = nbytes;
    899 
    900   p = mem_alloc_r (s, &nb);
    901   if (p)
    902     {
    903       memcpy (buf, p, nb);
    904       return (ssize_t) nb;
    905     }
    906   else
    907     return 0;
    908 }
    909 
    910 
    911 /* Stream read function for chracter(kind=4) internal units.  */
    912 
    913 static ssize_t
    914 mem_read4 (stream *s, void *buf, ssize_t nbytes)
    915 {
    916   void *p;
    917   size_t nb = nbytes;
    918 
    919   p = mem_alloc_r4 (s, &nb);
    920   if (p)
    921     {
    922       memcpy (buf, p, nb * 4);
    923       return (ssize_t) nb;
    924     }
    925   else
    926     return 0;
    927 }
    928 
    929 
    930 /* Stream write function for character(kind=1) internal units.  */
    931 
    932 static ssize_t
    933 mem_write (stream *s, const void *buf, ssize_t nbytes)
    934 {
    935   void *p;
    936   size_t nb = nbytes;
    937 
    938   p = mem_alloc_w (s, &nb);
    939   if (p)
    940     {
    941       memcpy (p, buf, nb);
    942       return (ssize_t) nb;
    943     }
    944   else
    945     return 0;
    946 }
    947 
    948 
    949 /* Stream write function for character(kind=4) internal units.  */
    950 
    951 static ssize_t
    952 mem_write4 (stream *s, const void *buf, ssize_t nwords)
    953 {
    954   gfc_char4_t *p;
    955   size_t nw = nwords;
    956 
    957   p = mem_alloc_w4 (s, &nw);
    958   if (p)
    959     {
    960       while (nw--)
    961 	*p++ = (gfc_char4_t) *((char *) buf);
    962       return nwords;
    963     }
    964   else
    965     return 0;
    966 }
    967 
    968 
    969 static gfc_offset
    970 mem_seek (stream *strm, gfc_offset offset, int whence)
    971 {
    972   unix_stream *s = (unix_stream *)strm;
    973   switch (whence)
    974     {
    975     case SEEK_SET:
    976       break;
    977     case SEEK_CUR:
    978       offset += s->logical_offset;
    979       break;
    980     case SEEK_END:
    981       offset += s->file_length;
    982       break;
    983     default:
    984       return -1;
    985     }
    986 
    987   /* Note that for internal array I/O it's actually possible to have a
    988      negative offset, so don't check for that.  */
    989   if (offset > s->file_length)
    990     {
    991       errno = EINVAL;
    992       return -1;
    993     }
    994 
    995   s->logical_offset = offset;
    996 
    997   /* Returning < 0 is the error indicator for sseek(), so return 0 if
    998      offset is negative.  Thus if the return value is 0, the caller
    999      has to use stell() to get the real value of logical_offset.  */
   1000   if (offset >= 0)
   1001     return offset;
   1002   return 0;
   1003 }
   1004 
   1005 
   1006 static gfc_offset
   1007 mem_tell (stream *s)
   1008 {
   1009   return ((unix_stream *)s)->logical_offset;
   1010 }
   1011 
   1012 
   1013 static int
   1014 mem_truncate (unix_stream *s __attribute__ ((unused)),
   1015 	      gfc_offset length __attribute__ ((unused)))
   1016 {
   1017   return 0;
   1018 }
   1019 
   1020 
   1021 static int
   1022 mem_flush (unix_stream *s __attribute__ ((unused)))
   1023 {
   1024   return 0;
   1025 }
   1026 
   1027 
   1028 static int
   1029 mem_close (unix_stream *s)
   1030 {
   1031   if (s)
   1032     free (s);
   1033   return 0;
   1034 }
   1035 
   1036 static const struct stream_vtable mem_vtable = {
   1037   .read = (void *) mem_read,
   1038   .write = (void *) mem_write,
   1039   .seek = (void *) mem_seek,
   1040   .tell = (void *) mem_tell,
   1041   /* buf_size is not a typo, we just reuse an identical
   1042      implementation.  */
   1043   .size = (void *) buf_size,
   1044   .trunc = (void *) mem_truncate,
   1045   .close = (void *) mem_close,
   1046   .flush = (void *) mem_flush,
   1047   .markeor = (void *) raw_markeor
   1048 };
   1049 
   1050 static const struct stream_vtable mem4_vtable = {
   1051   .read = (void *) mem_read4,
   1052   .write = (void *) mem_write4,
   1053   .seek = (void *) mem_seek,
   1054   .tell = (void *) mem_tell,
   1055   /* buf_size is not a typo, we just reuse an identical
   1056      implementation.  */
   1057   .size = (void *) buf_size,
   1058   .trunc = (void *) mem_truncate,
   1059   .close = (void *) mem_close,
   1060   .flush = (void *) mem_flush,
   1061   .markeor = (void *) raw_markeor
   1062 };
   1063 
   1064 /*********************************************************************
   1065   Public functions -- A reimplementation of this module needs to
   1066   define functional equivalents of the following.
   1067 *********************************************************************/
   1068 
   1069 /* open_internal()-- Returns a stream structure from a character(kind=1)
   1070    internal file */
   1071 
   1072 stream *
   1073 open_internal (char *base, size_t length, gfc_offset offset)
   1074 {
   1075   unix_stream *s;
   1076 
   1077   s = xcalloc (1, sizeof (unix_stream));
   1078 
   1079   s->buffer = base;
   1080   s->buffer_offset = offset;
   1081 
   1082   s->active = s->file_length = length;
   1083 
   1084   s->st.vptr = &mem_vtable;
   1085 
   1086   return (stream *) s;
   1087 }
   1088 
   1089 /* open_internal4()-- Returns a stream structure from a character(kind=4)
   1090    internal file */
   1091 
   1092 stream *
   1093 open_internal4 (char *base, size_t length, gfc_offset offset)
   1094 {
   1095   unix_stream *s;
   1096 
   1097   s = xcalloc (1, sizeof (unix_stream));
   1098 
   1099   s->buffer = base;
   1100   s->buffer_offset = offset;
   1101 
   1102   s->active = s->file_length = length * sizeof (gfc_char4_t);
   1103 
   1104   s->st.vptr = &mem4_vtable;
   1105 
   1106   return (stream *)s;
   1107 }
   1108 
   1109 
   1110 /* fd_to_stream()-- Given an open file descriptor, build a stream
   1111    around it. */
   1112 
   1113 static stream *
   1114 fd_to_stream (int fd, bool unformatted)
   1115 {
   1116   struct stat statbuf;
   1117   unix_stream *s;
   1118 
   1119   s = xcalloc (1, sizeof (unix_stream));
   1120 
   1121   s->fd = fd;
   1122 
   1123   /* Get the current length of the file. */
   1124 
   1125   if (TEMP_FAILURE_RETRY (fstat (fd, &statbuf)) == -1)
   1126     {
   1127       s->st_dev = s->st_ino = -1;
   1128       s->file_length = 0;
   1129       if (errno == EBADF)
   1130 	s->fd = -1;
   1131       raw_init (s);
   1132       return (stream *) s;
   1133     }
   1134 
   1135   s->st_dev = statbuf.st_dev;
   1136   s->st_ino = statbuf.st_ino;
   1137   s->file_length = statbuf.st_size;
   1138 
   1139   /* Only use buffered IO for regular files.  */
   1140   if (S_ISREG (statbuf.st_mode)
   1141       && !options.all_unbuffered
   1142       && !(options.unbuffered_preconnected &&
   1143 	   (s->fd == STDIN_FILENO
   1144 	    || s->fd == STDOUT_FILENO
   1145 	    || s->fd == STDERR_FILENO)))
   1146     buf_init (s, unformatted);
   1147   else
   1148     {
   1149       if (unformatted)
   1150 	{
   1151 	  s->unbuffered = true;
   1152 	  buf_init (s, unformatted);
   1153 	}
   1154       else
   1155 	raw_init (s);
   1156     }
   1157 
   1158   return (stream *) s;
   1159 }
   1160 
   1161 
   1162 /* Given the Fortran unit number, convert it to a C file descriptor.  */
   1163 
   1164 int
   1165 unit_to_fd (int unit)
   1166 {
   1167   gfc_unit *us;
   1168   int fd;
   1169 
   1170   us = find_unit (unit);
   1171   if (us == NULL)
   1172     return -1;
   1173 
   1174   fd = ((unix_stream *) us->s)->fd;
   1175   unlock_unit (us);
   1176   return fd;
   1177 }
   1178 
   1179 
   1180 /* Set the close-on-exec flag for an existing fd, if the system
   1181    supports such.  */
   1182 
   1183 static void __attribute__ ((unused))
   1184 set_close_on_exec (int fd __attribute__ ((unused)))
   1185 {
   1186   /* Mingw does not define F_SETFD.  */
   1187 #if defined(HAVE_FCNTL) && defined(F_SETFD) && defined(FD_CLOEXEC)
   1188   if (fd >= 0)
   1189     fcntl(fd, F_SETFD, FD_CLOEXEC);
   1190 #endif
   1191 }
   1192 
   1193 
   1194 /* Helper function for tempfile(). Tries to open a temporary file in
   1195    the directory specified by tempdir. If successful, the file name is
   1196    stored in fname and the descriptor returned. Returns -1 on
   1197    failure.  */
   1198 
   1199 static int
   1200 tempfile_open (const char *tempdir, char **fname)
   1201 {
   1202   int fd;
   1203   const char *slash = "/";
   1204 #if defined(HAVE_UMASK) && defined(HAVE_MKSTEMP)
   1205   mode_t mode_mask;
   1206 #endif
   1207 
   1208   if (!tempdir)
   1209     return -1;
   1210 
   1211   /* Check for the special case that tempdir ends with a slash or
   1212      backslash.  */
   1213   size_t tempdirlen = strlen (tempdir);
   1214   if (*tempdir == 0 || tempdir[tempdirlen - 1] == '/'
   1215 #ifdef __MINGW32__
   1216       || tempdir[tempdirlen - 1] == '\\'
   1217 #endif
   1218      )
   1219     slash = "";
   1220 
   1221   /* Take care that the template is longer in the mktemp() branch.  */
   1222   char *template = xmalloc (tempdirlen + 23);
   1223 
   1224 #ifdef HAVE_MKSTEMP
   1225   snprintf (template, tempdirlen + 23, "%s%sgfortrantmpXXXXXX",
   1226 	    tempdir, slash);
   1227 
   1228 #ifdef HAVE_UMASK
   1229   /* Temporarily set the umask such that the file has 0600 permissions.  */
   1230   mode_mask = umask (S_IXUSR | S_IRWXG | S_IRWXO);
   1231 #endif
   1232 
   1233 #if defined(HAVE_MKOSTEMP) && defined(O_CLOEXEC)
   1234   TEMP_FAILURE_RETRY (fd = mkostemp (template, O_CLOEXEC));
   1235 #else
   1236   TEMP_FAILURE_RETRY (fd = mkstemp (template));
   1237   set_close_on_exec (fd);
   1238 #endif
   1239 
   1240 #ifdef HAVE_UMASK
   1241   (void) umask (mode_mask);
   1242 #endif
   1243 
   1244 #else /* HAVE_MKSTEMP */
   1245   fd = -1;
   1246   int count = 0;
   1247   size_t slashlen = strlen (slash);
   1248   int flags = O_RDWR | O_CREAT | O_EXCL;
   1249 #if defined(HAVE_CRLF) && defined(O_BINARY)
   1250   flags |= O_BINARY;
   1251 #endif
   1252 #ifdef O_CLOEXEC
   1253   flags |= O_CLOEXEC;
   1254 #endif
   1255   do
   1256     {
   1257       snprintf (template, tempdirlen + 23, "%s%sgfortrantmpaaaXXXXXX",
   1258 		tempdir, slash);
   1259       if (count > 0)
   1260 	{
   1261 	  int c = count;
   1262 	  template[tempdirlen + slashlen + 13] = 'a' + (c% 26);
   1263 	  c /= 26;
   1264 	  template[tempdirlen + slashlen + 12] = 'a' + (c % 26);
   1265 	  c /= 26;
   1266 	  template[tempdirlen + slashlen + 11] = 'a' + (c % 26);
   1267 	  if (c >= 26)
   1268 	    break;
   1269 	}
   1270 
   1271       if (!mktemp (template))
   1272       {
   1273 	errno = EEXIST;
   1274 	count++;
   1275 	continue;
   1276       }
   1277 
   1278       TEMP_FAILURE_RETRY (fd = open (template, flags, S_IRUSR | S_IWUSR));
   1279     }
   1280   while (fd == -1 && errno == EEXIST);
   1281 #ifndef O_CLOEXEC
   1282   set_close_on_exec (fd);
   1283 #endif
   1284 #endif /* HAVE_MKSTEMP */
   1285 
   1286   *fname = template;
   1287   return fd;
   1288 }
   1289 
   1290 
   1291 /* tempfile()-- Generate a temporary filename for a scratch file and
   1292    open it.  mkstemp() opens the file for reading and writing, but the
   1293    library mode prevents anything that is not allowed.  The descriptor
   1294    is returned, which is -1 on error.  The template is pointed to by
   1295    opp->file, which is copied into the unit structure
   1296    and freed later. */
   1297 
   1298 static int
   1299 tempfile (st_parameter_open *opp)
   1300 {
   1301   const char *tempdir;
   1302   char *fname;
   1303   int fd = -1;
   1304 
   1305   tempdir = secure_getenv ("TMPDIR");
   1306   fd = tempfile_open (tempdir, &fname);
   1307 #ifdef __MINGW32__
   1308   if (fd == -1)
   1309     {
   1310       char buffer[MAX_PATH + 1];
   1311       DWORD ret;
   1312       ret = GetTempPath (MAX_PATH, buffer);
   1313       /* If we are not able to get a temp-directory, we use
   1314 	 current directory.  */
   1315       if (ret > MAX_PATH || !ret)
   1316         buffer[0] = 0;
   1317       else
   1318         buffer[ret] = 0;
   1319       tempdir = strdup (buffer);
   1320       fd = tempfile_open (tempdir, &fname);
   1321     }
   1322 #elif defined(__CYGWIN__)
   1323   if (fd == -1)
   1324     {
   1325       tempdir = secure_getenv ("TMP");
   1326       fd = tempfile_open (tempdir, &fname);
   1327     }
   1328   if (fd == -1)
   1329     {
   1330       tempdir = secure_getenv ("TEMP");
   1331       fd = tempfile_open (tempdir, &fname);
   1332     }
   1333 #endif
   1334   if (fd == -1)
   1335     fd = tempfile_open (P_tmpdir, &fname);
   1336 
   1337   opp->file = fname;
   1338   opp->file_len = strlen (fname);	/* Don't include trailing nul */
   1339 
   1340   return fd;
   1341 }
   1342 
   1343 
   1344 /* regular_file2()-- Open a regular file.
   1345    Change flags->action if it is ACTION_UNSPECIFIED on entry,
   1346    unless an error occurs.
   1347    Returns the descriptor, which is less than zero on error. */
   1348 
   1349 static int
   1350 regular_file2 (const char *path, st_parameter_open *opp, unit_flags *flags)
   1351 {
   1352   int mode;
   1353   int rwflag;
   1354   int crflag, crflag2;
   1355   int fd;
   1356 
   1357 #ifdef __CYGWIN__
   1358   if (opp->file_len == 7)
   1359     {
   1360       if (strncmp (path, "CONOUT$", 7) == 0
   1361 	  || strncmp (path, "CONERR$", 7) == 0)
   1362 	{
   1363 	  fd = open ("/dev/conout", O_WRONLY);
   1364 	  flags->action = ACTION_WRITE;
   1365 	  return fd;
   1366 	}
   1367     }
   1368 
   1369   if (opp->file_len == 6 && strncmp (path, "CONIN$", 6) == 0)
   1370     {
   1371       fd = open ("/dev/conin", O_RDONLY);
   1372       flags->action = ACTION_READ;
   1373       return fd;
   1374     }
   1375 #endif
   1376 
   1377 
   1378 #ifdef __MINGW32__
   1379   if (opp->file_len == 7)
   1380     {
   1381       if (strncmp (path, "CONOUT$", 7) == 0
   1382 	  || strncmp (path, "CONERR$", 7) == 0)
   1383 	{
   1384 	  fd = open ("CONOUT$", O_WRONLY);
   1385 	  flags->action = ACTION_WRITE;
   1386 	  return fd;
   1387 	}
   1388     }
   1389 
   1390   if (opp->file_len == 6 && strncmp (path, "CONIN$", 6) == 0)
   1391     {
   1392       fd = open ("CONIN$", O_RDONLY);
   1393       flags->action = ACTION_READ;
   1394       return fd;
   1395     }
   1396 #endif
   1397 
   1398   switch (flags->action)
   1399     {
   1400     case ACTION_READ:
   1401       rwflag = O_RDONLY;
   1402       break;
   1403 
   1404     case ACTION_WRITE:
   1405       rwflag = O_WRONLY;
   1406       break;
   1407 
   1408     case ACTION_READWRITE:
   1409     case ACTION_UNSPECIFIED:
   1410       rwflag = O_RDWR;
   1411       break;
   1412 
   1413     default:
   1414       internal_error (&opp->common, "regular_file(): Bad action");
   1415     }
   1416 
   1417   switch (flags->status)
   1418     {
   1419     case STATUS_NEW:
   1420       crflag = O_CREAT | O_EXCL;
   1421       break;
   1422 
   1423     case STATUS_OLD:		/* open will fail if the file does not exist*/
   1424       crflag = 0;
   1425       break;
   1426 
   1427     case STATUS_UNKNOWN:
   1428       if (rwflag == O_RDONLY)
   1429 	crflag = 0;
   1430       else
   1431 	crflag = O_CREAT;
   1432       break;
   1433 
   1434     case STATUS_REPLACE:
   1435       crflag = O_CREAT | O_TRUNC;
   1436       break;
   1437 
   1438     default:
   1439       /* Note: STATUS_SCRATCH is handled by tempfile () and should
   1440 	 never be seen here.  */
   1441       internal_error (&opp->common, "regular_file(): Bad status");
   1442     }
   1443 
   1444   /* rwflag |= O_LARGEFILE; */
   1445 
   1446 #if defined(HAVE_CRLF) && defined(O_BINARY)
   1447   crflag |= O_BINARY;
   1448 #endif
   1449 
   1450 #ifdef O_CLOEXEC
   1451   crflag |= O_CLOEXEC;
   1452 #endif
   1453 
   1454   mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
   1455   TEMP_FAILURE_RETRY (fd = open (path, rwflag | crflag, mode));
   1456   if (flags->action != ACTION_UNSPECIFIED)
   1457     return fd;
   1458 
   1459   if (fd >= 0)
   1460     {
   1461       flags->action = ACTION_READWRITE;
   1462       return fd;
   1463     }
   1464   if (errno != EACCES && errno != EPERM && errno != EROFS)
   1465      return fd;
   1466 
   1467   /* retry for read-only access */
   1468   rwflag = O_RDONLY;
   1469   if (flags->status == STATUS_UNKNOWN)
   1470     crflag2 = crflag & ~(O_CREAT);
   1471   else
   1472     crflag2 = crflag;
   1473   TEMP_FAILURE_RETRY (fd = open (path, rwflag | crflag2, mode));
   1474   if (fd >=0)
   1475     {
   1476       flags->action = ACTION_READ;
   1477       return fd;		/* success */
   1478     }
   1479 
   1480   if (errno != EACCES && errno != EPERM && errno != ENOENT)
   1481     return fd;			/* failure */
   1482 
   1483   /* retry for write-only access */
   1484   rwflag = O_WRONLY;
   1485   TEMP_FAILURE_RETRY (fd = open (path, rwflag | crflag, mode));
   1486   if (fd >=0)
   1487     {
   1488       flags->action = ACTION_WRITE;
   1489       return fd;		/* success */
   1490     }
   1491   return fd;			/* failure */
   1492 }
   1493 
   1494 
   1495 /* Lock the file, if necessary, based on SHARE flags.  */
   1496 
   1497 #if defined(HAVE_FCNTL) && defined(F_SETLK) && defined(F_UNLCK)
   1498 static int
   1499 open_share (st_parameter_open *opp, int fd, unit_flags *flags)
   1500 {
   1501   int r = 0;
   1502   struct flock f;
   1503   if (fd == STDOUT_FILENO || fd == STDERR_FILENO || fd == STDIN_FILENO)
   1504     return 0;
   1505 
   1506   f.l_start = 0;
   1507   f.l_len = 0;
   1508   f.l_whence = SEEK_SET;
   1509 
   1510   switch (flags->share)
   1511   {
   1512     case SHARE_DENYNONE:
   1513       f.l_type = F_RDLCK;
   1514       r = fcntl (fd, F_SETLK, &f);
   1515       break;
   1516     case SHARE_DENYRW:
   1517       /* Must be writable to hold write lock.  */
   1518       if (flags->action == ACTION_READ)
   1519 	{
   1520 	  generate_error (&opp->common, LIBERROR_BAD_ACTION,
   1521 	      "Cannot set write lock on file opened for READ");
   1522 	  return -1;
   1523 	}
   1524       f.l_type = F_WRLCK;
   1525       r = fcntl (fd, F_SETLK, &f);
   1526       break;
   1527     case SHARE_UNSPECIFIED:
   1528     default:
   1529       break;
   1530   }
   1531 
   1532   return r;
   1533 }
   1534 #else
   1535 static int
   1536 open_share (st_parameter_open *opp __attribute__ ((unused)),
   1537     int fd __attribute__ ((unused)),
   1538     unit_flags *flags __attribute__ ((unused)))
   1539 {
   1540   return 0;
   1541 }
   1542 #endif /* defined(HAVE_FCNTL) ... */
   1543 
   1544 
   1545 /* Wrapper around regular_file2, to make sure we free the path after
   1546    we're done.  */
   1547 
   1548 static int
   1549 regular_file (st_parameter_open *opp, unit_flags *flags)
   1550 {
   1551   char *path = fc_strdup (opp->file, opp->file_len);
   1552   int fd = regular_file2 (path, opp, flags);
   1553   free (path);
   1554   return fd;
   1555 }
   1556 
   1557 /* open_external()-- Open an external file, unix specific version.
   1558    Change flags->action if it is ACTION_UNSPECIFIED on entry.
   1559    Returns NULL on operating system error. */
   1560 
   1561 stream *
   1562 open_external (st_parameter_open *opp, unit_flags *flags)
   1563 {
   1564   int fd;
   1565 
   1566   if (flags->status == STATUS_SCRATCH)
   1567     {
   1568       fd = tempfile (opp);
   1569       if (flags->action == ACTION_UNSPECIFIED)
   1570 	flags->action = flags->readonly ? ACTION_READ : ACTION_READWRITE;
   1571 
   1572 #if HAVE_UNLINK_OPEN_FILE
   1573       /* We can unlink scratch files now and it will go away when closed. */
   1574       if (fd >= 0)
   1575 	unlink (opp->file);
   1576 #endif
   1577     }
   1578   else
   1579     {
   1580       /* regular_file resets flags->action if it is ACTION_UNSPECIFIED and
   1581          if it succeeds */
   1582       fd = regular_file (opp, flags);
   1583 #ifndef O_CLOEXEC
   1584       set_close_on_exec (fd);
   1585 #endif
   1586     }
   1587 
   1588   if (fd < 0)
   1589     return NULL;
   1590   fd = fix_fd (fd);
   1591 
   1592   if (open_share (opp, fd, flags) < 0)
   1593     return NULL;
   1594 
   1595   return fd_to_stream (fd, flags->form == FORM_UNFORMATTED);
   1596 }
   1597 
   1598 
   1599 /* input_stream()-- Return a stream pointer to the default input stream.
   1600    Called on initialization. */
   1601 
   1602 stream *
   1603 input_stream (void)
   1604 {
   1605   return fd_to_stream (STDIN_FILENO, false);
   1606 }
   1607 
   1608 
   1609 /* output_stream()-- Return a stream pointer to the default output stream.
   1610    Called on initialization. */
   1611 
   1612 stream *
   1613 output_stream (void)
   1614 {
   1615   stream *s;
   1616 
   1617 #if defined(HAVE_CRLF) && defined(HAVE_SETMODE)
   1618   setmode (STDOUT_FILENO, O_BINARY);
   1619 #endif
   1620 
   1621   s = fd_to_stream (STDOUT_FILENO, false);
   1622   return s;
   1623 }
   1624 
   1625 
   1626 /* error_stream()-- Return a stream pointer to the default error stream.
   1627    Called on initialization. */
   1628 
   1629 stream *
   1630 error_stream (void)
   1631 {
   1632   stream *s;
   1633 
   1634 #if defined(HAVE_CRLF) && defined(HAVE_SETMODE)
   1635   setmode (STDERR_FILENO, O_BINARY);
   1636 #endif
   1637 
   1638   s = fd_to_stream (STDERR_FILENO, false);
   1639   return s;
   1640 }
   1641 
   1642 
   1643 /* compare_file_filename()-- Given an open stream and a fortran string
   1644    that is a filename, figure out if the file is the same as the
   1645    filename. */
   1646 
   1647 int
   1648 compare_file_filename (gfc_unit *u, const char *name, gfc_charlen_type len)
   1649 {
   1650   struct stat st;
   1651   int ret;
   1652 #ifdef HAVE_WORKING_STAT
   1653   unix_stream *s;
   1654 #else
   1655 # ifdef __MINGW32__
   1656   uint64_t id1, id2;
   1657 # endif
   1658 #endif
   1659 
   1660   char *path = fc_strdup (name, len);
   1661 
   1662   /* If the filename doesn't exist, then there is no match with the
   1663      existing file. */
   1664 
   1665   if (TEMP_FAILURE_RETRY (stat (path, &st)) < 0)
   1666     {
   1667       ret = 0;
   1668       goto done;
   1669     }
   1670 
   1671 #ifdef HAVE_WORKING_STAT
   1672   s = (unix_stream *) (u->s);
   1673   ret = (st.st_dev == s->st_dev) && (st.st_ino == s->st_ino);
   1674   goto done;
   1675 #else
   1676 
   1677 # ifdef __MINGW32__
   1678   /* We try to match files by a unique ID.  On some filesystems (network
   1679      fs and FAT), we can't generate this unique ID, and will simply compare
   1680      filenames.  */
   1681   id1 = id_from_path (path);
   1682   id2 = id_from_fd (((unix_stream *) (u->s))->fd);
   1683   if (id1 || id2)
   1684     {
   1685       ret = (id1 == id2);
   1686       goto done;
   1687     }
   1688 # endif
   1689   if (u->filename)
   1690     ret = (strcmp(path, u->filename) == 0);
   1691   else
   1692     ret = 0;
   1693 #endif
   1694  done:
   1695   free (path);
   1696   return ret;
   1697 }
   1698 
   1699 
   1700 #ifdef HAVE_WORKING_STAT
   1701 # define FIND_FILE0_DECL struct stat *st
   1702 # define FIND_FILE0_ARGS st
   1703 #else
   1704 # define FIND_FILE0_DECL uint64_t id, const char *path
   1705 # define FIND_FILE0_ARGS id, path
   1706 #endif
   1707 
   1708 /* find_file0()-- Recursive work function for find_file() */
   1709 
   1710 static gfc_unit *
   1711 find_file0 (gfc_unit *u, FIND_FILE0_DECL)
   1712 {
   1713   gfc_unit *v;
   1714 #if defined(__MINGW32__) && !HAVE_WORKING_STAT
   1715   uint64_t id1;
   1716 #endif
   1717 
   1718   if (u == NULL)
   1719     return NULL;
   1720 
   1721 #ifdef HAVE_WORKING_STAT
   1722   if (u->s != NULL)
   1723     {
   1724       unix_stream *s = (unix_stream *) (u->s);
   1725       if (st[0].st_dev == s->st_dev && st[0].st_ino == s->st_ino)
   1726 	return u;
   1727     }
   1728 #else
   1729 # ifdef __MINGW32__
   1730   if (u->s && ((id1 = id_from_fd (((unix_stream *) u->s)->fd)) || id1))
   1731     {
   1732       if (id == id1)
   1733 	return u;
   1734     }
   1735   else
   1736 # endif
   1737     if (u->filename && strcmp (u->filename, path) == 0)
   1738       return u;
   1739 #endif
   1740 
   1741   v = find_file0 (u->left, FIND_FILE0_ARGS);
   1742   if (v != NULL)
   1743     return v;
   1744 
   1745   v = find_file0 (u->right, FIND_FILE0_ARGS);
   1746   if (v != NULL)
   1747     return v;
   1748 
   1749   return NULL;
   1750 }
   1751 
   1752 
   1753 /* find_file()-- Take the current filename and see if there is a unit
   1754    that has the file already open.  Returns a pointer to the unit if so. */
   1755 
   1756 gfc_unit *
   1757 find_file (const char *file, gfc_charlen_type file_len)
   1758 {
   1759   struct stat st[1];
   1760   gfc_unit *u;
   1761 #if defined(__MINGW32__) && !HAVE_WORKING_STAT
   1762   uint64_t id = 0ULL;
   1763 #endif
   1764 
   1765   char *path = fc_strdup (file, file_len);
   1766 
   1767   if (TEMP_FAILURE_RETRY (stat (path, &st[0])) < 0)
   1768     {
   1769       u = NULL;
   1770       goto done;
   1771     }
   1772 
   1773 #if defined(__MINGW32__) && !HAVE_WORKING_STAT
   1774   id = id_from_path (path);
   1775 #endif
   1776 
   1777   LOCK (&unit_lock);
   1778 retry:
   1779   u = find_file0 (unit_root, FIND_FILE0_ARGS);
   1780   if (u != NULL)
   1781     {
   1782       /* Fast path.  */
   1783       if (! __gthread_mutex_trylock (&u->lock))
   1784 	{
   1785 	  /* assert (u->closed == 0); */
   1786 	  UNLOCK (&unit_lock);
   1787 	  goto done;
   1788 	}
   1789 
   1790       inc_waiting_locked (u);
   1791     }
   1792   UNLOCK (&unit_lock);
   1793   if (u != NULL)
   1794     {
   1795       LOCK (&u->lock);
   1796       if (u->closed)
   1797 	{
   1798 	  LOCK (&unit_lock);
   1799 	  UNLOCK (&u->lock);
   1800 	  if (predec_waiting_locked (u) == 0)
   1801 	    free (u);
   1802 	  goto retry;
   1803 	}
   1804 
   1805       dec_waiting_unlocked (u);
   1806     }
   1807  done:
   1808   free (path);
   1809   return u;
   1810 }
   1811 
   1812 static gfc_unit *
   1813 flush_all_units_1 (gfc_unit *u, int min_unit)
   1814 {
   1815   while (u != NULL)
   1816     {
   1817       if (u->unit_number > min_unit)
   1818 	{
   1819 	  gfc_unit *r = flush_all_units_1 (u->left, min_unit);
   1820 	  if (r != NULL)
   1821 	    return r;
   1822 	}
   1823       if (u->unit_number >= min_unit)
   1824 	{
   1825 	  if (__gthread_mutex_trylock (&u->lock))
   1826 	    return u;
   1827 	  if (u->s)
   1828 	    sflush (u->s);
   1829 	  UNLOCK (&u->lock);
   1830 	}
   1831       u = u->right;
   1832     }
   1833   return NULL;
   1834 }
   1835 
   1836 void
   1837 flush_all_units (void)
   1838 {
   1839   gfc_unit *u;
   1840   int min_unit = 0;
   1841 
   1842   LOCK (&unit_lock);
   1843   do
   1844     {
   1845       u = flush_all_units_1 (unit_root, min_unit);
   1846       if (u != NULL)
   1847 	inc_waiting_locked (u);
   1848       UNLOCK (&unit_lock);
   1849       if (u == NULL)
   1850 	return;
   1851 
   1852       LOCK (&u->lock);
   1853 
   1854       min_unit = u->unit_number + 1;
   1855 
   1856       if (u->closed == 0)
   1857 	{
   1858 	  sflush (u->s);
   1859 	  LOCK (&unit_lock);
   1860 	  UNLOCK (&u->lock);
   1861 	  (void) predec_waiting_locked (u);
   1862 	}
   1863       else
   1864 	{
   1865 	  LOCK (&unit_lock);
   1866 	  UNLOCK (&u->lock);
   1867 	  if (predec_waiting_locked (u) == 0)
   1868 	    free (u);
   1869 	}
   1870     }
   1871   while (1);
   1872 }
   1873 
   1874 
   1875 /* Unlock the unit if necessary, based on SHARE flags.  */
   1876 
   1877 int
   1878 close_share (gfc_unit *u __attribute__ ((unused)))
   1879 {
   1880   int r = 0;
   1881 #if defined(HAVE_FCNTL) && defined(F_SETLK) && defined(F_UNLCK)
   1882   unix_stream *s = (unix_stream *) u->s;
   1883   int fd = s->fd;
   1884   struct flock f;
   1885 
   1886   switch (u->flags.share)
   1887   {
   1888     case SHARE_DENYRW:
   1889     case SHARE_DENYNONE:
   1890       if (fd != STDOUT_FILENO && fd != STDERR_FILENO && fd != STDIN_FILENO)
   1891 	{
   1892 	  f.l_start = 0;
   1893 	  f.l_len = 0;
   1894 	  f.l_whence = SEEK_SET;
   1895 	  f.l_type = F_UNLCK;
   1896 	  r = fcntl (fd, F_SETLK, &f);
   1897 	}
   1898       break;
   1899     case SHARE_UNSPECIFIED:
   1900     default:
   1901       break;
   1902   }
   1903 
   1904 #endif
   1905   return r;
   1906 }
   1907 
   1908 
   1909 /* file_exists()-- Returns nonzero if the current filename exists on
   1910    the system */
   1911 
   1912 int
   1913 file_exists (const char *file, gfc_charlen_type file_len)
   1914 {
   1915   char *path = fc_strdup (file, file_len);
   1916   int res = !(access (path, F_OK));
   1917   free (path);
   1918   return res;
   1919 }
   1920 
   1921 
   1922 /* file_size()-- Returns the size of the file.  */
   1923 
   1924 GFC_IO_INT
   1925 file_size (const char *file, gfc_charlen_type file_len)
   1926 {
   1927   char *path = fc_strdup (file, file_len);
   1928   struct stat statbuf;
   1929   int err;
   1930   TEMP_FAILURE_RETRY (err = stat (path, &statbuf));
   1931   free (path);
   1932   if (err == -1)
   1933     return -1;
   1934   return (GFC_IO_INT) statbuf.st_size;
   1935 }
   1936 
   1937 static const char yes[] = "YES", no[] = "NO", unknown[] = "UNKNOWN";
   1938 
   1939 /* inquire_sequential()-- Given a fortran string, determine if the
   1940    file is suitable for sequential access.  Returns a C-style
   1941    string. */
   1942 
   1943 const char *
   1944 inquire_sequential (const char *string, gfc_charlen_type len)
   1945 {
   1946   struct stat statbuf;
   1947 
   1948   if (string == NULL)
   1949     return unknown;
   1950 
   1951   char *path = fc_strdup (string, len);
   1952   int err;
   1953   TEMP_FAILURE_RETRY (err = stat (path, &statbuf));
   1954   free (path);
   1955   if (err == -1)
   1956     return unknown;
   1957 
   1958   if (S_ISREG (statbuf.st_mode) ||
   1959       S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode))
   1960     return unknown;
   1961 
   1962   if (S_ISDIR (statbuf.st_mode) || S_ISBLK (statbuf.st_mode))
   1963     return no;
   1964 
   1965   return unknown;
   1966 }
   1967 
   1968 
   1969 /* inquire_direct()-- Given a fortran string, determine if the file is
   1970    suitable for direct access.  Returns a C-style string. */
   1971 
   1972 const char *
   1973 inquire_direct (const char *string, gfc_charlen_type len)
   1974 {
   1975   struct stat statbuf;
   1976 
   1977   if (string == NULL)
   1978     return unknown;
   1979 
   1980   char *path = fc_strdup (string, len);
   1981   int err;
   1982   TEMP_FAILURE_RETRY (err = stat (path, &statbuf));
   1983   free (path);
   1984   if (err == -1)
   1985     return unknown;
   1986 
   1987   if (S_ISREG (statbuf.st_mode) || S_ISBLK (statbuf.st_mode))
   1988     return unknown;
   1989 
   1990   if (S_ISDIR (statbuf.st_mode) ||
   1991       S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode))
   1992     return no;
   1993 
   1994   return unknown;
   1995 }
   1996 
   1997 
   1998 /* inquire_formatted()-- Given a fortran string, determine if the file
   1999    is suitable for formatted form.  Returns a C-style string. */
   2000 
   2001 const char *
   2002 inquire_formatted (const char *string, gfc_charlen_type len)
   2003 {
   2004   struct stat statbuf;
   2005 
   2006   if (string == NULL)
   2007     return unknown;
   2008 
   2009   char *path = fc_strdup (string, len);
   2010   int err;
   2011   TEMP_FAILURE_RETRY (err = stat (path, &statbuf));
   2012   free (path);
   2013   if (err == -1)
   2014     return unknown;
   2015 
   2016   if (S_ISREG (statbuf.st_mode) ||
   2017       S_ISBLK (statbuf.st_mode) ||
   2018       S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode))
   2019     return unknown;
   2020 
   2021   if (S_ISDIR (statbuf.st_mode))
   2022     return no;
   2023 
   2024   return unknown;
   2025 }
   2026 
   2027 
   2028 /* inquire_unformatted()-- Given a fortran string, determine if the file
   2029    is suitable for unformatted form.  Returns a C-style string. */
   2030 
   2031 const char *
   2032 inquire_unformatted (const char *string, gfc_charlen_type len)
   2033 {
   2034   return inquire_formatted (string, len);
   2035 }
   2036 
   2037 
   2038 /* inquire_access()-- Given a fortran string, determine if the file is
   2039    suitable for access. */
   2040 
   2041 static const char *
   2042 inquire_access (const char *string, gfc_charlen_type len, int mode)
   2043 {
   2044   if (string == NULL)
   2045     return no;
   2046   char *path = fc_strdup (string, len);
   2047   int res = access (path, mode);
   2048   free (path);
   2049   if (res == -1)
   2050     return no;
   2051 
   2052   return yes;
   2053 }
   2054 
   2055 
   2056 /* inquire_read()-- Given a fortran string, determine if the file is
   2057    suitable for READ access. */
   2058 
   2059 const char *
   2060 inquire_read (const char *string, gfc_charlen_type len)
   2061 {
   2062   return inquire_access (string, len, R_OK);
   2063 }
   2064 
   2065 
   2066 /* inquire_write()-- Given a fortran string, determine if the file is
   2067    suitable for READ access. */
   2068 
   2069 const char *
   2070 inquire_write (const char *string, gfc_charlen_type len)
   2071 {
   2072   return inquire_access (string, len, W_OK);
   2073 }
   2074 
   2075 
   2076 /* inquire_readwrite()-- Given a fortran string, determine if the file is
   2077    suitable for read and write access. */
   2078 
   2079 const char *
   2080 inquire_readwrite (const char *string, gfc_charlen_type len)
   2081 {
   2082   return inquire_access (string, len, R_OK | W_OK);
   2083 }
   2084 
   2085 
   2086 int
   2087 stream_isatty (stream *s)
   2088 {
   2089   return isatty (((unix_stream *) s)->fd);
   2090 }
   2091 
   2092 int
   2093 stream_ttyname (stream *s  __attribute__ ((unused)),
   2094 		char *buf  __attribute__ ((unused)),
   2095 		size_t buflen  __attribute__ ((unused)))
   2096 {
   2097 #ifdef HAVE_TTYNAME_R
   2098   return ttyname_r (((unix_stream *)s)->fd, buf, buflen);
   2099 #elif defined HAVE_TTYNAME
   2100   char *p;
   2101   size_t plen;
   2102   p = ttyname (((unix_stream *)s)->fd);
   2103   if (!p)
   2104     return errno;
   2105   plen = strlen (p);
   2106   if (buflen < plen)
   2107     plen = buflen;
   2108   memcpy (buf, p, plen);
   2109   return 0;
   2110 #else
   2111   return ENOSYS;
   2112 #endif
   2113 }
   2114 
   2115 
   2116 
   2117 
   2118 /* How files are stored:  This is an operating-system specific issue,
   2119    and therefore belongs here.  There are three cases to consider.
   2120 
   2121    Direct Access:
   2122       Records are written as block of bytes corresponding to the record
   2123       length of the file.  This goes for both formatted and unformatted
   2124       records.  Positioning is done explicitly for each data transfer,
   2125       so positioning is not much of an issue.
   2126 
   2127    Sequential Formatted:
   2128       Records are separated by newline characters.  The newline character
   2129       is prohibited from appearing in a string.  If it does, this will be
   2130       messed up on the next read.  End of file is also the end of a record.
   2131 
   2132    Sequential Unformatted:
   2133       In this case, we are merely copying bytes to and from main storage,
   2134       yet we need to keep track of varying record lengths.  We adopt
   2135       the solution used by f2c.  Each record contains a pair of length
   2136       markers:
   2137 
   2138 	Length of record n in bytes
   2139 	Data of record n
   2140 	Length of record n in bytes
   2141 
   2142 	Length of record n+1 in bytes
   2143 	Data of record n+1
   2144 	Length of record n+1 in bytes
   2145 
   2146      The length is stored at the end of a record to allow backspacing to the
   2147      previous record.  Between data transfer statements, the file pointer
   2148      is left pointing to the first length of the current record.
   2149 
   2150      ENDFILE records are never explicitly stored.
   2151 
   2152 */
   2153