OSDN Git Service

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