OSDN Git Service

PR libfortran/27107
[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   char *buffer;
101   int len;                      /* Physical length of the current buffer */
102   int active;                   /* Length of valid bytes in the buffer */
103
104   int prot;
105   int ndirty;                   /* Dirty bytes starting at dirty_offset */
106
107   int special_file;             /* =1 if the fd refers to a special file */
108
109   unsigned unbuffered:1;
110
111   char small_buffer[BUFFER_SIZE];
112
113 }
114 unix_stream;
115
116 extern stream *init_error_stream (unix_stream *);
117 internal_proto(init_error_stream);
118
119
120 /* This implementation of stream I/O is based on the paper:
121  *
122  *  "Exploiting the advantages of mapped files for stream I/O",
123  *  O. Krieger, M. Stumm and R. Umrau, "Proceedings of the 1992 Winter
124  *  USENIX conference", p. 27-42.
125  *
126  * It differs in a number of ways from the version described in the
127  * paper.  First of all, threads are not an issue during I/O and we
128  * also don't have to worry about having multiple regions, since
129  * fortran's I/O model only allows you to be one place at a time.
130  *
131  * On the other hand, we have to be able to writing at the end of a
132  * stream, read from the start of a stream or read and write blocks of
133  * bytes from an arbitrary position.  After opening a file, a pointer
134  * to a stream structure is returned, which is used to handle file
135  * accesses until the file is closed.
136  *
137  * salloc_at_r(stream, len, where)-- Given a stream pointer, return a
138  * pointer to a block of memory that mirror the file at position
139  * 'where' that is 'len' bytes long.  The len integer is updated to
140  * reflect how many bytes were actually read.  The only reason for a
141  * short read is end of file.  The file pointer is updated.  The
142  * pointer is valid until the next call to salloc_*.
143  *
144  * salloc_at_w(stream, len, where)-- Given the stream pointer, returns
145  * a pointer to a block of memory that is updated to reflect the state
146  * of the file.  The length of the buffer is always equal to that
147  * requested.  The buffer must be completely set by the caller.  When
148  * data has been written, the sfree() function must be called to
149  * indicate that the caller is done writing data to the buffer.  This
150  * may or may not cause a physical write.
151  *
152  * Short forms of these are salloc_r() and salloc_w() which drop the
153  * 'where' parameter and use the current file pointer. */
154
155
156 /*move_pos_offset()--  Move the record pointer right or left
157  *relative to current position */
158
159 int
160 move_pos_offset (stream* st, int pos_off)
161 {
162   unix_stream * str = (unix_stream*)st;
163   if (pos_off < 0)
164     {
165       str->logical_offset += pos_off;
166
167       if (str->dirty_offset + str->ndirty > str->logical_offset)
168         {
169           if (str->ndirty + pos_off > 0)
170             str->ndirty += pos_off;
171           else
172             {
173               str->dirty_offset +=  pos_off + pos_off;
174               str->ndirty = 0;
175             }
176         }
177
178     return pos_off;
179   }
180   return 0;
181 }
182
183
184 /* fix_fd()-- Given a file descriptor, make sure it is not one of the
185  * standard descriptors, returning a non-standard descriptor.  If the
186  * user specifies that system errors should go to standard output,
187  * then closes standard output, we don't want the system errors to a
188  * file that has been given file descriptor 1 or 0.  We want to send
189  * the error to the invalid descriptor. */
190
191 static int
192 fix_fd (int fd)
193 {
194   int input, output, error;
195
196   input = output = error = 0;
197
198   /* Unix allocates the lowest descriptors first, so a loop is not
199      required, but this order is. */
200
201   if (fd == STDIN_FILENO)
202     {
203       fd = dup (fd);
204       input = 1;
205     }
206   if (fd == STDOUT_FILENO)
207     {
208       fd = dup (fd);
209       output = 1;
210     }
211   if (fd == STDERR_FILENO)
212     {
213       fd = dup (fd);
214       error = 1;
215     }
216
217   if (input)
218     close (STDIN_FILENO);
219   if (output)
220     close (STDOUT_FILENO);
221   if (error)
222     close (STDERR_FILENO);
223
224   return fd;
225 }
226
227 int
228 is_preconnected (stream * s)
229 {
230   int fd;
231
232   fd = ((unix_stream *) s)->fd;
233   if (fd == STDIN_FILENO || fd == STDOUT_FILENO || fd == STDERR_FILENO)
234     return 1;
235   else
236     return 0;
237 }
238
239 /* If the stream corresponds to a preconnected unit, we flush the
240    corresponding C stream.  This is bugware for mixed C-Fortran codes
241    where the C code doesn't flush I/O before returning.  */
242 void
243 flush_if_preconnected (stream * s)
244 {
245   int fd;
246
247   fd = ((unix_stream *) s)->fd;
248   if (fd == STDIN_FILENO)
249     fflush (stdin);
250   else if (fd == STDOUT_FILENO)
251     fflush (stdout);
252   else if (fd == STDERR_FILENO)
253     fflush (stderr);
254 }
255
256
257 /* Reset a stream after reading/writing. Assumes that the buffers have
258    been flushed.  */
259
260 inline static void
261 reset_stream (unix_stream * s, size_t bytes_rw)
262 {
263   s->physical_offset += bytes_rw;
264   s->logical_offset = s->physical_offset;
265   if (s->file_length != -1 && s->physical_offset > s->file_length)
266     s->file_length = s->physical_offset;
267 }
268
269
270 /* Read bytes into a buffer, allowing for short reads.  If the nbytes
271  * argument is less on return than on entry, it is because we've hit
272  * the end of file. */
273
274 static int
275 do_read (unix_stream * s, void * buf, size_t * nbytes)
276 {
277   ssize_t trans;
278   size_t bytes_left;
279   char *buf_st;
280   int status;
281
282   status = 0;
283   bytes_left = *nbytes;
284   buf_st = (char *) buf;
285
286   /* We must read in a loop since some systems don't restart system
287      calls in case of a signal.  */
288   while (bytes_left > 0)
289     {
290       /* Requests between SSIZE_MAX and SIZE_MAX are undefined by SUSv3,
291          so we must read in chunks smaller than SSIZE_MAX.  */
292       trans = (bytes_left < SSIZE_MAX) ? bytes_left : SSIZE_MAX;
293       trans = read (s->fd, buf_st, trans);
294       if (trans < 0)
295         {
296           if (errno == EINTR)
297             continue;
298           else
299             {
300               status = errno;
301               break;
302             }
303         }
304       else if (trans == 0) /* We hit EOF.  */
305         break;
306       buf_st += trans;
307       bytes_left -= trans;
308     }
309
310   *nbytes -= bytes_left;
311   return status;
312 }
313
314
315 /* Write a buffer to a stream, allowing for short writes.  */
316
317 static int
318 do_write (unix_stream * s, const void * buf, size_t * nbytes)
319 {
320   ssize_t trans;
321   size_t bytes_left;
322   char *buf_st;
323   int status;
324
325   status = 0;
326   bytes_left = *nbytes;
327   buf_st = (char *) buf;
328
329   /* We must write in a loop since some systems don't restart system
330      calls in case of a signal.  */
331   while (bytes_left > 0)
332     {
333       /* Requests between SSIZE_MAX and SIZE_MAX are undefined by SUSv3,
334          so we must write in chunks smaller than SSIZE_MAX.  */
335       trans = (bytes_left < SSIZE_MAX) ? bytes_left : SSIZE_MAX;
336       trans = write (s->fd, buf_st, trans);
337       if (trans < 0)
338         {
339           if (errno == EINTR)
340             continue;
341           else
342             {
343               status = errno;
344               break;
345             }
346         }
347       buf_st += trans;
348       bytes_left -= trans;
349     }
350
351   *nbytes -= bytes_left;
352   return status;
353 }
354
355
356 /* get_oserror()-- Get the most recent operating system error.  For
357  * unix, this is errno. */
358
359 const char *
360 get_oserror (void)
361 {
362   return strerror (errno);
363 }
364
365
366 /* sys_exit()-- Terminate the program with an exit code */
367
368 void
369 sys_exit (int code)
370 {
371   exit (code);
372 }
373
374
375 /*********************************************************************
376     File descriptor stream functions
377 *********************************************************************/
378
379
380 /* fd_flush()-- Write bytes that need to be written */
381
382 static try
383 fd_flush (unix_stream * s)
384 {
385   size_t writelen;
386
387   if (s->ndirty == 0)
388     return SUCCESS;
389   
390   if (s->file_length != -1 && s->physical_offset != s->dirty_offset &&
391       lseek (s->fd, s->dirty_offset, SEEK_SET) < 0)
392     return FAILURE;
393
394   writelen = s->ndirty;
395   if (do_write (s, s->buffer + (s->dirty_offset - s->buffer_offset),
396                 &writelen) != 0)
397     return FAILURE;
398
399   s->physical_offset = s->dirty_offset + writelen;
400
401   /* don't increment file_length if the file is non-seekable */
402   if (s->file_length != -1 && s->physical_offset > s->file_length)
403       s->file_length = s->physical_offset; 
404
405   s->ndirty -= writelen;
406   if (s->ndirty != 0)
407     return FAILURE;
408
409   return SUCCESS;
410 }
411
412
413 /* fd_alloc()-- Arrange a buffer such that the salloc() request can be
414  * satisfied.  This subroutine gets the buffer ready for whatever is
415  * to come next. */
416
417 static void
418 fd_alloc (unix_stream * s, gfc_offset where,
419           int *len __attribute__ ((unused)))
420 {
421   char *new_buffer;
422   int n, read_len;
423
424   if (*len <= BUFFER_SIZE)
425     {
426       new_buffer = s->small_buffer;
427       read_len = BUFFER_SIZE;
428     }
429   else
430     {
431       new_buffer = get_mem (*len);
432       read_len = *len;
433     }
434
435   /* Salvage bytes currently within the buffer.  This is important for
436    * devices that cannot seek. */
437
438   if (s->buffer != NULL && s->buffer_offset <= where &&
439       where <= s->buffer_offset + s->active)
440     {
441
442       n = s->active - (where - s->buffer_offset);
443       memmove (new_buffer, s->buffer + (where - s->buffer_offset), n);
444
445       s->active = n;
446     }
447   else
448     {                           /* new buffer starts off empty */
449       s->active = 0;
450     }
451
452   s->buffer_offset = where;
453
454   /* free the old buffer if necessary */
455
456   if (s->buffer != NULL && s->buffer != s->small_buffer)
457     free_mem (s->buffer);
458
459   s->buffer = new_buffer;
460   s->len = read_len;
461 }
462
463
464 /* fd_alloc_r_at()-- Allocate a stream buffer for reading.  Either
465  * we've already buffered the data or we need to load it.  Returns
466  * NULL on I/O error. */
467
468 static char *
469 fd_alloc_r_at (unix_stream * s, int *len, gfc_offset where)
470 {
471   gfc_offset m;
472
473   if (where == -1)
474     where = s->logical_offset;
475
476   if (s->buffer != NULL && s->buffer_offset <= where &&
477       where + *len <= s->buffer_offset + s->active)
478     {
479
480       /* Return a position within the current buffer */
481
482       s->logical_offset = where + *len;
483       return s->buffer + where - s->buffer_offset;
484     }
485
486   fd_alloc (s, where, len);
487
488   m = where + s->active;
489
490   if (s->physical_offset != m && lseek (s->fd, m, SEEK_SET) < 0)
491     return NULL;
492
493   /* do_read() hangs on read from terminals for *BSD-systems.  Only
494      use read() in that case.  */
495
496   if (s->special_file)
497     {
498       ssize_t n;
499
500       n = read (s->fd, s->buffer + s->active, s->len - s->active);
501       if (n < 0)
502         return NULL;
503
504       s->physical_offset = where + n;
505       s->active += n;
506     }
507   else
508     {
509       size_t n;
510
511       n = s->len - s->active;
512       if (do_read (s, s->buffer + s->active, &n) != 0)
513         return NULL;
514
515       s->physical_offset = where + n;
516       s->active += n;
517     }
518
519   if (s->active < *len)
520     *len = s->active;           /* Bytes actually available */
521
522   s->logical_offset = where + *len;
523
524   return s->buffer;
525 }
526
527
528 /* fd_alloc_w_at()-- Allocate a stream buffer for writing.  Either
529  * we've already buffered the data or we need to load it. */
530
531 static char *
532 fd_alloc_w_at (unix_stream * s, int *len, gfc_offset where)
533 {
534   gfc_offset n;
535
536   if (where == -1)
537     where = s->logical_offset;
538
539   if (s->buffer == NULL || s->buffer_offset > where ||
540       where + *len > s->buffer_offset + s->len)
541     {
542
543       if (fd_flush (s) == FAILURE)
544         return NULL;
545       fd_alloc (s, where, len);
546     }
547
548   /* Return a position within the current buffer */
549   if (s->ndirty == 0 
550       || where > s->dirty_offset + s->ndirty    
551       || s->dirty_offset > where + *len)
552     {  /* Discontiguous blocks, start with a clean buffer.  */  
553         /* Flush the buffer.  */  
554        if (s->ndirty != 0)    
555          fd_flush (s);  
556        s->dirty_offset = where;  
557        s->ndirty = *len;
558     }
559   else
560     {  
561       gfc_offset start;  /* Merge with the existing data.  */  
562       if (where < s->dirty_offset)    
563         start = where;  
564       else    
565         start = s->dirty_offset;  
566       if (where + *len > s->dirty_offset + s->ndirty)    
567         s->ndirty = where + *len - start;  
568       else    
569         s->ndirty = s->dirty_offset + s->ndirty - start;  
570         s->dirty_offset = start;
571     }
572
573   s->logical_offset = where + *len;
574
575   /* Don't increment file_length if the file is non-seekable.  */
576
577   if (s->file_length != -1 && s->logical_offset > s->file_length)
578      s->file_length = s->logical_offset;
579
580   n = s->logical_offset - s->buffer_offset;
581   if (n > s->active)
582     s->active = n;
583
584   return s->buffer + where - s->buffer_offset;
585 }
586
587
588 static try
589 fd_sfree (unix_stream * s)
590 {
591   if (s->ndirty != 0 &&
592       (s->buffer != s->small_buffer || options.all_unbuffered ||
593        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   s->physical_offset = s->logical_offset = offset;
614   s->active = 0;
615
616   return (lseek (s->fd, offset, SEEK_SET) < 0) ? FAILURE : SUCCESS;
617 }
618
619
620 /* truncate_file()-- Given a unit, truncate the file at the current
621  * position.  Sets the physical location to the new end of the file.
622  * Returns nonzero on error. */
623
624 static try
625 fd_truncate (unix_stream * s)
626 {
627   /* Non-seekable files, like terminals and fifo's fail the lseek so just
628      return success, there is nothing to truncate.  If its not a pipe there
629      is a real problem.  */
630   if (lseek (s->fd, s->logical_offset, SEEK_SET) == -1)
631     {
632       if (errno == ESPIPE)
633         return SUCCESS;
634       else
635         return FAILURE;
636     }
637
638   /* Using ftruncate on a seekable special file (like /dev/null)
639      is undefined, so we treat it as if the ftruncate succeeded.  */
640 #ifdef HAVE_FTRUNCATE
641   if (s->special_file || ftruncate (s->fd, s->logical_offset))
642 #else
643 #ifdef HAVE_CHSIZE
644   if (s->special_file || chsize (s->fd, s->logical_offset))
645 #endif
646 #endif
647     {
648       s->physical_offset = s->file_length = 0;
649       return SUCCESS;
650     }
651
652   s->physical_offset = s->file_length = s->logical_offset;
653   s->active = 0;
654   return SUCCESS;
655 }
656
657
658 /* Similar to memset(), but operating on a stream instead of a string.
659    Takes care of not using too much memory.  */
660
661 static try
662 fd_sset (unix_stream * s, int c, size_t n)
663 {
664   size_t bytes_left;
665   int trans;
666   void *p;
667
668   bytes_left = n;
669
670   while (bytes_left > 0)
671     {
672       /* memset() in chunks of BUFFER_SIZE.  */
673       trans = (bytes_left < BUFFER_SIZE) ? bytes_left : BUFFER_SIZE;
674
675       p = fd_alloc_w_at (s, &trans, -1);
676       if (p)
677           memset (p, c, trans);
678       else
679         return FAILURE;
680
681       bytes_left -= trans;
682     }
683
684   return SUCCESS;
685 }
686
687
688 /* Stream read function. Avoids using a buffer for big reads. The
689    interface is like POSIX read(), but the nbytes argument is a
690    pointer; on return it contains the number of bytes written. The
691    function return value is the status indicator (0 for success).  */
692
693 static int
694 fd_read (unix_stream * s, void * buf, size_t * nbytes)
695 {
696   void *p;
697   int tmp, status;
698
699   if (*nbytes < BUFFER_SIZE && !s->unbuffered)
700     {
701       tmp = *nbytes;
702       p = fd_alloc_r_at (s, &tmp, -1);
703       if (p)
704         {
705           *nbytes = tmp;
706           memcpy (buf, p, *nbytes);
707           return 0;
708         }
709       else
710         {
711           *nbytes = 0;
712           return errno;
713         }
714     }
715
716   /* If the request is bigger than BUFFER_SIZE we flush the buffers
717      and read directly.  */
718   if (fd_flush (s) == FAILURE)
719     {
720       *nbytes = 0;
721       return errno;
722     }
723
724   if (is_seekable ((stream *) s) && fd_seek (s, s->logical_offset) == FAILURE)
725     {
726       *nbytes = 0;
727       return errno;
728     }
729
730   status = do_read (s, buf, nbytes);
731   reset_stream (s, *nbytes);
732   return status;
733 }
734
735
736 /* Stream write function. Avoids using a buffer for big writes. The
737    interface is like POSIX write(), but the nbytes argument is a
738    pointer; on return it contains the number of bytes written. The
739    function return value is the status indicator (0 for success).  */
740
741 static int
742 fd_write (unix_stream * s, const void * buf, size_t * nbytes)
743 {
744   void *p;
745   int tmp, status;
746
747   if (*nbytes < BUFFER_SIZE && !s->unbuffered)
748     {
749       tmp = *nbytes;
750       p = fd_alloc_w_at (s, &tmp, -1);
751       if (p)
752         {
753           *nbytes = tmp;
754           memcpy (p, buf, *nbytes);
755           return 0;
756         }
757       else
758         {
759           *nbytes = 0;
760           return errno;
761         }
762     }
763
764   /* If the request is bigger than BUFFER_SIZE we flush the buffers
765      and write directly.  */
766   if (fd_flush (s) == FAILURE)
767     {
768       *nbytes = 0;
769       return errno;
770     }
771
772   if (is_seekable ((stream *) s) && fd_seek (s, s->logical_offset) == FAILURE)
773     {
774       *nbytes = 0;
775       return errno;
776     }
777
778   status =  do_write (s, buf, nbytes);
779   reset_stream (s, *nbytes);
780   return status;
781 }
782
783
784 static try
785 fd_close (unix_stream * s)
786 {
787   if (fd_flush (s) == FAILURE)
788     return FAILURE;
789
790   if (s->buffer != NULL && s->buffer != s->small_buffer)
791     free_mem (s->buffer);
792
793   if (s->fd != STDOUT_FILENO && s->fd != STDERR_FILENO)
794     {
795       if (close (s->fd) < 0)
796         return FAILURE;
797     }
798
799   free_mem (s);
800
801   return SUCCESS;
802 }
803
804
805 static void
806 fd_open (unix_stream * s)
807 {
808   if (isatty (s->fd))
809     s->unbuffered = 1;
810
811   s->st.alloc_r_at = (void *) fd_alloc_r_at;
812   s->st.alloc_w_at = (void *) fd_alloc_w_at;
813   s->st.sfree = (void *) fd_sfree;
814   s->st.close = (void *) fd_close;
815   s->st.seek = (void *) fd_seek;
816   s->st.truncate = (void *) fd_truncate;
817   s->st.read = (void *) fd_read;
818   s->st.write = (void *) fd_write;
819   s->st.set = (void *) fd_sset;
820
821   s->buffer = NULL;
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 (unix_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 (unix_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 (unix_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 (unix_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 (unix_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 (unix_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 (unix_stream * s __attribute__ ((unused)))
972 {
973   return SUCCESS;
974 }
975
976
977 static try
978 mem_close (unix_stream * s)
979 {
980   if (s != NULL)
981     free_mem (s);
982
983   return SUCCESS;
984 }
985
986
987 static try
988 mem_sfree (unix_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   unix_stream * s = (unix_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   unix_stream *s;
1015
1016   s = get_mem (sizeof (unix_stream));
1017   memset (s, '\0', sizeof (unix_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)
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   error->buffer = error->small_buffer;
1381
1382   return (stream *) error;
1383 }
1384
1385 /* st_printf()-- simple printf() function for streams that handles the
1386  * formats %d, %s and %c.  This function handles printing of error
1387  * messages that originate within the library itself, not from a user
1388  * program. */
1389
1390 int
1391 st_printf (const char *format, ...)
1392 {
1393   int count, total;
1394   va_list arg;
1395   char *p;
1396   const char *q;
1397   stream *s;
1398   char itoa_buf[GFC_ITOA_BUF_SIZE];
1399   unix_stream err_stream;
1400
1401   total = 0;
1402   s = init_error_stream (&err_stream);
1403   va_start (arg, format);
1404
1405   for (;;)
1406     {
1407       count = 0;
1408
1409       while (format[count] != '%' && format[count] != '\0')
1410         count++;
1411
1412       if (count != 0)
1413         {
1414           p = salloc_w (s, &count);
1415           memmove (p, format, count);
1416           sfree (s);
1417         }
1418
1419       total += count;
1420       format += count;
1421       if (*format++ == '\0')
1422         break;
1423
1424       switch (*format)
1425         {
1426         case 'c':
1427           count = 1;
1428
1429           p = salloc_w (s, &count);
1430           *p = (char) va_arg (arg, int);
1431
1432           sfree (s);
1433           break;
1434
1435         case 'd':
1436           q = gfc_itoa (va_arg (arg, int), itoa_buf, sizeof (itoa_buf));
1437           count = strlen (q);
1438
1439           p = salloc_w (s, &count);
1440           memmove (p, q, count);
1441           sfree (s);
1442           break;
1443
1444         case 'x':
1445           q = xtoa (va_arg (arg, unsigned), itoa_buf, sizeof (itoa_buf));
1446           count = strlen (q);
1447
1448           p = salloc_w (s, &count);
1449           memmove (p, q, count);
1450           sfree (s);
1451           break;
1452
1453         case 's':
1454           q = va_arg (arg, char *);
1455           count = strlen (q);
1456
1457           p = salloc_w (s, &count);
1458           memmove (p, q, count);
1459           sfree (s);
1460           break;
1461
1462         case '\0':
1463           return total;
1464
1465         default:
1466           count = 2;
1467           p = salloc_w (s, &count);
1468           p[0] = format[-1];
1469           p[1] = format[0];
1470           sfree (s);
1471           break;
1472         }
1473
1474       total += count;
1475       format++;
1476     }
1477
1478   va_end (arg);
1479   return total;
1480 }
1481
1482
1483 /* compare_file_filename()-- Given an open stream and a fortran string
1484  * that is a filename, figure out if the file is the same as the
1485  * filename. */
1486
1487 int
1488 compare_file_filename (gfc_unit *u, const char *name, int len)
1489 {
1490   char path[PATH_MAX + 1];
1491   struct stat st1;
1492 #ifdef HAVE_WORKING_STAT
1493   struct stat st2;
1494 #endif
1495
1496   if (unpack_filename (path, name, len))
1497     return 0;                   /* Can't be the same */
1498
1499   /* If the filename doesn't exist, then there is no match with the
1500    * existing file. */
1501
1502   if (stat (path, &st1) < 0)
1503     return 0;
1504
1505 #ifdef HAVE_WORKING_STAT
1506   fstat (((unix_stream *) (u->s))->fd, &st2);
1507   return (st1.st_dev == st2.st_dev) && (st1.st_ino == st2.st_ino);
1508 #else
1509   if (len != u->file_len)
1510     return 0;
1511   return (memcmp(path, u->file, len) == 0);
1512 #endif
1513 }
1514
1515
1516 #ifdef HAVE_WORKING_STAT
1517 # define FIND_FILE0_DECL struct stat *st
1518 # define FIND_FILE0_ARGS st
1519 #else
1520 # define FIND_FILE0_DECL const char *file, gfc_charlen_type file_len
1521 # define FIND_FILE0_ARGS file, file_len
1522 #endif
1523
1524 /* find_file0()-- Recursive work function for find_file() */
1525
1526 static gfc_unit *
1527 find_file0 (gfc_unit *u, FIND_FILE0_DECL)
1528 {
1529   gfc_unit *v;
1530
1531   if (u == NULL)
1532     return NULL;
1533
1534 #ifdef HAVE_WORKING_STAT
1535   if (u->s != NULL
1536       && fstat (((unix_stream *) u->s)->fd, &st[1]) >= 0 &&
1537       st[0].st_dev == st[1].st_dev && st[0].st_ino == st[1].st_ino)
1538     return u;
1539 #else
1540   if (compare_string (u->file_len, u->file, file_len, file) == 0)
1541     return u;
1542 #endif
1543
1544   v = find_file0 (u->left, FIND_FILE0_ARGS);
1545   if (v != NULL)
1546     return v;
1547
1548   v = find_file0 (u->right, FIND_FILE0_ARGS);
1549   if (v != NULL)
1550     return v;
1551
1552   return NULL;
1553 }
1554
1555
1556 /* find_file()-- Take the current filename and see if there is a unit
1557  * that has the file already open.  Returns a pointer to the unit if so. */
1558
1559 gfc_unit *
1560 find_file (const char *file, gfc_charlen_type file_len)
1561 {
1562   char path[PATH_MAX + 1];
1563   struct stat st[2];
1564   gfc_unit *u;
1565
1566   if (unpack_filename (path, file, file_len))
1567     return NULL;
1568
1569   if (stat (path, &st[0]) < 0)
1570     return NULL;
1571
1572   __gthread_mutex_lock (&unit_lock);
1573 retry:
1574   u = find_file0 (unit_root, FIND_FILE0_ARGS);
1575   if (u != NULL)
1576     {
1577       /* Fast path.  */
1578       if (! __gthread_mutex_trylock (&u->lock))
1579         {
1580           /* assert (u->closed == 0); */
1581           __gthread_mutex_unlock (&unit_lock);
1582           return u;
1583         }
1584
1585       inc_waiting_locked (u);
1586     }
1587   __gthread_mutex_unlock (&unit_lock);
1588   if (u != NULL)
1589     {
1590       __gthread_mutex_lock (&u->lock);
1591       if (u->closed)
1592         {
1593           __gthread_mutex_lock (&unit_lock);
1594           __gthread_mutex_unlock (&u->lock);
1595           if (predec_waiting_locked (u) == 0)
1596             free_mem (u);
1597           goto retry;
1598         }
1599
1600       dec_waiting_unlocked (u);
1601     }
1602   return u;
1603 }
1604
1605 static gfc_unit *
1606 flush_all_units_1 (gfc_unit *u, int min_unit)
1607 {
1608   while (u != NULL)
1609     {
1610       if (u->unit_number > min_unit)
1611         {
1612           gfc_unit *r = flush_all_units_1 (u->left, min_unit);
1613           if (r != NULL)
1614             return r;
1615         }
1616       if (u->unit_number >= min_unit)
1617         {
1618           if (__gthread_mutex_trylock (&u->lock))
1619             return u;
1620           if (u->s)
1621             flush (u->s);
1622           __gthread_mutex_unlock (&u->lock);
1623         }
1624       u = u->right;
1625     }
1626   return NULL;
1627 }
1628
1629 void
1630 flush_all_units (void)
1631 {
1632   gfc_unit *u;
1633   int min_unit = 0;
1634
1635   __gthread_mutex_lock (&unit_lock);
1636   do
1637     {
1638       u = flush_all_units_1 (unit_root, min_unit);
1639       if (u != NULL)
1640         inc_waiting_locked (u);
1641       __gthread_mutex_unlock (&unit_lock);
1642       if (u == NULL)
1643         return;
1644
1645       __gthread_mutex_lock (&u->lock);
1646
1647       min_unit = u->unit_number + 1;
1648
1649       if (u->closed == 0)
1650         {
1651           flush (u->s);
1652           __gthread_mutex_lock (&unit_lock);
1653           __gthread_mutex_unlock (&u->lock);
1654           (void) predec_waiting_locked (u);
1655         }
1656       else
1657         {
1658           __gthread_mutex_lock (&unit_lock);
1659           __gthread_mutex_unlock (&u->lock);
1660           if (predec_waiting_locked (u) == 0)
1661             free_mem (u);
1662         }
1663     }
1664   while (1);
1665 }
1666
1667
1668 /* stream_at_bof()-- Returns nonzero if the stream is at the beginning
1669  * of the file. */
1670
1671 int
1672 stream_at_bof (stream * s)
1673 {
1674   unix_stream *us;
1675
1676   if (!is_seekable (s))
1677     return 0;
1678
1679   us = (unix_stream *) s;
1680
1681   return us->logical_offset == 0;
1682 }
1683
1684
1685 /* stream_at_eof()-- Returns nonzero if the stream is at the end
1686  * of the file. */
1687
1688 int
1689 stream_at_eof (stream * s)
1690 {
1691   unix_stream *us;
1692
1693   if (!is_seekable (s))
1694     return 0;
1695
1696   us = (unix_stream *) s;
1697
1698   return us->logical_offset == us->dirty_offset;
1699 }
1700
1701
1702 /* delete_file()-- Given a unit structure, delete the file associated
1703  * with the unit.  Returns nonzero if something went wrong. */
1704
1705 int
1706 delete_file (gfc_unit * u)
1707 {
1708   char path[PATH_MAX + 1];
1709
1710   if (unpack_filename (path, u->file, u->file_len))
1711     {                           /* Shouldn't be possible */
1712       errno = ENOENT;
1713       return 1;
1714     }
1715
1716   return unlink (path);
1717 }
1718
1719
1720 /* file_exists()-- Returns nonzero if the current filename exists on
1721  * the system */
1722
1723 int
1724 file_exists (const char *file, gfc_charlen_type file_len)
1725 {
1726   char path[PATH_MAX + 1];
1727   struct stat statbuf;
1728
1729   if (unpack_filename (path, file, file_len))
1730     return 0;
1731
1732   if (stat (path, &statbuf) < 0)
1733     return 0;
1734
1735   return 1;
1736 }
1737
1738
1739
1740 static const char yes[] = "YES", no[] = "NO", unknown[] = "UNKNOWN";
1741
1742 /* inquire_sequential()-- Given a fortran string, determine if the
1743  * file is suitable for sequential access.  Returns a C-style
1744  * string. */
1745
1746 const char *
1747 inquire_sequential (const char *string, int len)
1748 {
1749   char path[PATH_MAX + 1];
1750   struct stat statbuf;
1751
1752   if (string == NULL ||
1753       unpack_filename (path, string, len) || stat (path, &statbuf) < 0)
1754     return unknown;
1755
1756   if (S_ISREG (statbuf.st_mode) ||
1757       S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode))
1758     return yes;
1759
1760   if (S_ISDIR (statbuf.st_mode) || S_ISBLK (statbuf.st_mode))
1761     return no;
1762
1763   return unknown;
1764 }
1765
1766
1767 /* inquire_direct()-- Given a fortran string, determine if the file is
1768  * suitable for direct access.  Returns a C-style string. */
1769
1770 const char *
1771 inquire_direct (const char *string, int len)
1772 {
1773   char path[PATH_MAX + 1];
1774   struct stat statbuf;
1775
1776   if (string == NULL ||
1777       unpack_filename (path, string, len) || stat (path, &statbuf) < 0)
1778     return unknown;
1779
1780   if (S_ISREG (statbuf.st_mode) || S_ISBLK (statbuf.st_mode))
1781     return yes;
1782
1783   if (S_ISDIR (statbuf.st_mode) ||
1784       S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode))
1785     return no;
1786
1787   return unknown;
1788 }
1789
1790
1791 /* inquire_formatted()-- Given a fortran string, determine if the file
1792  * is suitable for formatted form.  Returns a C-style string. */
1793
1794 const char *
1795 inquire_formatted (const char *string, int len)
1796 {
1797   char path[PATH_MAX + 1];
1798   struct stat statbuf;
1799
1800   if (string == NULL ||
1801       unpack_filename (path, string, len) || stat (path, &statbuf) < 0)
1802     return unknown;
1803
1804   if (S_ISREG (statbuf.st_mode) ||
1805       S_ISBLK (statbuf.st_mode) ||
1806       S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode))
1807     return yes;
1808
1809   if (S_ISDIR (statbuf.st_mode))
1810     return no;
1811
1812   return unknown;
1813 }
1814
1815
1816 /* inquire_unformatted()-- Given a fortran string, determine if the file
1817  * is suitable for unformatted form.  Returns a C-style string. */
1818
1819 const char *
1820 inquire_unformatted (const char *string, int len)
1821 {
1822   return inquire_formatted (string, len);
1823 }
1824
1825
1826 /* inquire_access()-- Given a fortran string, determine if the file is
1827  * suitable for access. */
1828
1829 static const char *
1830 inquire_access (const char *string, int len, int mode)
1831 {
1832   char path[PATH_MAX + 1];
1833
1834   if (string == NULL || unpack_filename (path, string, len) ||
1835       access (path, mode) < 0)
1836     return no;
1837
1838   return yes;
1839 }
1840
1841
1842 /* inquire_read()-- Given a fortran string, determine if the file is
1843  * suitable for READ access. */
1844
1845 const char *
1846 inquire_read (const char *string, int len)
1847 {
1848   return inquire_access (string, len, R_OK);
1849 }
1850
1851
1852 /* inquire_write()-- Given a fortran string, determine if the file is
1853  * suitable for READ access. */
1854
1855 const char *
1856 inquire_write (const char *string, int len)
1857 {
1858   return inquire_access (string, len, W_OK);
1859 }
1860
1861
1862 /* inquire_readwrite()-- Given a fortran string, determine if the file is
1863  * suitable for read and write access. */
1864
1865 const char *
1866 inquire_readwrite (const char *string, int len)
1867 {
1868   return inquire_access (string, len, R_OK | W_OK);
1869 }
1870
1871
1872 /* file_length()-- Return the file length in bytes, -1 if unknown */
1873
1874 gfc_offset
1875 file_length (stream * s)
1876 {
1877   return ((unix_stream *) s)->file_length;
1878 }
1879
1880
1881 /* file_position()-- Return the current position of the file */
1882
1883 gfc_offset
1884 file_position (stream * s)
1885 {
1886   return ((unix_stream *) s)->logical_offset;
1887 }
1888
1889
1890 /* is_seekable()-- Return nonzero if the stream is seekable, zero if
1891  * it is not */
1892
1893 int
1894 is_seekable (stream * s)
1895 {
1896   /* By convention, if file_length == -1, the file is not
1897      seekable.  */
1898   return ((unix_stream *) s)->file_length!=-1;
1899 }
1900
1901 try
1902 flush (stream *s)
1903 {
1904   return fd_flush( (unix_stream *) s);
1905 }
1906
1907 int
1908 stream_isatty (stream *s)
1909 {
1910   return isatty (((unix_stream *) s)->fd);
1911 }
1912
1913 char *
1914 stream_ttyname (stream *s)
1915 {
1916 #ifdef HAVE_TTYNAME
1917   return ttyname (((unix_stream *) s)->fd);
1918 #else
1919   return NULL;
1920 #endif
1921 }
1922
1923 gfc_offset
1924 stream_offset (stream *s)
1925 {
1926   return (((unix_stream *) s)->logical_offset);
1927 }
1928
1929
1930 /* How files are stored:  This is an operating-system specific issue,
1931    and therefore belongs here.  There are three cases to consider.
1932
1933    Direct Access:
1934       Records are written as block of bytes corresponding to the record
1935       length of the file.  This goes for both formatted and unformatted
1936       records.  Positioning is done explicitly for each data transfer,
1937       so positioning is not much of an issue.
1938
1939    Sequential Formatted:
1940       Records are separated by newline characters.  The newline character
1941       is prohibited from appearing in a string.  If it does, this will be
1942       messed up on the next read.  End of file is also the end of a record.
1943
1944    Sequential Unformatted:
1945       In this case, we are merely copying bytes to and from main storage,
1946       yet we need to keep track of varying record lengths.  We adopt
1947       the solution used by f2c.  Each record contains a pair of length
1948       markers:
1949
1950         Length of record n in bytes
1951         Data of record n
1952         Length of record n in bytes
1953
1954         Length of record n+1 in bytes
1955         Data of record n+1
1956         Length of record n+1 in bytes
1957
1958      The length is stored at the end of a record to allow backspacing to the
1959      previous record.  Between data transfer statements, the file pointer
1960      is left pointing to the first length of the current record.
1961
1962      ENDFILE records are never explicitly stored.
1963
1964 */