OSDN Git Service

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