OSDN Git Service

2007-05-26 Janne Blomqvist <jb@gcc.gnu.org>
[pf3gnuchains/gcc-fork.git] / libgfortran / io / unix.c
1 /* Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007
2    Free Software Foundation, Inc.
3    Contributed by Andy Vaught
4
5 This file is part of the GNU Fortran 95 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 2, or (at your option)
10 any later version.
11
12 In addition to the permissions in the GNU General Public License, the
13 Free Software Foundation gives you unlimited permission to link the
14 compiled version of this file into combinations with other programs,
15 and to distribute those combinations without any restriction coming
16 from the use of this file.  (The General Public License restrictions
17 do apply in other respects; for example, they cover modification of
18 the file, and distribution when not linked into a combine
19 executable.)
20
21 Libgfortran is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24 GNU General Public License for more details.
25
26 You should have received a copy of the GNU General Public License
27 along with Libgfortran; see the file COPYING.  If not, write to
28 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
29 Boston, MA 02110-1301, USA.  */
30
31 /* Unix stream I/O module */
32
33 #include "config.h"
34 #include <stdlib.h>
35 #include <limits.h>
36
37 #include <unistd.h>
38 #include <stdio.h>
39 #include <stdarg.h>
40 #include <sys/stat.h>
41 #include <fcntl.h>
42 #include <assert.h>
43
44 #include <string.h>
45 #include <errno.h>
46
47 #include "libgfortran.h"
48 #include "io.h"
49
50 #ifndef SSIZE_MAX
51 #define SSIZE_MAX SHRT_MAX
52 #endif
53
54 #ifndef PATH_MAX
55 #define PATH_MAX 1024
56 #endif
57
58 #ifndef PROT_READ
59 #define PROT_READ 1
60 #endif
61
62 #ifndef PROT_WRITE
63 #define PROT_WRITE 2
64 #endif
65
66 /* These flags aren't defined on all targets (mingw32), so provide them
67    here.  */
68 #ifndef S_IRGRP
69 #define S_IRGRP 0
70 #endif
71
72 #ifndef S_IWGRP
73 #define S_IWGRP 0
74 #endif
75
76 #ifndef S_IROTH
77 #define S_IROTH 0
78 #endif
79
80 #ifndef S_IWOTH
81 #define S_IWOTH 0
82 #endif
83
84
85 /* Unix stream I/O module */
86
87 #define BUFFER_SIZE 8192
88
89 typedef struct
90 {
91   stream st;
92
93   int fd;
94   gfc_offset buffer_offset;     /* File offset of the start of the buffer */
95   gfc_offset physical_offset;   /* Current physical file offset */
96   gfc_offset logical_offset;    /* Current logical file offset */
97   gfc_offset dirty_offset;      /* Start of modified bytes in buffer */
98   gfc_offset file_length;       /* Length of the file, -1 if not seekable. */
99
100   int len;                      /* Physical length of the current buffer */
101   int active;                   /* Length of valid bytes in the buffer */
102
103   int prot;
104   int ndirty;                   /* Dirty bytes starting at dirty_offset */
105
106   int special_file;             /* =1 if the fd refers to a special file */
107
108   int unbuffered;               /* =1 if the stream is not buffered */
109
110   char buffer[BUFFER_SIZE];
111 }
112 unix_stream;
113
114
115 /* Stream structure for internal files. Fields must be kept in sync
116    with unix_stream above, except for the buffer. For internal files
117    we point the buffer pointer directly at the destination memory.  */
118
119 typedef struct
120 {
121   stream st;
122
123   int fd;
124   gfc_offset buffer_offset;     /* File offset of the start of the buffer */
125   gfc_offset physical_offset;   /* Current physical file offset */
126   gfc_offset logical_offset;    /* Current logical file offset */
127   gfc_offset dirty_offset;      /* Start of modified bytes in buffer */
128   gfc_offset file_length;       /* Length of the file, -1 if not seekable. */
129
130   int len;                      /* Physical length of the current buffer */
131   int active;                   /* Length of valid bytes in the buffer */
132
133   int prot;
134   int ndirty;                   /* Dirty bytes starting at dirty_offset */
135
136   int special_file;             /* =1 if the fd refers to a special file */
137
138   int unbuffered;               /* =1 if the stream is not buffered */
139
140   char *buffer;
141 }
142 int_stream;
143
144 extern stream *init_error_stream (unix_stream *);
145 internal_proto(init_error_stream);
146
147
148 /* This implementation of stream I/O is based on the paper:
149  *
150  *  "Exploiting the advantages of mapped files for stream I/O",
151  *  O. Krieger, M. Stumm and R. Umrau, "Proceedings of the 1992 Winter
152  *  USENIX conference", p. 27-42.
153  *
154  * It differs in a number of ways from the version described in the
155  * paper.  First of all, threads are not an issue during I/O and we
156  * also don't have to worry about having multiple regions, since
157  * fortran's I/O model only allows you to be one place at a time.
158  *
159  * On the other hand, we have to be able to writing at the end of a
160  * stream, read from the start of a stream or read and write blocks of
161  * bytes from an arbitrary position.  After opening a file, a pointer
162  * to a stream structure is returned, which is used to handle file
163  * accesses until the file is closed.
164  *
165  * salloc_at_r(stream, len, where)-- Given a stream pointer, return a
166  * pointer to a block of memory that mirror the file at position
167  * 'where' that is 'len' bytes long.  The len integer is updated to
168  * reflect how many bytes were actually read.  The only reason for a
169  * short read is end of file.  The file pointer is updated.  The
170  * pointer is valid until the next call to salloc_*.
171  *
172  * salloc_at_w(stream, len, where)-- Given the stream pointer, returns
173  * a pointer to a block of memory that is updated to reflect the state
174  * of the file.  The length of the buffer is always equal to that
175  * requested.  The buffer must be completely set by the caller.  When
176  * data has been written, the sfree() function must be called to
177  * indicate that the caller is done writing data to the buffer.  This
178  * may or may not cause a physical write.
179  *
180  * Short forms of these are salloc_r() and salloc_w() which drop the
181  * 'where' parameter and use the current file pointer. */
182
183
184 /*move_pos_offset()--  Move the record pointer right or left
185  *relative to current position */
186
187 int
188 move_pos_offset (stream* st, int pos_off)
189 {
190   unix_stream * str = (unix_stream*)st;
191   if (pos_off < 0)
192     {
193       str->logical_offset += pos_off;
194
195       if (str->dirty_offset + str->ndirty > str->logical_offset)
196         {
197           if (str->ndirty + pos_off > 0)
198             str->ndirty += pos_off;
199           else
200             {
201               str->dirty_offset +=  pos_off + pos_off;
202               str->ndirty = 0;
203             }
204         }
205
206     return pos_off;
207   }
208   return 0;
209 }
210
211
212 /* fix_fd()-- Given a file descriptor, make sure it is not one of the
213  * standard descriptors, returning a non-standard descriptor.  If the
214  * user specifies that system errors should go to standard output,
215  * then closes standard output, we don't want the system errors to a
216  * file that has been given file descriptor 1 or 0.  We want to send
217  * the error to the invalid descriptor. */
218
219 static int
220 fix_fd (int fd)
221 {
222   int input, output, error;
223
224   input = output = error = 0;
225
226   /* Unix allocates the lowest descriptors first, so a loop is not
227      required, but this order is. */
228
229   if (fd == STDIN_FILENO)
230     {
231       fd = dup (fd);
232       input = 1;
233     }
234   if (fd == STDOUT_FILENO)
235     {
236       fd = dup (fd);
237       output = 1;
238     }
239   if (fd == STDERR_FILENO)
240     {
241       fd = dup (fd);
242       error = 1;
243     }
244
245   if (input)
246     close (STDIN_FILENO);
247   if (output)
248     close (STDOUT_FILENO);
249   if (error)
250     close (STDERR_FILENO);
251
252   return fd;
253 }
254
255 int
256 is_preconnected (stream * s)
257 {
258   int fd;
259
260   fd = ((unix_stream *) s)->fd;
261   if (fd == STDIN_FILENO || fd == STDOUT_FILENO || fd == STDERR_FILENO)
262     return 1;
263   else
264     return 0;
265 }
266
267 /* If the stream corresponds to a preconnected unit, we flush the
268    corresponding C stream.  This is bugware for mixed C-Fortran codes
269    where the C code doesn't flush I/O before returning.  */
270 void
271 flush_if_preconnected (stream * s)
272 {
273   int fd;
274
275   fd = ((unix_stream *) s)->fd;
276   if (fd == STDIN_FILENO)
277     fflush (stdin);
278   else if (fd == STDOUT_FILENO)
279     fflush (stdout);
280   else if (fd == STDERR_FILENO)
281     fflush (stderr);
282 }
283
284
285 /* Reset a stream after reading/writing. Assumes that the buffers have
286    been flushed.  */
287
288 inline static void
289 reset_stream (unix_stream * s, size_t bytes_rw)
290 {
291   s->physical_offset += bytes_rw;
292   s->logical_offset = s->physical_offset;
293   if (s->file_length != -1 && s->physical_offset > s->file_length)
294     s->file_length = s->physical_offset;
295 }
296
297
298 /* Read bytes into a buffer, allowing for short reads.  If the nbytes
299  * argument is less on return than on entry, it is because we've hit
300  * the end of file. */
301
302 static int
303 do_read (unix_stream * s, void * buf, size_t * nbytes)
304 {
305   ssize_t trans;
306   size_t bytes_left;
307   char *buf_st;
308   int status;
309
310   status = 0;
311   bytes_left = *nbytes;
312   buf_st = (char *) buf;
313
314   /* We must read in a loop since some systems don't restart system
315      calls in case of a signal.  */
316   while (bytes_left > 0)
317     {
318       /* Requests between SSIZE_MAX and SIZE_MAX are undefined by SUSv3,
319          so we must read in chunks smaller than SSIZE_MAX.  */
320       trans = (bytes_left < SSIZE_MAX) ? bytes_left : SSIZE_MAX;
321       trans = read (s->fd, buf_st, trans);
322       if (trans < 0)
323         {
324           if (errno == EINTR)
325             continue;
326           else
327             {
328               status = errno;
329               break;
330             }
331         }
332       else if (trans == 0) /* We hit EOF.  */
333         break;
334       buf_st += trans;
335       bytes_left -= trans;
336     }
337
338   *nbytes -= bytes_left;
339   return status;
340 }
341
342
343 /* Write a buffer to a stream, allowing for short writes.  */
344
345 static int
346 do_write (unix_stream * s, const void * buf, size_t * nbytes)
347 {
348   ssize_t trans;
349   size_t bytes_left;
350   char *buf_st;
351   int status;
352
353   status = 0;
354   bytes_left = *nbytes;
355   buf_st = (char *) buf;
356
357   /* We must write in a loop since some systems don't restart system
358      calls in case of a signal.  */
359   while (bytes_left > 0)
360     {
361       /* Requests between SSIZE_MAX and SIZE_MAX are undefined by SUSv3,
362          so we must write in chunks smaller than SSIZE_MAX.  */
363       trans = (bytes_left < SSIZE_MAX) ? bytes_left : SSIZE_MAX;
364       trans = write (s->fd, buf_st, trans);
365       if (trans < 0)
366         {
367           if (errno == EINTR)
368             continue;
369           else
370             {
371               status = errno;
372               break;
373             }
374         }
375       buf_st += trans;
376       bytes_left -= trans;
377     }
378
379   *nbytes -= bytes_left;
380   return status;
381 }
382
383
384 /* get_oserror()-- Get the most recent operating system error.  For
385  * unix, this is errno. */
386
387 const char *
388 get_oserror (void)
389 {
390   return strerror (errno);
391 }
392
393
394 /*********************************************************************
395     File descriptor stream functions
396 *********************************************************************/
397
398
399 /* fd_flush()-- Write bytes that need to be written */
400
401 static try
402 fd_flush (unix_stream * s)
403 {
404   size_t writelen;
405
406   if (s->ndirty == 0)
407     return SUCCESS;
408   
409   if (s->file_length != -1 && s->physical_offset != s->dirty_offset &&
410       lseek (s->fd, s->dirty_offset, SEEK_SET) < 0)
411     return FAILURE;
412
413   writelen = s->ndirty;
414   if (do_write (s, s->buffer + (s->dirty_offset - s->buffer_offset),
415                 &writelen) != 0)
416     return FAILURE;
417
418   s->physical_offset = s->dirty_offset + writelen;
419
420   /* don't increment file_length if the file is non-seekable */
421   if (s->file_length != -1 && s->physical_offset > s->file_length)
422       s->file_length = s->physical_offset; 
423
424   s->ndirty -= writelen;
425   if (s->ndirty != 0)
426     return FAILURE;
427
428   return SUCCESS;
429 }
430
431
432 /* fd_alloc()-- Arrange a buffer such that the salloc() request can be
433  * satisfied.  This subroutine gets the buffer ready for whatever is
434  * to come next. */
435
436 static void
437 fd_alloc (unix_stream * s, gfc_offset where,
438           int *len __attribute__ ((unused)))
439 {
440   int n;
441
442   /* Salvage bytes currently within the buffer.  This is important for
443    * devices that cannot seek. */
444
445   if (s->buffer_offset <= where &&
446       where <= s->buffer_offset + s->active)
447     {
448
449       n = s->active - (where - s->buffer_offset);
450       memmove (s->buffer, s->buffer + (where - s->buffer_offset), n);
451
452       s->active = n;
453     }
454   else
455     {                           /* new buffer starts off empty */
456       s->active = 0;
457     }
458
459   s->buffer_offset = where;
460
461   s->len = BUFFER_SIZE;
462 }
463
464
465 /* fd_alloc_r_at()-- Allocate a stream buffer for reading.  Either
466  * we've already buffered the data or we need to load it.  Returns
467  * NULL on I/O error. */
468
469 static char *
470 fd_alloc_r_at (unix_stream * s, int *len, gfc_offset where)
471 {
472   gfc_offset m;
473
474   if (where == -1)
475     where = s->logical_offset;
476
477   if (s->buffer != NULL && s->buffer_offset <= where &&
478       where + *len <= s->buffer_offset + s->active)
479     {
480
481       /* Return a position within the current buffer */
482
483       s->logical_offset = where + *len;
484       return s->buffer + where - s->buffer_offset;
485     }
486
487   fd_alloc (s, where, len);
488
489   m = where + s->active;
490
491   if (s->physical_offset != m && lseek (s->fd, m, SEEK_SET) < 0)
492     return NULL;
493
494   /* do_read() hangs on read from terminals for *BSD-systems.  Only
495      use read() in that case.  */
496
497   if (s->special_file)
498     {
499       ssize_t n;
500
501       n = read (s->fd, s->buffer + s->active, s->len - s->active);
502       if (n < 0)
503         return NULL;
504
505       s->physical_offset = m + n;
506       s->active += n;
507     }
508   else
509     {
510       size_t n;
511
512       n = s->len - s->active;
513       if (do_read (s, s->buffer + s->active, &n) != 0)
514         return NULL;
515
516       s->physical_offset = m + n;
517       s->active += n;
518     }
519
520   if (s->active < *len)
521     *len = s->active;           /* Bytes actually available */
522
523   s->logical_offset = where + *len;
524
525   return s->buffer;
526 }
527
528
529 /* fd_alloc_w_at()-- Allocate a stream buffer for writing.  Either
530  * we've already buffered the data or we need to load it. */
531
532 static char *
533 fd_alloc_w_at (unix_stream * s, int *len, gfc_offset where)
534 {
535   gfc_offset n;
536
537   if (where == -1)
538     where = s->logical_offset;
539
540   if (s->buffer == NULL || s->buffer_offset > where ||
541       where + *len > s->buffer_offset + s->len)
542     {
543
544       if (fd_flush (s) == FAILURE)
545         return NULL;
546       fd_alloc (s, where, len);
547     }
548
549   /* Return a position within the current buffer */
550   if (s->ndirty == 0 
551       || where > s->dirty_offset + s->ndirty    
552       || s->dirty_offset > where + *len)
553     {  /* Discontiguous blocks, start with a clean buffer.  */  
554         /* Flush the buffer.  */  
555        if (s->ndirty != 0)    
556          fd_flush (s);  
557        s->dirty_offset = where;  
558        s->ndirty = *len;
559     }
560   else
561     {  
562       gfc_offset start;  /* Merge with the existing data.  */  
563       if (where < s->dirty_offset)    
564         start = where;  
565       else    
566         start = s->dirty_offset;  
567       if (where + *len > s->dirty_offset + s->ndirty)    
568         s->ndirty = where + *len - start;  
569       else    
570         s->ndirty = s->dirty_offset + s->ndirty - start;  
571         s->dirty_offset = start;
572     }
573
574   s->logical_offset = where + *len;
575
576   /* Don't increment file_length if the file is non-seekable.  */
577
578   if (s->file_length != -1 && s->logical_offset > s->file_length)
579      s->file_length = s->logical_offset;
580
581   n = s->logical_offset - s->buffer_offset;
582   if (n > s->active)
583     s->active = n;
584
585   return s->buffer + where - s->buffer_offset;
586 }
587
588
589 static try
590 fd_sfree (unix_stream * s)
591 {
592   if (s->ndirty != 0 &&
593       (options.all_unbuffered || s->unbuffered))
594     return fd_flush (s);
595
596   return SUCCESS;
597 }
598
599
600 static try
601 fd_seek (unix_stream * s, gfc_offset offset)
602 {
603
604   if (s->file_length == -1)
605     return SUCCESS;
606
607   if (s->physical_offset == offset) /* Are we lucky and avoid syscall?  */
608     {
609       s->logical_offset = offset;
610       return SUCCESS;
611     }
612
613   if (lseek (s->fd, offset, SEEK_SET) >= 0)
614     {
615       s->physical_offset = s->logical_offset = offset;
616       s->active = 0;
617       return SUCCESS;
618     }
619
620   return FAILURE;
621 }
622
623
624 /* truncate_file()-- Given a unit, truncate the file at the current
625  * position.  Sets the physical location to the new end of the file.
626  * Returns nonzero on error. */
627
628 static try
629 fd_truncate (unix_stream * s)
630 {
631   /* Non-seekable files, like terminals and fifo's fail the lseek so just
632      return success, there is nothing to truncate.  If its not a pipe there
633      is a real problem.  */
634   if (lseek (s->fd, s->logical_offset, SEEK_SET) == -1)
635     {
636       if (errno == ESPIPE)
637         return SUCCESS;
638       else
639         return FAILURE;
640     }
641
642   /* Using ftruncate on a seekable special file (like /dev/null)
643      is undefined, so we treat it as if the ftruncate succeeded.  */
644 #ifdef HAVE_FTRUNCATE
645   if (s->special_file || ftruncate (s->fd, s->logical_offset))
646 #else
647 #ifdef HAVE_CHSIZE
648   if (s->special_file || chsize (s->fd, s->logical_offset))
649 #endif
650 #endif
651     {
652       s->physical_offset = s->file_length = 0;
653       return SUCCESS;
654     }
655
656   s->physical_offset = s->file_length = s->logical_offset;
657   s->active = 0;
658   return SUCCESS;
659 }
660
661
662 /* Similar to memset(), but operating on a stream instead of a string.
663    Takes care of not using too much memory.  */
664
665 static try
666 fd_sset (unix_stream * s, int c, size_t n)
667 {
668   size_t bytes_left;
669   int trans;
670   void *p;
671
672   bytes_left = n;
673
674   while (bytes_left > 0)
675     {
676       /* memset() in chunks of BUFFER_SIZE.  */
677       trans = (bytes_left < BUFFER_SIZE) ? bytes_left : BUFFER_SIZE;
678
679       p = fd_alloc_w_at (s, &trans, -1);
680       if (p)
681           memset (p, c, trans);
682       else
683         return FAILURE;
684
685       bytes_left -= trans;
686     }
687
688   return SUCCESS;
689 }
690
691
692 /* Stream read function. Avoids using a buffer for big reads. The
693    interface is like POSIX read(), but the nbytes argument is a
694    pointer; on return it contains the number of bytes written. The
695    function return value is the status indicator (0 for success).  */
696
697 static int
698 fd_read (unix_stream * s, void * buf, size_t * nbytes)
699 {
700   void *p;
701   int tmp, status;
702
703   if (*nbytes < BUFFER_SIZE && !s->unbuffered)
704     {
705       tmp = *nbytes;
706       p = fd_alloc_r_at (s, &tmp, -1);
707       if (p)
708         {
709           *nbytes = tmp;
710           memcpy (buf, p, *nbytes);
711           return 0;
712         }
713       else
714         {
715           *nbytes = 0;
716           return errno;
717         }
718     }
719
720   /* If the request is bigger than BUFFER_SIZE we flush the buffers
721      and read directly.  */
722   if (fd_flush (s) == FAILURE)
723     {
724       *nbytes = 0;
725       return errno;
726     }
727
728   if (is_seekable ((stream *) s) && fd_seek (s, s->logical_offset) == FAILURE)
729     {
730       *nbytes = 0;
731       return errno;
732     }
733
734   status = do_read (s, buf, nbytes);
735   reset_stream (s, *nbytes);
736   return status;
737 }
738
739
740 /* Stream write function. Avoids using a buffer for big writes. The
741    interface is like POSIX write(), but the nbytes argument is a
742    pointer; on return it contains the number of bytes written. The
743    function return value is the status indicator (0 for success).  */
744
745 static int
746 fd_write (unix_stream * s, const void * buf, size_t * nbytes)
747 {
748   void *p;
749   int tmp, status;
750
751   if (*nbytes < BUFFER_SIZE && !s->unbuffered)
752     {
753       tmp = *nbytes;
754       p = fd_alloc_w_at (s, &tmp, -1);
755       if (p)
756         {
757           *nbytes = tmp;
758           memcpy (p, buf, *nbytes);
759           return 0;
760         }
761       else
762         {
763           *nbytes = 0;
764           return errno;
765         }
766     }
767
768   /* If the request is bigger than BUFFER_SIZE we flush the buffers
769      and write directly.  */
770   if (fd_flush (s) == FAILURE)
771     {
772       *nbytes = 0;
773       return errno;
774     }
775
776   if (is_seekable ((stream *) s) && fd_seek (s, s->logical_offset) == FAILURE)
777     {
778       *nbytes = 0;
779       return errno;
780     }
781
782   status =  do_write (s, buf, nbytes);
783   reset_stream (s, *nbytes);
784   return status;
785 }
786
787
788 static try
789 fd_close (unix_stream * s)
790 {
791   if (fd_flush (s) == FAILURE)
792     return FAILURE;
793
794   if (s->fd != STDOUT_FILENO && s->fd != STDERR_FILENO)
795     {
796       if (close (s->fd) < 0)
797         return FAILURE;
798     }
799
800   free_mem (s);
801
802   return SUCCESS;
803 }
804
805
806 static void
807 fd_open (unix_stream * s)
808 {
809   if (isatty (s->fd))
810     s->unbuffered = 1;
811
812   s->st.alloc_r_at = (void *) fd_alloc_r_at;
813   s->st.alloc_w_at = (void *) fd_alloc_w_at;
814   s->st.sfree = (void *) fd_sfree;
815   s->st.close = (void *) fd_close;
816   s->st.seek = (void *) fd_seek;
817   s->st.truncate = (void *) fd_truncate;
818   s->st.read = (void *) fd_read;
819   s->st.write = (void *) fd_write;
820   s->st.set = (void *) fd_sset;
821
822 }
823
824
825
826
827 /*********************************************************************
828   memory stream functions - These are used for internal files
829
830   The idea here is that a single stream structure is created and all
831   requests must be satisfied from it.  The location and size of the
832   buffer is the character variable supplied to the READ or WRITE
833   statement.
834
835 *********************************************************************/
836
837
838 static char *
839 mem_alloc_r_at (int_stream * s, int *len, gfc_offset where)
840 {
841   gfc_offset n;
842
843   if (where == -1)
844     where = s->logical_offset;
845
846   if (where < s->buffer_offset || where > s->buffer_offset + s->active)
847     return NULL;
848
849   s->logical_offset = where + *len;
850
851   n = s->buffer_offset + s->active - where;
852   if (*len > n)
853     *len = n;
854
855   return s->buffer + (where - s->buffer_offset);
856 }
857
858
859 static char *
860 mem_alloc_w_at (int_stream * s, int *len, gfc_offset where)
861 {
862   gfc_offset m;
863
864   assert (*len >= 0);  /* Negative values not allowed. */
865   
866   if (where == -1)
867     where = s->logical_offset;
868
869   m = where + *len;
870
871   if (where < s->buffer_offset)
872     return NULL;
873
874   if (m > s->file_length)
875     return NULL;
876
877   s->logical_offset = m;
878
879   return s->buffer + (where - s->buffer_offset);
880 }
881
882
883 /* Stream read function for internal units. This is not actually used
884    at the moment, as all internal IO is formatted and the formatted IO
885    routines use mem_alloc_r_at.  */
886
887 static int
888 mem_read (int_stream * s, void * buf, size_t * nbytes)
889 {
890   void *p;
891   int tmp;
892
893   tmp = *nbytes;
894   p = mem_alloc_r_at (s, &tmp, -1);
895   if (p)
896     {
897       *nbytes = tmp;
898       memcpy (buf, p, *nbytes);
899       return 0;
900     }
901   else
902     {
903       *nbytes = 0;
904       return errno;
905     }
906 }
907
908
909 /* Stream write function for internal units. This is not actually used
910    at the moment, as all internal IO is formatted and the formatted IO
911    routines use mem_alloc_w_at.  */
912
913 static int
914 mem_write (int_stream * s, const void * buf, size_t * nbytes)
915 {
916   void *p;
917   int tmp;
918
919   errno = 0;
920
921   tmp = *nbytes;
922   p = mem_alloc_w_at (s, &tmp, -1);
923   if (p)
924     {
925       *nbytes = tmp;
926       memcpy (p, buf, *nbytes);
927       return 0;
928     }
929   else
930     {
931       *nbytes = 0;
932       return errno;
933     }
934 }
935
936
937 static int
938 mem_seek (int_stream * s, gfc_offset offset)
939 {
940   if (offset > s->file_length)
941     {
942       errno = ESPIPE;
943       return FAILURE;
944     }
945
946   s->logical_offset = offset;
947   return SUCCESS;
948 }
949
950
951 static try
952 mem_set (int_stream * s, int c, size_t n)
953 {
954   void *p;
955   int len;
956
957   len = n;
958   
959   p = mem_alloc_w_at (s, &len, -1);
960   if (p)
961     {
962       memset (p, c, len);
963       return SUCCESS;
964     }
965   else
966     return FAILURE;
967 }
968
969
970 static int
971 mem_truncate (int_stream * s __attribute__ ((unused)))
972 {
973   return SUCCESS;
974 }
975
976
977 static try
978 mem_close (int_stream * s)
979 {
980   if (s != NULL)
981     free_mem (s);
982
983   return SUCCESS;
984 }
985
986
987 static try
988 mem_sfree (int_stream * s __attribute__ ((unused)))
989 {
990   return SUCCESS;
991 }
992
993
994
995 /*********************************************************************
996   Public functions -- A reimplementation of this module needs to
997   define functional equivalents of the following.
998 *********************************************************************/
999
1000 /* empty_internal_buffer()-- Zero the buffer of Internal file */
1001
1002 void
1003 empty_internal_buffer(stream *strm)
1004 {
1005   int_stream * s = (int_stream *) strm;
1006   memset(s->buffer, ' ', s->file_length);
1007 }
1008
1009 /* open_internal()-- Returns a stream structure from an internal file */
1010
1011 stream *
1012 open_internal (char *base, int length)
1013 {
1014   int_stream *s;
1015
1016   s = get_mem (sizeof (int_stream));
1017   memset (s, '\0', sizeof (int_stream));
1018
1019   s->buffer = base;
1020   s->buffer_offset = 0;
1021
1022   s->logical_offset = 0;
1023   s->active = s->file_length = length;
1024
1025   s->st.alloc_r_at = (void *) mem_alloc_r_at;
1026   s->st.alloc_w_at = (void *) mem_alloc_w_at;
1027   s->st.sfree = (void *) mem_sfree;
1028   s->st.close = (void *) mem_close;
1029   s->st.seek = (void *) mem_seek;
1030   s->st.truncate = (void *) mem_truncate;
1031   s->st.read = (void *) mem_read;
1032   s->st.write = (void *) mem_write;
1033   s->st.set = (void *) mem_set;
1034
1035   return (stream *) s;
1036 }
1037
1038
1039 /* fd_to_stream()-- Given an open file descriptor, build a stream
1040  * around it. */
1041
1042 static stream *
1043 fd_to_stream (int fd, int prot)
1044 {
1045   struct stat statbuf;
1046   unix_stream *s;
1047
1048   s = get_mem (sizeof (unix_stream));
1049   memset (s, '\0', sizeof (unix_stream));
1050
1051   s->fd = fd;
1052   s->buffer_offset = 0;
1053   s->physical_offset = 0;
1054   s->logical_offset = 0;
1055   s->prot = prot;
1056
1057   /* Get the current length of the file. */
1058
1059   fstat (fd, &statbuf);
1060
1061   if (lseek (fd, 0, SEEK_CUR) == (off_t) -1)
1062     s->file_length = -1;
1063   else
1064     s->file_length = S_ISREG (statbuf.st_mode) ? statbuf.st_size : -1;
1065
1066   s->special_file = !S_ISREG (statbuf.st_mode);
1067
1068   fd_open (s);
1069
1070   return (stream *) s;
1071 }
1072
1073
1074 /* Given the Fortran unit number, convert it to a C file descriptor.  */
1075
1076 int
1077 unit_to_fd (int unit)
1078 {
1079   gfc_unit *us;
1080   int fd;
1081
1082   us = find_unit (unit);
1083   if (us == NULL)
1084     return -1;
1085
1086   fd = ((unix_stream *) us->s)->fd;
1087   unlock_unit (us);
1088   return fd;
1089 }
1090
1091
1092 /* unpack_filename()-- Given a fortran string and a pointer to a
1093  * buffer that is PATH_MAX characters, convert the fortran string to a
1094  * C string in the buffer.  Returns nonzero if this is not possible.  */
1095
1096 int
1097 unpack_filename (char *cstring, const char *fstring, int len)
1098 {
1099   len = fstrlen (fstring, len);
1100   if (len >= PATH_MAX)
1101     return 1;
1102
1103   memmove (cstring, fstring, len);
1104   cstring[len] = '\0';
1105
1106   return 0;
1107 }
1108
1109
1110 /* tempfile()-- Generate a temporary filename for a scratch file and
1111  * open it.  mkstemp() opens the file for reading and writing, but the
1112  * library mode prevents anything that is not allowed.  The descriptor
1113  * is returned, which is -1 on error.  The template is pointed to by 
1114  * opp->file, which is copied into the unit structure
1115  * and freed later. */
1116
1117 static int
1118 tempfile (st_parameter_open *opp)
1119 {
1120   const char *tempdir;
1121   char *template;
1122   int fd;
1123
1124   tempdir = getenv ("GFORTRAN_TMPDIR");
1125   if (tempdir == NULL)
1126     tempdir = getenv ("TMP");
1127   if (tempdir == NULL)
1128     tempdir = getenv ("TEMP");
1129   if (tempdir == NULL)
1130     tempdir = DEFAULT_TEMPDIR;
1131
1132   template = get_mem (strlen (tempdir) + 20);
1133
1134   st_sprintf (template, "%s/gfortrantmpXXXXXX", tempdir);
1135
1136 #ifdef HAVE_MKSTEMP
1137
1138   fd = mkstemp (template);
1139
1140 #else /* HAVE_MKSTEMP */
1141
1142   if (mktemp (template))
1143     do
1144 #if defined(HAVE_CRLF) && defined(O_BINARY)
1145       fd = open (template, O_RDWR | O_CREAT | O_EXCL | O_BINARY,
1146                  S_IREAD | S_IWRITE);
1147 #else
1148       fd = open (template, O_RDWR | O_CREAT | O_EXCL, S_IREAD | S_IWRITE);
1149 #endif
1150     while (!(fd == -1 && errno == EEXIST) && mktemp (template));
1151   else
1152     fd = -1;
1153
1154 #endif /* HAVE_MKSTEMP */
1155
1156   if (fd < 0)
1157     free_mem (template);
1158   else
1159     {
1160       opp->file = template;
1161       opp->file_len = strlen (template);        /* Don't include trailing nul */
1162     }
1163
1164   return fd;
1165 }
1166
1167
1168 /* regular_file()-- Open a regular file.
1169  * Change flags->action if it is ACTION_UNSPECIFIED on entry,
1170  * unless an error occurs.
1171  * Returns the descriptor, which is less than zero on error. */
1172
1173 static int
1174 regular_file (st_parameter_open *opp, unit_flags *flags)
1175 {
1176   char path[PATH_MAX + 1];
1177   int mode;
1178   int rwflag;
1179   int crflag;
1180   int fd;
1181
1182   if (unpack_filename (path, opp->file, opp->file_len))
1183     {
1184       errno = ENOENT;           /* Fake an OS error */
1185       return -1;
1186     }
1187
1188   rwflag = 0;
1189
1190   switch (flags->action)
1191     {
1192     case ACTION_READ:
1193       rwflag = O_RDONLY;
1194       break;
1195
1196     case ACTION_WRITE:
1197       rwflag = O_WRONLY;
1198       break;
1199
1200     case ACTION_READWRITE:
1201     case ACTION_UNSPECIFIED:
1202       rwflag = O_RDWR;
1203       break;
1204
1205     default:
1206       internal_error (&opp->common, "regular_file(): Bad action");
1207     }
1208
1209   switch (flags->status)
1210     {
1211     case STATUS_NEW:
1212       crflag = O_CREAT | O_EXCL;
1213       break;
1214
1215     case STATUS_OLD:            /* open will fail if the file does not exist*/
1216       crflag = 0;
1217       break;
1218
1219     case STATUS_UNKNOWN:
1220     case STATUS_SCRATCH:
1221       crflag = O_CREAT;
1222       break;
1223
1224     case STATUS_REPLACE:
1225       crflag = O_CREAT | O_TRUNC;
1226       break;
1227
1228     default:
1229       internal_error (&opp->common, "regular_file(): Bad status");
1230     }
1231
1232   /* rwflag |= O_LARGEFILE; */
1233
1234 #if defined(HAVE_CRLF) && defined(O_BINARY)
1235   crflag |= O_BINARY;
1236 #endif
1237
1238   mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
1239   fd = open (path, rwflag | crflag, mode);
1240   if (flags->action != ACTION_UNSPECIFIED)
1241     return fd;
1242
1243   if (fd >= 0)
1244     {
1245       flags->action = ACTION_READWRITE;
1246       return fd;
1247     }
1248   if (errno != EACCES && errno != EROFS)
1249      return fd;
1250
1251   /* retry for read-only access */
1252   rwflag = O_RDONLY;
1253   fd = open (path, rwflag | crflag, mode);
1254   if (fd >=0)
1255     {
1256       flags->action = ACTION_READ;
1257       return fd;               /* success */
1258     }
1259   
1260   if (errno != EACCES)
1261     return fd;                 /* failure */
1262
1263   /* retry for write-only access */
1264   rwflag = O_WRONLY;
1265   fd = open (path, rwflag | crflag, mode);
1266   if (fd >=0)
1267     {
1268       flags->action = ACTION_WRITE;
1269       return fd;               /* success */
1270     }
1271   return fd;                   /* failure */
1272 }
1273
1274
1275 /* open_external()-- Open an external file, unix specific version.
1276  * Change flags->action if it is ACTION_UNSPECIFIED on entry.
1277  * Returns NULL on operating system error. */
1278
1279 stream *
1280 open_external (st_parameter_open *opp, unit_flags *flags)
1281 {
1282   int fd, prot;
1283
1284   if (flags->status == STATUS_SCRATCH)
1285     {
1286       fd = tempfile (opp);
1287       if (flags->action == ACTION_UNSPECIFIED)
1288         flags->action = ACTION_READWRITE;
1289
1290 #if HAVE_UNLINK_OPEN_FILE
1291       /* We can unlink scratch files now and it will go away when closed. */
1292       if (fd >= 0)
1293         unlink (opp->file);
1294 #endif
1295     }
1296   else
1297     {
1298       /* regular_file resets flags->action if it is ACTION_UNSPECIFIED and
1299        * if it succeeds */
1300       fd = regular_file (opp, flags);
1301     }
1302
1303   if (fd < 0)
1304     return NULL;
1305   fd = fix_fd (fd);
1306
1307   switch (flags->action)
1308     {
1309     case ACTION_READ:
1310       prot = PROT_READ;
1311       break;
1312
1313     case ACTION_WRITE:
1314       prot = PROT_WRITE;
1315       break;
1316
1317     case ACTION_READWRITE:
1318       prot = PROT_READ | PROT_WRITE;
1319       break;
1320
1321     default:
1322       internal_error (&opp->common, "open_external(): Bad action");
1323     }
1324
1325   return fd_to_stream (fd, prot);
1326 }
1327
1328
1329 /* input_stream()-- Return a stream pointer to the default input stream.
1330  * Called on initialization. */
1331
1332 stream *
1333 input_stream (void)
1334 {
1335   return fd_to_stream (STDIN_FILENO, PROT_READ);
1336 }
1337
1338
1339 /* output_stream()-- Return a stream pointer to the default output stream.
1340  * Called on initialization. */
1341
1342 stream *
1343 output_stream (void)
1344 {
1345 #if defined(HAVE_CRLF) && defined(HAVE_SETMODE)
1346   setmode (STDOUT_FILENO, O_BINARY);
1347 #endif
1348   return fd_to_stream (STDOUT_FILENO, PROT_WRITE);
1349 }
1350
1351
1352 /* error_stream()-- Return a stream pointer to the default error stream.
1353  * Called on initialization. */
1354
1355 stream *
1356 error_stream (void)
1357 {
1358 #if defined(HAVE_CRLF) && defined(HAVE_SETMODE)
1359   setmode (STDERR_FILENO, O_BINARY);
1360 #endif
1361   return fd_to_stream (STDERR_FILENO, PROT_WRITE);
1362 }
1363
1364 /* init_error_stream()-- Return a pointer to the error stream.  This
1365  * subroutine is called when the stream is needed, rather than at
1366  * initialization.  We want to work even if memory has been seriously
1367  * corrupted. */
1368
1369 stream *
1370 init_error_stream (unix_stream *error)
1371 {
1372   memset (error, '\0', sizeof (*error));
1373
1374   error->fd = options.use_stderr ? STDERR_FILENO : STDOUT_FILENO;
1375
1376   error->st.alloc_w_at = (void *) fd_alloc_w_at;
1377   error->st.sfree = (void *) fd_sfree;
1378
1379   error->unbuffered = 1;
1380
1381   return (stream *) error;
1382 }
1383
1384 /* st_printf()-- simple printf() function for streams that handles the
1385  * formats %d, %s and %c.  This function handles printing of error
1386  * messages that originate within the library itself, not from a user
1387  * program. */
1388
1389 int
1390 st_printf (const char *format, ...)
1391 {
1392   int count, total;
1393   va_list arg;
1394   char *p;
1395   const char *q;
1396   stream *s;
1397   char itoa_buf[GFC_ITOA_BUF_SIZE];
1398   unix_stream err_stream;
1399
1400   total = 0;
1401   s = init_error_stream (&err_stream);
1402   va_start (arg, format);
1403
1404   for (;;)
1405     {
1406       count = 0;
1407
1408       while (format[count] != '%' && format[count] != '\0')
1409         count++;
1410
1411       if (count != 0)
1412         {
1413           p = salloc_w (s, &count);
1414           memmove (p, format, count);
1415           sfree (s);
1416         }
1417
1418       total += count;
1419       format += count;
1420       if (*format++ == '\0')
1421         break;
1422
1423       switch (*format)
1424         {
1425         case 'c':
1426           count = 1;
1427
1428           p = salloc_w (s, &count);
1429           *p = (char) va_arg (arg, int);
1430
1431           sfree (s);
1432           break;
1433
1434         case 'd':
1435           q = gfc_itoa (va_arg (arg, int), itoa_buf, sizeof (itoa_buf));
1436           count = strlen (q);
1437
1438           p = salloc_w (s, &count);
1439           memmove (p, q, count);
1440           sfree (s);
1441           break;
1442
1443         case 'x':
1444           q = xtoa (va_arg (arg, unsigned), itoa_buf, sizeof (itoa_buf));
1445           count = strlen (q);
1446
1447           p = salloc_w (s, &count);
1448           memmove (p, q, count);
1449           sfree (s);
1450           break;
1451
1452         case 's':
1453           q = va_arg (arg, char *);
1454           count = strlen (q);
1455
1456           p = salloc_w (s, &count);
1457           memmove (p, q, count);
1458           sfree (s);
1459           break;
1460
1461         case '\0':
1462           return total;
1463
1464         default:
1465           count = 2;
1466           p = salloc_w (s, &count);
1467           p[0] = format[-1];
1468           p[1] = format[0];
1469           sfree (s);
1470           break;
1471         }
1472
1473       total += count;
1474       format++;
1475     }
1476
1477   va_end (arg);
1478   return total;
1479 }
1480
1481
1482 /* compare_file_filename()-- Given an open stream and a fortran string
1483  * that is a filename, figure out if the file is the same as the
1484  * filename. */
1485
1486 int
1487 compare_file_filename (gfc_unit *u, const char *name, int len)
1488 {
1489   char path[PATH_MAX + 1];
1490   struct stat st1;
1491 #ifdef HAVE_WORKING_STAT
1492   struct stat st2;
1493 #endif
1494
1495   if (unpack_filename (path, name, len))
1496     return 0;                   /* Can't be the same */
1497
1498   /* If the filename doesn't exist, then there is no match with the
1499    * existing file. */
1500
1501   if (stat (path, &st1) < 0)
1502     return 0;
1503
1504 #ifdef HAVE_WORKING_STAT
1505   fstat (((unix_stream *) (u->s))->fd, &st2);
1506   return (st1.st_dev == st2.st_dev) && (st1.st_ino == st2.st_ino);
1507 #else
1508   if (len != u->file_len)
1509     return 0;
1510   return (memcmp(path, u->file, len) == 0);
1511 #endif
1512 }
1513
1514
1515 #ifdef HAVE_WORKING_STAT
1516 # define FIND_FILE0_DECL struct stat *st
1517 # define FIND_FILE0_ARGS st
1518 #else
1519 # define FIND_FILE0_DECL const char *file, gfc_charlen_type file_len
1520 # define FIND_FILE0_ARGS file, file_len
1521 #endif
1522
1523 /* find_file0()-- Recursive work function for find_file() */
1524
1525 static gfc_unit *
1526 find_file0 (gfc_unit *u, FIND_FILE0_DECL)
1527 {
1528   gfc_unit *v;
1529
1530   if (u == NULL)
1531     return NULL;
1532
1533 #ifdef HAVE_WORKING_STAT
1534   if (u->s != NULL
1535       && fstat (((unix_stream *) u->s)->fd, &st[1]) >= 0 &&
1536       st[0].st_dev == st[1].st_dev && st[0].st_ino == st[1].st_ino)
1537     return u;
1538 #else
1539   if (compare_string (u->file_len, u->file, file_len, file) == 0)
1540     return u;
1541 #endif
1542
1543   v = find_file0 (u->left, FIND_FILE0_ARGS);
1544   if (v != NULL)
1545     return v;
1546
1547   v = find_file0 (u->right, FIND_FILE0_ARGS);
1548   if (v != NULL)
1549     return v;
1550
1551   return NULL;
1552 }
1553
1554
1555 /* find_file()-- Take the current filename and see if there is a unit
1556  * that has the file already open.  Returns a pointer to the unit if so. */
1557
1558 gfc_unit *
1559 find_file (const char *file, gfc_charlen_type file_len)
1560 {
1561   char path[PATH_MAX + 1];
1562   struct stat st[2];
1563   gfc_unit *u;
1564
1565   if (unpack_filename (path, file, file_len))
1566     return NULL;
1567
1568   if (stat (path, &st[0]) < 0)
1569     return NULL;
1570
1571   __gthread_mutex_lock (&unit_lock);
1572 retry:
1573   u = find_file0 (unit_root, FIND_FILE0_ARGS);
1574   if (u != NULL)
1575     {
1576       /* Fast path.  */
1577       if (! __gthread_mutex_trylock (&u->lock))
1578         {
1579           /* assert (u->closed == 0); */
1580           __gthread_mutex_unlock (&unit_lock);
1581           return u;
1582         }
1583
1584       inc_waiting_locked (u);
1585     }
1586   __gthread_mutex_unlock (&unit_lock);
1587   if (u != NULL)
1588     {
1589       __gthread_mutex_lock (&u->lock);
1590       if (u->closed)
1591         {
1592           __gthread_mutex_lock (&unit_lock);
1593           __gthread_mutex_unlock (&u->lock);
1594           if (predec_waiting_locked (u) == 0)
1595             free_mem (u);
1596           goto retry;
1597         }
1598
1599       dec_waiting_unlocked (u);
1600     }
1601   return u;
1602 }
1603
1604 static gfc_unit *
1605 flush_all_units_1 (gfc_unit *u, int min_unit)
1606 {
1607   while (u != NULL)
1608     {
1609       if (u->unit_number > min_unit)
1610         {
1611           gfc_unit *r = flush_all_units_1 (u->left, min_unit);
1612           if (r != NULL)
1613             return r;
1614         }
1615       if (u->unit_number >= min_unit)
1616         {
1617           if (__gthread_mutex_trylock (&u->lock))
1618             return u;
1619           if (u->s)
1620             flush (u->s);
1621           __gthread_mutex_unlock (&u->lock);
1622         }
1623       u = u->right;
1624     }
1625   return NULL;
1626 }
1627
1628 void
1629 flush_all_units (void)
1630 {
1631   gfc_unit *u;
1632   int min_unit = 0;
1633
1634   __gthread_mutex_lock (&unit_lock);
1635   do
1636     {
1637       u = flush_all_units_1 (unit_root, min_unit);
1638       if (u != NULL)
1639         inc_waiting_locked (u);
1640       __gthread_mutex_unlock (&unit_lock);
1641       if (u == NULL)
1642         return;
1643
1644       __gthread_mutex_lock (&u->lock);
1645
1646       min_unit = u->unit_number + 1;
1647
1648       if (u->closed == 0)
1649         {
1650           flush (u->s);
1651           __gthread_mutex_lock (&unit_lock);
1652           __gthread_mutex_unlock (&u->lock);
1653           (void) predec_waiting_locked (u);
1654         }
1655       else
1656         {
1657           __gthread_mutex_lock (&unit_lock);
1658           __gthread_mutex_unlock (&u->lock);
1659           if (predec_waiting_locked (u) == 0)
1660             free_mem (u);
1661         }
1662     }
1663   while (1);
1664 }
1665
1666
1667 /* stream_at_bof()-- Returns nonzero if the stream is at the beginning
1668  * of the file. */
1669
1670 int
1671 stream_at_bof (stream * s)
1672 {
1673   unix_stream *us;
1674
1675   if (!is_seekable (s))
1676     return 0;
1677
1678   us = (unix_stream *) s;
1679
1680   return us->logical_offset == 0;
1681 }
1682
1683
1684 /* stream_at_eof()-- Returns nonzero if the stream is at the end
1685  * of the file. */
1686
1687 int
1688 stream_at_eof (stream * s)
1689 {
1690   unix_stream *us;
1691
1692   if (!is_seekable (s))
1693     return 0;
1694
1695   us = (unix_stream *) s;
1696
1697   return us->logical_offset == us->dirty_offset;
1698 }
1699
1700
1701 /* delete_file()-- Given a unit structure, delete the file associated
1702  * with the unit.  Returns nonzero if something went wrong. */
1703
1704 int
1705 delete_file (gfc_unit * u)
1706 {
1707   char path[PATH_MAX + 1];
1708
1709   if (unpack_filename (path, u->file, u->file_len))
1710     {                           /* Shouldn't be possible */
1711       errno = ENOENT;
1712       return 1;
1713     }
1714
1715   return unlink (path);
1716 }
1717
1718
1719 /* file_exists()-- Returns nonzero if the current filename exists on
1720  * the system */
1721
1722 int
1723 file_exists (const char *file, gfc_charlen_type file_len)
1724 {
1725   char path[PATH_MAX + 1];
1726   struct stat statbuf;
1727
1728   if (unpack_filename (path, file, file_len))
1729     return 0;
1730
1731   if (stat (path, &statbuf) < 0)
1732     return 0;
1733
1734   return 1;
1735 }
1736
1737
1738
1739 static const char yes[] = "YES", no[] = "NO", unknown[] = "UNKNOWN";
1740
1741 /* inquire_sequential()-- Given a fortran string, determine if the
1742  * file is suitable for sequential access.  Returns a C-style
1743  * string. */
1744
1745 const char *
1746 inquire_sequential (const char *string, int len)
1747 {
1748   char path[PATH_MAX + 1];
1749   struct stat statbuf;
1750
1751   if (string == NULL ||
1752       unpack_filename (path, string, len) || stat (path, &statbuf) < 0)
1753     return unknown;
1754
1755   if (S_ISREG (statbuf.st_mode) ||
1756       S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode))
1757     return yes;
1758
1759   if (S_ISDIR (statbuf.st_mode) || S_ISBLK (statbuf.st_mode))
1760     return no;
1761
1762   return unknown;
1763 }
1764
1765
1766 /* inquire_direct()-- Given a fortran string, determine if the file is
1767  * suitable for direct access.  Returns a C-style string. */
1768
1769 const char *
1770 inquire_direct (const char *string, int len)
1771 {
1772   char path[PATH_MAX + 1];
1773   struct stat statbuf;
1774
1775   if (string == NULL ||
1776       unpack_filename (path, string, len) || stat (path, &statbuf) < 0)
1777     return unknown;
1778
1779   if (S_ISREG (statbuf.st_mode) || S_ISBLK (statbuf.st_mode))
1780     return yes;
1781
1782   if (S_ISDIR (statbuf.st_mode) ||
1783       S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode))
1784     return no;
1785
1786   return unknown;
1787 }
1788
1789
1790 /* inquire_formatted()-- Given a fortran string, determine if the file
1791  * is suitable for formatted form.  Returns a C-style string. */
1792
1793 const char *
1794 inquire_formatted (const char *string, int len)
1795 {
1796   char path[PATH_MAX + 1];
1797   struct stat statbuf;
1798
1799   if (string == NULL ||
1800       unpack_filename (path, string, len) || stat (path, &statbuf) < 0)
1801     return unknown;
1802
1803   if (S_ISREG (statbuf.st_mode) ||
1804       S_ISBLK (statbuf.st_mode) ||
1805       S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode))
1806     return yes;
1807
1808   if (S_ISDIR (statbuf.st_mode))
1809     return no;
1810
1811   return unknown;
1812 }
1813
1814
1815 /* inquire_unformatted()-- Given a fortran string, determine if the file
1816  * is suitable for unformatted form.  Returns a C-style string. */
1817
1818 const char *
1819 inquire_unformatted (const char *string, int len)
1820 {
1821   return inquire_formatted (string, len);
1822 }
1823
1824
1825 /* inquire_access()-- Given a fortran string, determine if the file is
1826  * suitable for access. */
1827
1828 static const char *
1829 inquire_access (const char *string, int len, int mode)
1830 {
1831   char path[PATH_MAX + 1];
1832
1833   if (string == NULL || unpack_filename (path, string, len) ||
1834       access (path, mode) < 0)
1835     return no;
1836
1837   return yes;
1838 }
1839
1840
1841 /* inquire_read()-- Given a fortran string, determine if the file is
1842  * suitable for READ access. */
1843
1844 const char *
1845 inquire_read (const char *string, int len)
1846 {
1847   return inquire_access (string, len, R_OK);
1848 }
1849
1850
1851 /* inquire_write()-- Given a fortran string, determine if the file is
1852  * suitable for READ access. */
1853
1854 const char *
1855 inquire_write (const char *string, int len)
1856 {
1857   return inquire_access (string, len, W_OK);
1858 }
1859
1860
1861 /* inquire_readwrite()-- Given a fortran string, determine if the file is
1862  * suitable for read and write access. */
1863
1864 const char *
1865 inquire_readwrite (const char *string, int len)
1866 {
1867   return inquire_access (string, len, R_OK | W_OK);
1868 }
1869
1870
1871 /* file_length()-- Return the file length in bytes, -1 if unknown */
1872
1873 gfc_offset
1874 file_length (stream * s)
1875 {
1876   return ((unix_stream *) s)->file_length;
1877 }
1878
1879
1880 /* file_position()-- Return the current position of the file */
1881
1882 gfc_offset
1883 file_position (stream *s)
1884 {
1885   return ((unix_stream *) s)->logical_offset;
1886 }
1887
1888
1889 /* is_seekable()-- Return nonzero if the stream is seekable, zero if
1890  * it is not */
1891
1892 int
1893 is_seekable (stream *s)
1894 {
1895   /* By convention, if file_length == -1, the file is not
1896      seekable.  */
1897   return ((unix_stream *) s)->file_length!=-1;
1898 }
1899
1900
1901 /* is_special()-- Return nonzero if the stream is not a regular file.  */
1902
1903 int
1904 is_special (stream *s)
1905 {
1906   return ((unix_stream *) s)->special_file;
1907 }
1908
1909
1910 try
1911 flush (stream *s)
1912 {
1913   return fd_flush( (unix_stream *) s);
1914 }
1915
1916 int
1917 stream_isatty (stream *s)
1918 {
1919   return isatty (((unix_stream *) s)->fd);
1920 }
1921
1922 char *
1923 stream_ttyname (stream *s)
1924 {
1925 #ifdef HAVE_TTYNAME
1926   return ttyname (((unix_stream *) s)->fd);
1927 #else
1928   return NULL;
1929 #endif
1930 }
1931
1932 gfc_offset
1933 stream_offset (stream *s)
1934 {
1935   return (((unix_stream *) s)->logical_offset);
1936 }
1937
1938
1939 /* How files are stored:  This is an operating-system specific issue,
1940    and therefore belongs here.  There are three cases to consider.
1941
1942    Direct Access:
1943       Records are written as block of bytes corresponding to the record
1944       length of the file.  This goes for both formatted and unformatted
1945       records.  Positioning is done explicitly for each data transfer,
1946       so positioning is not much of an issue.
1947
1948    Sequential Formatted:
1949       Records are separated by newline characters.  The newline character
1950       is prohibited from appearing in a string.  If it does, this will be
1951       messed up on the next read.  End of file is also the end of a record.
1952
1953    Sequential Unformatted:
1954       In this case, we are merely copying bytes to and from main storage,
1955       yet we need to keep track of varying record lengths.  We adopt
1956       the solution used by f2c.  Each record contains a pair of length
1957       markers:
1958
1959         Length of record n in bytes
1960         Data of record n
1961         Length of record n in bytes
1962
1963         Length of record n+1 in bytes
1964         Data of record n+1
1965         Length of record n+1 in bytes
1966
1967      The length is stored at the end of a record to allow backspacing to the
1968      previous record.  Between data transfer statements, the file pointer
1969      is left pointing to the first length of the current record.
1970
1971      ENDFILE records are never explicitly stored.
1972
1973 */