OSDN Git Service

2008-01-03 Thomas Koenig <tkoenig@gcc.gnu.org>
[pf3gnuchains/gcc-fork.git] / libgfortran / io / unix.c
1 /* Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007
2    Free Software Foundation, Inc.
3    Contributed by Andy Vaught
4
5 This file is part of the GNU Fortran 95 runtime library (libgfortran).
6
7 Libgfortran is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 In addition to the permissions in the GNU General Public License, the
13 Free Software Foundation gives you unlimited permission to link the
14 compiled version of this file into combinations with other programs,
15 and to distribute those combinations without any restriction coming
16 from the use of this file.  (The General Public License restrictions
17 do apply in other respects; for example, they cover modification of
18 the file, and distribution when not linked into a combine
19 executable.)
20
21 Libgfortran is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24 GNU General Public License for more details.
25
26 You should have received a copy of the GNU General Public License
27 along with Libgfortran; see the file COPYING.  If not, write to
28 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
29 Boston, MA 02110-1301, USA.  */
30
31 /* Unix stream I/O module */
32
33 #include "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, gfc_offset offset)
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 = offset;
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   stream * s;
1415
1416 #if defined(HAVE_CRLF) && defined(HAVE_SETMODE)
1417   setmode (STDOUT_FILENO, O_BINARY);
1418 #endif
1419
1420   s = fd_to_stream (STDOUT_FILENO, PROT_WRITE);
1421   if (options.unbuffered_preconnected)
1422     ((unix_stream *) s)->unbuffered = 1;
1423   return s;
1424 }
1425
1426
1427 /* error_stream()-- Return a stream pointer to the default error stream.
1428  * Called on initialization. */
1429
1430 stream *
1431 error_stream (void)
1432 {
1433   stream * s;
1434
1435 #if defined(HAVE_CRLF) && defined(HAVE_SETMODE)
1436   setmode (STDERR_FILENO, O_BINARY);
1437 #endif
1438
1439   s = fd_to_stream (STDERR_FILENO, PROT_WRITE);
1440   if (options.unbuffered_preconnected)
1441     ((unix_stream *) s)->unbuffered = 1;
1442   return s;
1443 }
1444
1445
1446 /* st_vprintf()-- vprintf function for error output.  To avoid buffer
1447    overruns, we limit the length of the buffer to ST_VPRINTF_SIZE.  2k
1448    is big enough to completely fill a 80x25 terminal, so it shuld be
1449    OK.  We use a direct write() because it is simpler and least likely
1450    to be clobbered by memory corruption.  Writing an error message
1451    longer than that is an error.  */
1452
1453 #define ST_VPRINTF_SIZE 2048
1454
1455 int
1456 st_vprintf (const char *format, va_list ap)
1457 {
1458   static char buffer[ST_VPRINTF_SIZE];
1459   int written;
1460   int fd;
1461
1462   fd = options.use_stderr ? STDERR_FILENO : STDOUT_FILENO;
1463 #ifdef HAVE_VSNPRINTF
1464   written = vsnprintf(buffer, ST_VPRINTF_SIZE, format, ap);
1465 #else
1466   written = vsprintf(buffer, format, ap);
1467
1468   if (written >= ST_VPRINTF_SIZE-1)
1469     {
1470       /* The error message was longer than our buffer.  Ouch.  Because
1471          we may have messed up things badly, report the error and
1472          quit.  */
1473 #define ERROR_MESSAGE "Internal error: buffer overrun in st_vprintf()\n"
1474       write (fd, buffer, ST_VPRINTF_SIZE-1);
1475       write (fd, ERROR_MESSAGE, strlen(ERROR_MESSAGE));
1476       sys_exit(2);
1477 #undef ERROR_MESSAGE
1478
1479     }
1480 #endif
1481
1482   written = write (fd, buffer, written);
1483   return written;
1484 }
1485
1486 /* st_printf()-- printf() function for error output.  This just calls
1487    st_vprintf() to do the actual work.  */
1488
1489 int
1490 st_printf (const char *format, ...)
1491 {
1492   int written;
1493   va_list ap;
1494   va_start (ap, format);
1495   written = st_vprintf(format, ap);
1496   va_end (ap);
1497   return written;
1498 }
1499
1500
1501 /* compare_file_filename()-- Given an open stream and a fortran string
1502  * that is a filename, figure out if the file is the same as the
1503  * filename. */
1504
1505 int
1506 compare_file_filename (gfc_unit *u, const char *name, int len)
1507 {
1508   char path[PATH_MAX + 1];
1509   struct stat st1;
1510 #ifdef HAVE_WORKING_STAT
1511   struct stat st2;
1512 #else
1513 # ifdef __MINGW32__
1514   uint64_t id1, id2;
1515 # endif
1516 #endif
1517
1518   if (unpack_filename (path, name, len))
1519     return 0;                   /* Can't be the same */
1520
1521   /* If the filename doesn't exist, then there is no match with the
1522    * existing file. */
1523
1524   if (stat (path, &st1) < 0)
1525     return 0;
1526
1527 #ifdef HAVE_WORKING_STAT
1528   fstat (((unix_stream *) (u->s))->fd, &st2);
1529   return (st1.st_dev == st2.st_dev) && (st1.st_ino == st2.st_ino);
1530 #else
1531
1532 # ifdef __MINGW32__
1533   /* We try to match files by a unique ID.  On some filesystems (network
1534      fs and FAT), we can't generate this unique ID, and will simply compare
1535      filenames.  */
1536   id1 = id_from_path (path);
1537   id2 = id_from_fd (((unix_stream *) (u->s))->fd);
1538   if (id1 || id2)
1539     return (id1 == id2);
1540 # endif
1541
1542   if (len != u->file_len)
1543     return 0;
1544   return (memcmp(path, u->file, len) == 0);
1545 #endif
1546 }
1547
1548
1549 #ifdef HAVE_WORKING_STAT
1550 # define FIND_FILE0_DECL struct stat *st
1551 # define FIND_FILE0_ARGS st
1552 #else
1553 # define FIND_FILE0_DECL uint64_t id, const char *file, gfc_charlen_type file_len
1554 # define FIND_FILE0_ARGS id, file, file_len
1555 #endif
1556
1557 /* find_file0()-- Recursive work function for find_file() */
1558
1559 static gfc_unit *
1560 find_file0 (gfc_unit *u, FIND_FILE0_DECL)
1561 {
1562   gfc_unit *v;
1563 #if defined(__MINGW32__) && !HAVE_WORKING_STAT
1564   uint64_t id1;
1565 #endif
1566
1567   if (u == NULL)
1568     return NULL;
1569
1570 #ifdef HAVE_WORKING_STAT
1571   if (u->s != NULL
1572       && fstat (((unix_stream *) u->s)->fd, &st[1]) >= 0 &&
1573       st[0].st_dev == st[1].st_dev && st[0].st_ino == st[1].st_ino)
1574     return u;
1575 #else
1576 # ifdef __MINGW32__ 
1577   if (u->s && ((id1 = id_from_fd (((unix_stream *) u->s)->fd)) || id1))
1578     {
1579       if (id == id1)
1580         return u;
1581     }
1582   else
1583 # endif
1584     if (compare_string (u->file_len, u->file, file_len, file) == 0)
1585       return u;
1586 #endif
1587
1588   v = find_file0 (u->left, FIND_FILE0_ARGS);
1589   if (v != NULL)
1590     return v;
1591
1592   v = find_file0 (u->right, FIND_FILE0_ARGS);
1593   if (v != NULL)
1594     return v;
1595
1596   return NULL;
1597 }
1598
1599
1600 /* find_file()-- Take the current filename and see if there is a unit
1601  * that has the file already open.  Returns a pointer to the unit if so. */
1602
1603 gfc_unit *
1604 find_file (const char *file, gfc_charlen_type file_len)
1605 {
1606   char path[PATH_MAX + 1];
1607   struct stat st[2];
1608   gfc_unit *u;
1609   uint64_t id;
1610
1611   if (unpack_filename (path, file, file_len))
1612     return NULL;
1613
1614   if (stat (path, &st[0]) < 0)
1615     return NULL;
1616
1617 #if defined(__MINGW32__) && !HAVE_WORKING_STAT
1618   id = id_from_path (path);
1619 #else
1620   id = 0;
1621 #endif
1622
1623   __gthread_mutex_lock (&unit_lock);
1624 retry:
1625   u = find_file0 (unit_root, FIND_FILE0_ARGS);
1626   if (u != NULL)
1627     {
1628       /* Fast path.  */
1629       if (! __gthread_mutex_trylock (&u->lock))
1630         {
1631           /* assert (u->closed == 0); */
1632           __gthread_mutex_unlock (&unit_lock);
1633           return u;
1634         }
1635
1636       inc_waiting_locked (u);
1637     }
1638   __gthread_mutex_unlock (&unit_lock);
1639   if (u != NULL)
1640     {
1641       __gthread_mutex_lock (&u->lock);
1642       if (u->closed)
1643         {
1644           __gthread_mutex_lock (&unit_lock);
1645           __gthread_mutex_unlock (&u->lock);
1646           if (predec_waiting_locked (u) == 0)
1647             free_mem (u);
1648           goto retry;
1649         }
1650
1651       dec_waiting_unlocked (u);
1652     }
1653   return u;
1654 }
1655
1656 static gfc_unit *
1657 flush_all_units_1 (gfc_unit *u, int min_unit)
1658 {
1659   while (u != NULL)
1660     {
1661       if (u->unit_number > min_unit)
1662         {
1663           gfc_unit *r = flush_all_units_1 (u->left, min_unit);
1664           if (r != NULL)
1665             return r;
1666         }
1667       if (u->unit_number >= min_unit)
1668         {
1669           if (__gthread_mutex_trylock (&u->lock))
1670             return u;
1671           if (u->s)
1672             flush (u->s);
1673           __gthread_mutex_unlock (&u->lock);
1674         }
1675       u = u->right;
1676     }
1677   return NULL;
1678 }
1679
1680 void
1681 flush_all_units (void)
1682 {
1683   gfc_unit *u;
1684   int min_unit = 0;
1685
1686   __gthread_mutex_lock (&unit_lock);
1687   do
1688     {
1689       u = flush_all_units_1 (unit_root, min_unit);
1690       if (u != NULL)
1691         inc_waiting_locked (u);
1692       __gthread_mutex_unlock (&unit_lock);
1693       if (u == NULL)
1694         return;
1695
1696       __gthread_mutex_lock (&u->lock);
1697
1698       min_unit = u->unit_number + 1;
1699
1700       if (u->closed == 0)
1701         {
1702           flush (u->s);
1703           __gthread_mutex_lock (&unit_lock);
1704           __gthread_mutex_unlock (&u->lock);
1705           (void) predec_waiting_locked (u);
1706         }
1707       else
1708         {
1709           __gthread_mutex_lock (&unit_lock);
1710           __gthread_mutex_unlock (&u->lock);
1711           if (predec_waiting_locked (u) == 0)
1712             free_mem (u);
1713         }
1714     }
1715   while (1);
1716 }
1717
1718
1719 /* stream_at_bof()-- Returns nonzero if the stream is at the beginning
1720  * of the file. */
1721
1722 int
1723 stream_at_bof (stream * s)
1724 {
1725   unix_stream *us;
1726
1727   if (!is_seekable (s))
1728     return 0;
1729
1730   us = (unix_stream *) s;
1731
1732   return us->logical_offset == 0;
1733 }
1734
1735
1736 /* stream_at_eof()-- Returns nonzero if the stream is at the end
1737  * of the file. */
1738
1739 int
1740 stream_at_eof (stream * s)
1741 {
1742   unix_stream *us;
1743
1744   if (!is_seekable (s))
1745     return 0;
1746
1747   us = (unix_stream *) s;
1748
1749   return us->logical_offset == us->dirty_offset;
1750 }
1751
1752
1753 /* delete_file()-- Given a unit structure, delete the file associated
1754  * with the unit.  Returns nonzero if something went wrong. */
1755
1756 int
1757 delete_file (gfc_unit * u)
1758 {
1759   char path[PATH_MAX + 1];
1760
1761   if (unpack_filename (path, u->file, u->file_len))
1762     {                           /* Shouldn't be possible */
1763       errno = ENOENT;
1764       return 1;
1765     }
1766
1767   return unlink (path);
1768 }
1769
1770
1771 /* file_exists()-- Returns nonzero if the current filename exists on
1772  * the system */
1773
1774 int
1775 file_exists (const char *file, gfc_charlen_type file_len)
1776 {
1777   char path[PATH_MAX + 1];
1778   struct stat statbuf;
1779
1780   if (unpack_filename (path, file, file_len))
1781     return 0;
1782
1783   if (stat (path, &statbuf) < 0)
1784     return 0;
1785
1786   return 1;
1787 }
1788
1789
1790
1791 static const char yes[] = "YES", no[] = "NO", unknown[] = "UNKNOWN";
1792
1793 /* inquire_sequential()-- Given a fortran string, determine if the
1794  * file is suitable for sequential access.  Returns a C-style
1795  * string. */
1796
1797 const char *
1798 inquire_sequential (const char *string, int len)
1799 {
1800   char path[PATH_MAX + 1];
1801   struct stat statbuf;
1802
1803   if (string == NULL ||
1804       unpack_filename (path, string, len) || stat (path, &statbuf) < 0)
1805     return unknown;
1806
1807   if (S_ISREG (statbuf.st_mode) ||
1808       S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode))
1809     return yes;
1810
1811   if (S_ISDIR (statbuf.st_mode) || S_ISBLK (statbuf.st_mode))
1812     return no;
1813
1814   return unknown;
1815 }
1816
1817
1818 /* inquire_direct()-- Given a fortran string, determine if the file is
1819  * suitable for direct access.  Returns a C-style string. */
1820
1821 const char *
1822 inquire_direct (const char *string, int len)
1823 {
1824   char path[PATH_MAX + 1];
1825   struct stat statbuf;
1826
1827   if (string == NULL ||
1828       unpack_filename (path, string, len) || stat (path, &statbuf) < 0)
1829     return unknown;
1830
1831   if (S_ISREG (statbuf.st_mode) || S_ISBLK (statbuf.st_mode))
1832     return yes;
1833
1834   if (S_ISDIR (statbuf.st_mode) ||
1835       S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode))
1836     return no;
1837
1838   return unknown;
1839 }
1840
1841
1842 /* inquire_formatted()-- Given a fortran string, determine if the file
1843  * is suitable for formatted form.  Returns a C-style string. */
1844
1845 const char *
1846 inquire_formatted (const char *string, int len)
1847 {
1848   char path[PATH_MAX + 1];
1849   struct stat statbuf;
1850
1851   if (string == NULL ||
1852       unpack_filename (path, string, len) || stat (path, &statbuf) < 0)
1853     return unknown;
1854
1855   if (S_ISREG (statbuf.st_mode) ||
1856       S_ISBLK (statbuf.st_mode) ||
1857       S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode))
1858     return yes;
1859
1860   if (S_ISDIR (statbuf.st_mode))
1861     return no;
1862
1863   return unknown;
1864 }
1865
1866
1867 /* inquire_unformatted()-- Given a fortran string, determine if the file
1868  * is suitable for unformatted form.  Returns a C-style string. */
1869
1870 const char *
1871 inquire_unformatted (const char *string, int len)
1872 {
1873   return inquire_formatted (string, len);
1874 }
1875
1876
1877 #ifndef HAVE_ACCESS
1878
1879 #ifndef W_OK
1880 #define W_OK 2
1881 #endif
1882
1883 #ifndef R_OK
1884 #define R_OK 4
1885 #endif
1886
1887 /* Fallback implementation of access() on systems that don't have it.
1888    Only modes R_OK and W_OK are used in this file.  */
1889
1890 static int
1891 fallback_access (const char *path, int mode)
1892 {
1893   if ((mode & R_OK) && open (path, O_RDONLY) < 0)
1894     return -1;
1895
1896   if ((mode & W_OK) && open (path, O_WRONLY) < 0)
1897     return -1;
1898
1899   return 0;
1900 }
1901
1902 #undef access
1903 #define access fallback_access
1904 #endif
1905
1906
1907 /* inquire_access()-- Given a fortran string, determine if the file is
1908  * suitable for access. */
1909
1910 static const char *
1911 inquire_access (const char *string, int len, int mode)
1912 {
1913   char path[PATH_MAX + 1];
1914
1915   if (string == NULL || unpack_filename (path, string, len) ||
1916       access (path, mode) < 0)
1917     return no;
1918
1919   return yes;
1920 }
1921
1922
1923 /* inquire_read()-- Given a fortran string, determine if the file is
1924  * suitable for READ access. */
1925
1926 const char *
1927 inquire_read (const char *string, int len)
1928 {
1929   return inquire_access (string, len, R_OK);
1930 }
1931
1932
1933 /* inquire_write()-- Given a fortran string, determine if the file is
1934  * suitable for READ access. */
1935
1936 const char *
1937 inquire_write (const char *string, int len)
1938 {
1939   return inquire_access (string, len, W_OK);
1940 }
1941
1942
1943 /* inquire_readwrite()-- Given a fortran string, determine if the file is
1944  * suitable for read and write access. */
1945
1946 const char *
1947 inquire_readwrite (const char *string, int len)
1948 {
1949   return inquire_access (string, len, R_OK | W_OK);
1950 }
1951
1952
1953 /* file_length()-- Return the file length in bytes, -1 if unknown */
1954
1955 gfc_offset
1956 file_length (stream * s)
1957 {
1958   return ((unix_stream *) s)->file_length;
1959 }
1960
1961
1962 /* file_position()-- Return the current position of the file */
1963
1964 gfc_offset
1965 file_position (stream *s)
1966 {
1967   return ((unix_stream *) s)->logical_offset;
1968 }
1969
1970
1971 /* is_seekable()-- Return nonzero if the stream is seekable, zero if
1972  * it is not */
1973
1974 int
1975 is_seekable (stream *s)
1976 {
1977   /* By convention, if file_length == -1, the file is not
1978      seekable.  */
1979   return ((unix_stream *) s)->file_length!=-1;
1980 }
1981
1982
1983 /* is_special()-- Return nonzero if the stream is not a regular file.  */
1984
1985 int
1986 is_special (stream *s)
1987 {
1988   return ((unix_stream *) s)->special_file;
1989 }
1990
1991
1992 try
1993 flush (stream *s)
1994 {
1995   return fd_flush( (unix_stream *) s);
1996 }
1997
1998 int
1999 stream_isatty (stream *s)
2000 {
2001   return isatty (((unix_stream *) s)->fd);
2002 }
2003
2004 char *
2005 stream_ttyname (stream *s __attribute__ ((unused)))
2006 {
2007 #ifdef HAVE_TTYNAME
2008   return ttyname (((unix_stream *) s)->fd);
2009 #else
2010   return NULL;
2011 #endif
2012 }
2013
2014 gfc_offset
2015 stream_offset (stream *s)
2016 {
2017   return (((unix_stream *) s)->logical_offset);
2018 }
2019
2020
2021 /* How files are stored:  This is an operating-system specific issue,
2022    and therefore belongs here.  There are three cases to consider.
2023
2024    Direct Access:
2025       Records are written as block of bytes corresponding to the record
2026       length of the file.  This goes for both formatted and unformatted
2027       records.  Positioning is done explicitly for each data transfer,
2028       so positioning is not much of an issue.
2029
2030    Sequential Formatted:
2031       Records are separated by newline characters.  The newline character
2032       is prohibited from appearing in a string.  If it does, this will be
2033       messed up on the next read.  End of file is also the end of a record.
2034
2035    Sequential Unformatted:
2036       In this case, we are merely copying bytes to and from main storage,
2037       yet we need to keep track of varying record lengths.  We adopt
2038       the solution used by f2c.  Each record contains a pair of length
2039       markers:
2040
2041         Length of record n in bytes
2042         Data of record n
2043         Length of record n in bytes
2044
2045         Length of record n+1 in bytes
2046         Data of record n+1
2047         Length of record n+1 in bytes
2048
2049      The length is stored at the end of a record to allow backspacing to the
2050      previous record.  Between data transfer statements, the file pointer
2051      is left pointing to the first length of the current record.
2052
2053      ENDFILE records are never explicitly stored.
2054
2055 */