OSDN Git Service

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