OSDN Git Service

Return error when trying to seek a non-seekable buffered file
[pf3gnuchains/gcc-fork.git] / libgfortran / io / unix.c
1 /* Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
2    2011
3    Free Software Foundation, Inc.
4    Contributed by Andy Vaught
5    F2003 I/O support contributed by Jerry DeLisle
6
7 This file is part of the GNU Fortran runtime library (libgfortran).
8
9 Libgfortran is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3, or (at your option)
12 any later version.
13
14 Libgfortran is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18
19 Under Section 7 of GPL version 3, you are granted additional
20 permissions described in the GCC Runtime Library Exception, version
21 3.1, as published by the Free Software Foundation.
22
23 You should have received a copy of the GNU General Public License and
24 a copy of the GCC Runtime Library Exception along with this program;
25 see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
26 <http://www.gnu.org/licenses/>.  */
27
28 /* Unix stream I/O module */
29
30 #include "io.h"
31 #include "unix.h"
32 #include <stdlib.h>
33 #include <limits.h>
34
35 #include <unistd.h>
36 #include <sys/stat.h>
37 #include <fcntl.h>
38 #include <assert.h>
39
40 #include <string.h>
41 #include <errno.h>
42
43
44 /* min macro that evaluates its arguments only once.  */
45 #define min(a,b)                \
46   ({ typeof (a) _a = (a);       \
47     typeof (b) _b = (b);        \
48     _a < _b ? _a : _b; })
49
50
51 /* For mingw, we don't identify files by their inode number, but by a
52    64-bit identifier created from a BY_HANDLE_FILE_INFORMATION. */
53 #ifdef __MINGW32__
54
55 #define WIN32_LEAN_AND_MEAN
56 #include <windows.h>
57
58 #if !defined(_FILE_OFFSET_BITS) || _FILE_OFFSET_BITS != 64
59 #undef lseek
60 #define lseek _lseeki64
61 #undef fstat
62 #define fstat _fstati64
63 #undef stat
64 #define stat _stati64
65 #endif
66
67 #ifndef HAVE_WORKING_STAT
68 static uint64_t
69 id_from_handle (HANDLE hFile)
70 {
71   BY_HANDLE_FILE_INFORMATION FileInformation;
72
73   if (hFile == INVALID_HANDLE_VALUE)
74       return 0;
75
76   memset (&FileInformation, 0, sizeof(FileInformation));
77   if (!GetFileInformationByHandle (hFile, &FileInformation))
78     return 0;
79
80   return ((uint64_t) FileInformation.nFileIndexLow)
81          | (((uint64_t) FileInformation.nFileIndexHigh) << 32);
82 }
83
84
85 static uint64_t
86 id_from_path (const char *path)
87 {
88   HANDLE hFile;
89   uint64_t res;
90
91   if (!path || !*path || access (path, F_OK))
92     return (uint64_t) -1;
93
94   hFile = CreateFile (path, 0, 0, NULL, OPEN_EXISTING,
95                       FILE_FLAG_BACKUP_SEMANTICS | FILE_ATTRIBUTE_READONLY,
96                       NULL);
97   res = id_from_handle (hFile);
98   CloseHandle (hFile);
99   return res;
100 }
101
102
103 static uint64_t
104 id_from_fd (const int fd)
105 {
106   return id_from_handle ((HANDLE) _get_osfhandle (fd));
107 }
108
109 #endif
110 #endif
111
112 #ifndef PATH_MAX
113 #define PATH_MAX 1024
114 #endif
115
116 /* These flags aren't defined on all targets (mingw32), so provide them
117    here.  */
118 #ifndef S_IRGRP
119 #define S_IRGRP 0
120 #endif
121
122 #ifndef S_IWGRP
123 #define S_IWGRP 0
124 #endif
125
126 #ifndef S_IROTH
127 #define S_IROTH 0
128 #endif
129
130 #ifndef S_IWOTH
131 #define S_IWOTH 0
132 #endif
133
134
135 #ifndef HAVE_ACCESS
136
137 #ifndef W_OK
138 #define W_OK 2
139 #endif
140
141 #ifndef R_OK
142 #define R_OK 4
143 #endif
144
145 #ifndef F_OK
146 #define F_OK 0
147 #endif
148
149 /* Fallback implementation of access() on systems that don't have it.
150    Only modes R_OK, W_OK and F_OK are used in this file.  */
151
152 static int
153 fallback_access (const char *path, int mode)
154 {
155   int fd;
156
157   if ((mode & R_OK) && (fd = open (path, O_RDONLY)) < 0)
158     return -1;
159   close (fd);
160
161   if ((mode & W_OK) && (fd = open (path, O_WRONLY)) < 0)
162     return -1;
163   close (fd);
164
165   if (mode == F_OK)
166     {
167       struct stat st;
168       return stat (path, &st);
169     }
170
171   return 0;
172 }
173
174 #undef access
175 #define access fallback_access
176 #endif
177
178
179 /* Unix and internal stream I/O module */
180
181 static const int BUFFER_SIZE = 8192;
182
183 typedef struct
184 {
185   stream st;
186
187   gfc_offset buffer_offset;     /* File offset of the start of the buffer */
188   gfc_offset physical_offset;   /* Current physical file offset */
189   gfc_offset logical_offset;    /* Current logical file offset */
190   gfc_offset file_length;       /* Length of the file, -1 if not seekable. */
191
192   char *buffer;                 /* Pointer to the buffer.  */
193   int fd;                       /* The POSIX file descriptor.  */
194
195   int active;                   /* Length of valid bytes in the buffer */
196
197   int ndirty;                   /* Dirty bytes starting at buffer_offset */
198
199   int special_file;             /* =1 if the fd refers to a special file */
200
201   /* Cached stat(2) values.  */
202   dev_t st_dev;
203   ino_t st_ino;
204 }
205 unix_stream;
206
207
208 /* fix_fd()-- Given a file descriptor, make sure it is not one of the
209  * standard descriptors, returning a non-standard descriptor.  If the
210  * user specifies that system errors should go to standard output,
211  * then closes standard output, we don't want the system errors to a
212  * file that has been given file descriptor 1 or 0.  We want to send
213  * the error to the invalid descriptor. */
214
215 static int
216 fix_fd (int fd)
217 {
218 #ifdef HAVE_DUP
219   int input, output, error;
220
221   input = output = error = 0;
222
223   /* Unix allocates the lowest descriptors first, so a loop is not
224      required, but this order is. */
225   if (fd == STDIN_FILENO)
226     {
227       fd = dup (fd);
228       input = 1;
229     }
230   if (fd == STDOUT_FILENO)
231     {
232       fd = dup (fd);
233       output = 1;
234     }
235   if (fd == STDERR_FILENO)
236     {
237       fd = dup (fd);
238       error = 1;
239     }
240
241   if (input)
242     close (STDIN_FILENO);
243   if (output)
244     close (STDOUT_FILENO);
245   if (error)
246     close (STDERR_FILENO);
247 #endif
248
249   return fd;
250 }
251
252
253 /* If the stream corresponds to a preconnected unit, we flush the
254    corresponding C stream.  This is bugware for mixed C-Fortran codes
255    where the C code doesn't flush I/O before returning.  */
256 void
257 flush_if_preconnected (stream * s)
258 {
259   int fd;
260
261   fd = ((unix_stream *) s)->fd;
262   if (fd == STDIN_FILENO)
263     fflush (stdin);
264   else if (fd == STDOUT_FILENO)
265     fflush (stdout);
266   else if (fd == STDERR_FILENO)
267     fflush (stderr);
268 }
269
270
271 /********************************************************************
272 Raw I/O functions (read, write, seek, tell, truncate, close).
273
274 These functions wrap the basic POSIX I/O syscalls. Any deviation in
275 semantics is a bug, except the following: write restarts in case
276 of being interrupted by a signal, and as the first argument the
277 functions take the unix_stream struct rather than an integer file
278 descriptor. Also, for POSIX read() and write() a nbyte argument larger
279 than SSIZE_MAX is undefined; here the type of nbyte is ssize_t rather
280 than size_t as for POSIX read/write.
281 *********************************************************************/
282
283 static int
284 raw_flush (unix_stream * s  __attribute__ ((unused)))
285 {
286   return 0;
287 }
288
289 static ssize_t
290 raw_read (unix_stream * s, void * buf, ssize_t nbyte)
291 {
292   /* For read we can't do I/O in a loop like raw_write does, because
293      that will break applications that wait for interactive I/O.  */
294   return read (s->fd, buf, nbyte);
295 }
296
297 static ssize_t
298 raw_write (unix_stream * s, const void * buf, ssize_t nbyte)
299 {
300   ssize_t trans, bytes_left;
301   char *buf_st;
302
303   bytes_left = nbyte;
304   buf_st = (char *) buf;
305
306   /* We must write in a loop since some systems don't restart system
307      calls in case of a signal.  */
308   while (bytes_left > 0)
309     {
310       trans = write (s->fd, buf_st, bytes_left);
311       if (trans < 0)
312         {
313           if (errno == EINTR)
314             continue;
315           else
316             return trans;
317         }
318       buf_st += trans;
319       bytes_left -= trans;
320     }
321
322   return nbyte - bytes_left;
323 }
324
325 static gfc_offset
326 raw_seek (unix_stream * s, gfc_offset offset, int whence)
327 {
328   return lseek (s->fd, offset, whence);
329 }
330
331 static gfc_offset
332 raw_tell (unix_stream * s)
333 {
334   return lseek (s->fd, 0, SEEK_CUR);
335 }
336
337 static int
338 raw_truncate (unix_stream * s, gfc_offset length)
339 {
340 #ifdef __MINGW32__
341   HANDLE h;
342   gfc_offset cur;
343
344   if (isatty (s->fd))
345     {
346       errno = EBADF;
347       return -1;
348     }
349   h = (HANDLE) _get_osfhandle (s->fd);
350   if (h == INVALID_HANDLE_VALUE)
351     {
352       errno = EBADF;
353       return -1;
354     }
355   cur = lseek (s->fd, 0, SEEK_CUR);
356   if (cur == -1)
357     return -1;
358   if (lseek (s->fd, length, SEEK_SET) == -1)
359     goto error;
360   if (!SetEndOfFile (h))
361     {
362       errno = EBADF;
363       goto error;
364     }
365   if (lseek (s->fd, cur, SEEK_SET) == -1)
366     return -1;
367   return 0;
368  error:
369   lseek (s->fd, cur, SEEK_SET);
370   return -1;
371 #elif defined HAVE_FTRUNCATE
372   return ftruncate (s->fd, length);
373 #elif defined HAVE_CHSIZE
374   return chsize (s->fd, length);
375 #else
376   runtime_error ("required ftruncate or chsize support not present");
377   return -1;
378 #endif
379 }
380
381 static int
382 raw_close (unix_stream * s)
383 {
384   int retval;
385   
386   if (s->fd != STDOUT_FILENO
387       && s->fd != STDERR_FILENO
388       && s->fd != STDIN_FILENO)
389     retval = close (s->fd);
390   else
391     retval = 0;
392   free (s);
393   return retval;
394 }
395
396 static int
397 raw_init (unix_stream * s)
398 {
399   s->st.read = (void *) raw_read;
400   s->st.write = (void *) raw_write;
401   s->st.seek = (void *) raw_seek;
402   s->st.tell = (void *) raw_tell;
403   s->st.trunc = (void *) raw_truncate;
404   s->st.close = (void *) raw_close;
405   s->st.flush = (void *) raw_flush;
406
407   s->buffer = NULL;
408   return 0;
409 }
410
411
412 /*********************************************************************
413 Buffered I/O functions. These functions have the same semantics as the
414 raw I/O functions above, except that they are buffered in order to
415 improve performance. The buffer must be flushed when switching from
416 reading to writing and vice versa.
417 *********************************************************************/
418
419 static int
420 buf_flush (unix_stream * s)
421 {
422   int writelen;
423
424   /* Flushing in read mode means discarding read bytes.  */
425   s->active = 0;
426
427   if (s->ndirty == 0)
428     return 0;
429   
430   if (s->file_length != -1 && s->physical_offset != s->buffer_offset
431       && lseek (s->fd, s->buffer_offset, SEEK_SET) < 0)
432     return -1;
433
434   writelen = raw_write (s, s->buffer, s->ndirty);
435
436   s->physical_offset = s->buffer_offset + writelen;
437
438   /* Don't increment file_length if the file is non-seekable.  */
439   if (s->file_length != -1 && s->physical_offset > s->file_length)
440       s->file_length = s->physical_offset;
441
442   s->ndirty -= writelen;
443   if (s->ndirty != 0)
444     return -1;
445
446 #ifdef _WIN32
447   _commit (s->fd);
448 #endif
449
450   return 0;
451 }
452
453 static ssize_t
454 buf_read (unix_stream * s, void * buf, ssize_t nbyte)
455 {
456   if (s->active == 0)
457     s->buffer_offset = s->logical_offset;
458
459   /* Is the data we want in the buffer?  */
460   if (s->logical_offset + nbyte <= s->buffer_offset + s->active
461       && s->buffer_offset <= s->logical_offset)
462     memcpy (buf, s->buffer + (s->logical_offset - s->buffer_offset), nbyte);
463   else
464     {
465       /* First copy the active bytes if applicable, then read the rest
466          either directly or filling the buffer.  */
467       char *p;
468       int nread = 0;
469       ssize_t to_read, did_read;
470       gfc_offset new_logical;
471       
472       p = (char *) buf;
473       if (s->logical_offset >= s->buffer_offset 
474           && s->buffer_offset + s->active >= s->logical_offset)
475         {
476           nread = s->active - (s->logical_offset - s->buffer_offset);
477           memcpy (buf, s->buffer + (s->logical_offset - s->buffer_offset), 
478                   nread);
479           p += nread;
480         }
481       /* At this point we consider all bytes in the buffer discarded.  */
482       to_read = nbyte - nread;
483       new_logical = s->logical_offset + nread;
484       if (s->file_length != -1 && s->physical_offset != new_logical
485           && lseek (s->fd, new_logical, SEEK_SET) < 0)
486         return -1;
487       s->buffer_offset = s->physical_offset = new_logical;
488       if (to_read <= BUFFER_SIZE/2)
489         {
490           did_read = raw_read (s, s->buffer, BUFFER_SIZE);
491           s->physical_offset += did_read;
492           s->active = did_read;
493           did_read = (did_read > to_read) ? to_read : did_read;
494           memcpy (p, s->buffer, did_read);
495         }
496       else
497         {
498           did_read = raw_read (s, p, to_read);
499           s->physical_offset += did_read;
500           s->active = 0;
501         }
502       nbyte = did_read + nread;
503     }
504   s->logical_offset += nbyte;
505   return nbyte;
506 }
507
508 static ssize_t
509 buf_write (unix_stream * s, const void * buf, ssize_t nbyte)
510 {
511   if (s->ndirty == 0)
512     s->buffer_offset = s->logical_offset;
513
514   /* Does the data fit into the buffer?  As a special case, if the
515      buffer is empty and the request is bigger than BUFFER_SIZE/2,
516      write directly. This avoids the case where the buffer would have
517      to be flushed at every write.  */
518   if (!(s->ndirty == 0 && nbyte > BUFFER_SIZE/2)
519       && s->logical_offset + nbyte <= s->buffer_offset + BUFFER_SIZE
520       && s->buffer_offset <= s->logical_offset
521       && s->buffer_offset + s->ndirty >= s->logical_offset)
522     {
523       memcpy (s->buffer + (s->logical_offset - s->buffer_offset), buf, nbyte);
524       int nd = (s->logical_offset - s->buffer_offset) + nbyte;
525       if (nd > s->ndirty)
526         s->ndirty = nd;
527     }
528   else
529     {
530       /* Flush, and either fill the buffer with the new data, or if
531          the request is bigger than the buffer size, write directly
532          bypassing the buffer.  */
533       buf_flush (s);
534       if (nbyte <= BUFFER_SIZE/2)
535         {
536           memcpy (s->buffer, buf, nbyte);
537           s->buffer_offset = s->logical_offset;
538           s->ndirty += nbyte;
539         }
540       else
541         {
542           if (s->file_length != -1 && s->physical_offset != s->logical_offset)
543             {
544               if (lseek (s->fd, s->logical_offset, SEEK_SET) < 0)
545                 return -1;
546               s->physical_offset = s->logical_offset;
547             }
548
549           nbyte = raw_write (s, buf, nbyte);
550           s->physical_offset += nbyte;
551         }
552     }
553   s->logical_offset += nbyte;
554   /* Don't increment file_length if the file is non-seekable.  */
555   if (s->file_length != -1 && s->logical_offset > s->file_length)
556     s->file_length = s->logical_offset;
557   return nbyte;
558 }
559
560 static gfc_offset
561 buf_seek (unix_stream * s, gfc_offset offset, int whence)
562 {
563   if (s->file_length == -1)
564     {
565       errno = ESPIPE;
566       return -1;
567     }
568   switch (whence)
569     {
570     case SEEK_SET:
571       break;
572     case SEEK_CUR:
573       offset += s->logical_offset;
574       break;
575     case SEEK_END:
576       offset += s->file_length;
577       break;
578     default:
579       return -1;
580     }
581   if (offset < 0)
582     {
583       errno = EINVAL;
584       return -1;
585     }
586   s->logical_offset = offset;
587   return offset;
588 }
589
590 static gfc_offset
591 buf_tell (unix_stream * s)
592 {
593   return buf_seek (s, 0, SEEK_CUR);
594 }
595
596 static int
597 buf_truncate (unix_stream * s, gfc_offset length)
598 {
599   int r;
600
601   if (buf_flush (s) != 0)
602     return -1;
603   r = raw_truncate (s, length);
604   if (r == 0)
605     s->file_length = length;
606   return r;
607 }
608
609 static int
610 buf_close (unix_stream * s)
611 {
612   if (buf_flush (s) != 0)
613     return -1;
614   free (s->buffer);
615   return raw_close (s);
616 }
617
618 static int
619 buf_init (unix_stream * s)
620 {
621   s->st.read = (void *) buf_read;
622   s->st.write = (void *) buf_write;
623   s->st.seek = (void *) buf_seek;
624   s->st.tell = (void *) buf_tell;
625   s->st.trunc = (void *) buf_truncate;
626   s->st.close = (void *) buf_close;
627   s->st.flush = (void *) buf_flush;
628
629   s->buffer = get_mem (BUFFER_SIZE);
630   return 0;
631 }
632
633
634 /*********************************************************************
635   memory stream functions - These are used for internal files
636
637   The idea here is that a single stream structure is created and all
638   requests must be satisfied from it.  The location and size of the
639   buffer is the character variable supplied to the READ or WRITE
640   statement.
641
642 *********************************************************************/
643
644 char *
645 mem_alloc_r (stream * strm, int * len)
646 {
647   unix_stream * s = (unix_stream *) strm;
648   gfc_offset n;
649   gfc_offset where = s->logical_offset;
650
651   if (where < s->buffer_offset || where > s->buffer_offset + s->active)
652     return NULL;
653
654   n = s->buffer_offset + s->active - where;
655   if (*len > n)
656     *len = n;
657
658   s->logical_offset = where + *len;
659
660   return s->buffer + (where - s->buffer_offset);
661 }
662
663
664 char *
665 mem_alloc_r4 (stream * strm, int * len)
666 {
667   unix_stream * s = (unix_stream *) strm;
668   gfc_offset n;
669   gfc_offset where = s->logical_offset;
670
671   if (where < s->buffer_offset || where > s->buffer_offset + s->active)
672     return NULL;
673
674   n = s->buffer_offset + s->active - where;
675   if (*len > n)
676     *len = n;
677
678   s->logical_offset = where + *len;
679
680   return s->buffer + (where - s->buffer_offset) * 4;
681 }
682
683
684 char *
685 mem_alloc_w (stream * strm, int * len)
686 {
687   unix_stream * s = (unix_stream *) strm;
688   gfc_offset m;
689   gfc_offset where = s->logical_offset;
690
691   m = where + *len;
692
693   if (where < s->buffer_offset)
694     return NULL;
695
696   if (m > s->file_length)
697     return NULL;
698
699   s->logical_offset = m;
700
701   return s->buffer + (where - s->buffer_offset);
702 }
703
704
705 gfc_char4_t *
706 mem_alloc_w4 (stream * strm, int * len)
707 {
708   unix_stream * s = (unix_stream *) strm;
709   gfc_offset m;
710   gfc_offset where = s->logical_offset;
711   gfc_char4_t *result = (gfc_char4_t *) s->buffer;
712
713   m = where + *len;
714
715   if (where < s->buffer_offset)
716     return NULL;
717
718   if (m > s->file_length)
719     return NULL;
720
721   s->logical_offset = m;
722   return &result[where - s->buffer_offset];
723 }
724
725
726 /* Stream read function for character(kine=1) internal units.  */
727
728 static ssize_t
729 mem_read (stream * s, void * buf, ssize_t nbytes)
730 {
731   void *p;
732   int nb = nbytes;
733
734   p = mem_alloc_r (s, &nb);
735   if (p)
736     {
737       memcpy (buf, p, nb);
738       return (ssize_t) nb;
739     }
740   else
741     return 0;
742 }
743
744
745 /* Stream read function for chracter(kind=4) internal units.  */
746
747 static ssize_t
748 mem_read4 (stream * s, void * buf, ssize_t nbytes)
749 {
750   void *p;
751   int nb = nbytes;
752
753   p = mem_alloc_r (s, &nb);
754   if (p)
755     {
756       memcpy (buf, p, nb);
757       return (ssize_t) nb;
758     }
759   else
760     return 0;
761 }
762
763
764 /* Stream write function for character(kind=1) internal units.  */
765
766 static ssize_t
767 mem_write (stream * s, const void * buf, ssize_t nbytes)
768 {
769   void *p;
770   int nb = nbytes;
771
772   p = mem_alloc_w (s, &nb);
773   if (p)
774     {
775       memcpy (p, buf, nb);
776       return (ssize_t) nb;
777     }
778   else
779     return 0;
780 }
781
782
783 /* Stream write function for character(kind=4) internal units.  */
784
785 static ssize_t
786 mem_write4 (stream * s, const void * buf, ssize_t nwords)
787 {
788   gfc_char4_t *p;
789   int nw = nwords;
790
791   p = mem_alloc_w4 (s, &nw);
792   if (p)
793     {
794       while (nw--)
795         *p++ = (gfc_char4_t) *((char *) buf);
796       return nwords;
797     }
798   else
799     return 0;
800 }
801
802
803 static gfc_offset
804 mem_seek (stream * strm, gfc_offset offset, int whence)
805 {
806   unix_stream * s = (unix_stream *) strm;
807   switch (whence)
808     {
809     case SEEK_SET:
810       break;
811     case SEEK_CUR:
812       offset += s->logical_offset;
813       break;
814     case SEEK_END:
815       offset += s->file_length;
816       break;
817     default:
818       return -1;
819     }
820
821   /* Note that for internal array I/O it's actually possible to have a
822      negative offset, so don't check for that.  */
823   if (offset > s->file_length)
824     {
825       errno = EINVAL;
826       return -1;
827     }
828
829   s->logical_offset = offset;
830
831   /* Returning < 0 is the error indicator for sseek(), so return 0 if
832      offset is negative.  Thus if the return value is 0, the caller
833      has to use stell() to get the real value of logical_offset.  */
834   if (offset >= 0)
835     return offset;
836   return 0;
837 }
838
839
840 static gfc_offset
841 mem_tell (stream * s)
842 {
843   return ((unix_stream *)s)->logical_offset;
844 }
845
846
847 static int
848 mem_truncate (unix_stream * s __attribute__ ((unused)), 
849               gfc_offset length __attribute__ ((unused)))
850 {
851   return 0;
852 }
853
854
855 static int
856 mem_flush (unix_stream * s __attribute__ ((unused)))
857 {
858   return 0;
859 }
860
861
862 static int
863 mem_close (unix_stream * s)
864 {
865   free (s);
866
867   return 0;
868 }
869
870
871 /*********************************************************************
872   Public functions -- A reimplementation of this module needs to
873   define functional equivalents of the following.
874 *********************************************************************/
875
876 /* open_internal()-- Returns a stream structure from a character(kind=1)
877    internal file */
878
879 stream *
880 open_internal (char *base, int length, gfc_offset offset)
881 {
882   unix_stream *s;
883
884   s = get_mem (sizeof (unix_stream));
885   memset (s, '\0', sizeof (unix_stream));
886
887   s->buffer = base;
888   s->buffer_offset = offset;
889
890   s->logical_offset = 0;
891   s->active = s->file_length = length;
892
893   s->st.close = (void *) mem_close;
894   s->st.seek = (void *) mem_seek;
895   s->st.tell = (void *) mem_tell;
896   s->st.trunc = (void *) mem_truncate;
897   s->st.read = (void *) mem_read;
898   s->st.write = (void *) mem_write;
899   s->st.flush = (void *) mem_flush;
900
901   return (stream *) s;
902 }
903
904 /* open_internal4()-- Returns a stream structure from a character(kind=4)
905    internal file */
906
907 stream *
908 open_internal4 (char *base, int length, gfc_offset offset)
909 {
910   unix_stream *s;
911
912   s = get_mem (sizeof (unix_stream));
913   memset (s, '\0', sizeof (unix_stream));
914
915   s->buffer = base;
916   s->buffer_offset = offset;
917
918   s->logical_offset = 0;
919   s->active = s->file_length = length;
920
921   s->st.close = (void *) mem_close;
922   s->st.seek = (void *) mem_seek;
923   s->st.tell = (void *) mem_tell;
924   s->st.trunc = (void *) mem_truncate;
925   s->st.read = (void *) mem_read4;
926   s->st.write = (void *) mem_write4;
927   s->st.flush = (void *) mem_flush;
928
929   return (stream *) s;
930 }
931
932
933 /* fd_to_stream()-- Given an open file descriptor, build a stream
934  * around it. */
935
936 static stream *
937 fd_to_stream (int fd)
938 {
939   struct stat statbuf;
940   unix_stream *s;
941
942   s = get_mem (sizeof (unix_stream));
943   memset (s, '\0', sizeof (unix_stream));
944
945   s->fd = fd;
946   s->buffer_offset = 0;
947   s->physical_offset = 0;
948   s->logical_offset = 0;
949
950   /* Get the current length of the file. */
951
952   fstat (fd, &statbuf);
953
954   s->st_dev = statbuf.st_dev;
955   s->st_ino = statbuf.st_ino;
956   s->special_file = !S_ISREG (statbuf.st_mode);
957
958   if (S_ISREG (statbuf.st_mode))
959     s->file_length = statbuf.st_size;
960   else
961     {
962       /* Some character special files are seekable but most are not,
963          so figure it out by trying to seek.  On Linux, /dev/null is
964          an example of such a special file.  */
965       s->file_length = lseek (fd, 0, SEEK_END);
966       if (s->file_length > 0)
967         lseek (fd, 0, SEEK_SET);
968     }
969
970   if (!(S_ISREG (statbuf.st_mode) || S_ISBLK (statbuf.st_mode))
971       || options.all_unbuffered
972       ||(options.unbuffered_preconnected && 
973          (s->fd == STDIN_FILENO 
974           || s->fd == STDOUT_FILENO 
975           || s->fd == STDERR_FILENO))
976       || isatty (s->fd))
977     raw_init (s);
978   else
979     buf_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_IREAD | S_IWRITE);
1117 #else
1118       fd = open (template, O_RDWR | O_CREAT | O_EXCL, S_IREAD | S_IWRITE);
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 /* file_length()-- Return the file length in bytes, -1 if unknown */
1765
1766 gfc_offset
1767 file_length (stream * s)
1768 {
1769   gfc_offset curr, end;
1770   if (!is_seekable (s))
1771     return -1;
1772   curr = stell (s);
1773   if (curr == -1)
1774     return curr;
1775   end = sseek (s, 0, SEEK_END);
1776   sseek (s, curr, SEEK_SET);
1777   return end;
1778 }
1779
1780
1781 /* is_seekable()-- Return nonzero if the stream is seekable, zero if
1782  * it is not */
1783
1784 int
1785 is_seekable (stream *s)
1786 {
1787   /* By convention, if file_length == -1, the file is not
1788      seekable.  */
1789   return ((unix_stream *) s)->file_length!=-1;
1790 }
1791
1792
1793 /* is_special()-- Return nonzero if the stream is not a regular file.  */
1794
1795 int
1796 is_special (stream *s)
1797 {
1798   return ((unix_stream *) s)->special_file;
1799 }
1800
1801
1802 int
1803 stream_isatty (stream *s)
1804 {
1805   return isatty (((unix_stream *) s)->fd);
1806 }
1807
1808 int
1809 stream_ttyname (stream *s  __attribute__ ((unused)),
1810                 char * buf  __attribute__ ((unused)),
1811                 size_t buflen  __attribute__ ((unused)))
1812 {
1813 #ifdef HAVE_TTYNAME_R
1814   return ttyname_r (((unix_stream *) s)->fd, buf, buflen);
1815 #elif defined HAVE_TTYNAME
1816   char *p;
1817   size_t plen;
1818   p = ttyname (((unix_stream *) s)->fd);
1819   if (!p)
1820     return errno;
1821   plen = strlen (p);
1822   if (buflen < plen)
1823     plen = buflen;
1824   memcpy (buf, p, plen);
1825   return 0;
1826 #else
1827   return ENOSYS;
1828 #endif
1829 }
1830
1831
1832
1833
1834 /* How files are stored:  This is an operating-system specific issue,
1835    and therefore belongs here.  There are three cases to consider.
1836
1837    Direct Access:
1838       Records are written as block of bytes corresponding to the record
1839       length of the file.  This goes for both formatted and unformatted
1840       records.  Positioning is done explicitly for each data transfer,
1841       so positioning is not much of an issue.
1842
1843    Sequential Formatted:
1844       Records are separated by newline characters.  The newline character
1845       is prohibited from appearing in a string.  If it does, this will be
1846       messed up on the next read.  End of file is also the end of a record.
1847
1848    Sequential Unformatted:
1849       In this case, we are merely copying bytes to and from main storage,
1850       yet we need to keep track of varying record lengths.  We adopt
1851       the solution used by f2c.  Each record contains a pair of length
1852       markers:
1853
1854         Length of record n in bytes
1855         Data of record n
1856         Length of record n in bytes
1857
1858         Length of record n+1 in bytes
1859         Data of record n+1
1860         Length of record n+1 in bytes
1861
1862      The length is stored at the end of a record to allow backspacing to the
1863      previous record.  Between data transfer statements, the file pointer
1864      is left pointing to the first length of the current record.
1865
1866      ENDFILE records are never explicitly stored.
1867
1868 */