OSDN Git Service

* io/io.h: Change DEFAULT_TEMPDIR to /tmp instead of /var/tmp.
[pf3gnuchains/gcc-fork.git] / libgfortran / io / unix.c
1 /* Copyright (C) 2002, 2003, 2004, 2005
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, 59 Temple Place - Suite 330,
29 Boston, MA 02111-1307, USA.  */
30
31 /* Unix stream I/O module */
32
33 #include "config.h"
34 #include <stdlib.h>
35 #include <limits.h>
36
37 #include <unistd.h>
38 #include <stdio.h>
39 #include <sys/stat.h>
40 #include <fcntl.h>
41
42 #ifdef HAVE_SYS_MMAN_H
43 #include <sys/mman.h>
44 #endif
45 #include <string.h>
46 #include <errno.h>
47
48 #include "libgfortran.h"
49 #include "io.h"
50
51 #ifndef PATH_MAX
52 #define PATH_MAX 1024
53 #endif
54
55 #ifndef MAP_FAILED
56 #define MAP_FAILED ((void *) -1)
57 #endif
58
59 #ifndef PROT_READ
60 #define PROT_READ 1
61 #endif
62
63 #ifndef PROT_WRITE
64 #define PROT_WRITE 2
65 #endif
66
67 /* These flags aren't defined on all targets (mingw32), so provide them
68    here.  */
69 #ifndef S_IRGRP
70 #define S_IRGRP 0
71 #endif
72
73 #ifndef S_IWGRP
74 #define S_IWGRP 0
75 #endif
76
77 #ifndef S_IROTH
78 #define S_IROTH 0
79 #endif
80
81 #ifndef S_IWOTH
82 #define S_IWOTH 0
83 #endif
84
85 /* This implementation of stream I/O is based on the paper:
86  *
87  *  "Exploiting the advantages of mapped files for stream I/O",
88  *  O. Krieger, M. Stumm and R. Umrau, "Proceedings of the 1992 Winter
89  *  USENIX conference", p. 27-42.
90  *
91  * It differs in a number of ways from the version described in the
92  * paper.  First of all, threads are not an issue during I/O and we
93  * also don't have to worry about having multiple regions, since
94  * fortran's I/O model only allows you to be one place at a time.
95  *
96  * On the other hand, we have to be able to writing at the end of a
97  * stream, read from the start of a stream or read and write blocks of
98  * bytes from an arbitrary position.  After opening a file, a pointer
99  * to a stream structure is returned, which is used to handle file
100  * accesses until the file is closed.
101  *
102  * salloc_at_r(stream, len, where)-- Given a stream pointer, return a
103  * pointer to a block of memory that mirror the file at position
104  * 'where' that is 'len' bytes long.  The len integer is updated to
105  * reflect how many bytes were actually read.  The only reason for a
106  * short read is end of file.  The file pointer is updated.  The
107  * pointer is valid until the next call to salloc_*.
108  *
109  * salloc_at_w(stream, len, where)-- Given the stream pointer, returns
110  * a pointer to a block of memory that is updated to reflect the state
111  * of the file.  The length of the buffer is always equal to that
112  * requested.  The buffer must be completely set by the caller.  When
113  * data has been written, the sfree() function must be called to
114  * indicate that the caller is done writing data to the buffer.  This
115  * may or may not cause a physical write.
116  *
117  * Short forms of these are salloc_r() and salloc_w() which drop the
118  * 'where' parameter and use the current file pointer. */
119
120
121 #define BUFFER_SIZE 8192
122
123 typedef struct
124 {
125   stream st;
126
127   int fd;
128   gfc_offset buffer_offset;     /* File offset of the start of the buffer */
129   gfc_offset physical_offset;   /* Current physical file offset */
130   gfc_offset logical_offset;    /* Current logical file offset */
131   gfc_offset dirty_offset;      /* Start of modified bytes in buffer */
132   gfc_offset file_length;       /* Length of the file, -1 if not seekable. */
133
134   char *buffer;
135   int len;                      /* Physical length of the current buffer */
136   int active;                   /* Length of valid bytes in the buffer */
137
138   int prot;
139   int ndirty;                   /* Dirty bytes starting at dirty_offset */
140
141   int special_file;             /* =1 if the fd refers to a special file */
142
143   unsigned unbuffered:1, mmaped:1;
144
145   char small_buffer[BUFFER_SIZE];
146
147 }
148 unix_stream;
149
150 /*move_pos_offset()--  Move the record pointer right or left
151  *relative to current position */
152
153 int
154 move_pos_offset (stream* st, int pos_off)
155 {
156   unix_stream * str = (unix_stream*)st;
157   if (pos_off < 0)
158     {
159       str->logical_offset += pos_off;
160
161       if (str->dirty_offset + str->ndirty > str->logical_offset)
162         {
163           if (str->ndirty + pos_off > 0)
164             str->ndirty += pos_off;
165           else
166             {
167               str->dirty_offset +=  pos_off + pos_off;
168               str->ndirty = 0;
169             }
170         }
171
172     return pos_off;
173   }
174   return 0;
175 }
176
177
178 /* fix_fd()-- Given a file descriptor, make sure it is not one of the
179  * standard descriptors, returning a non-standard descriptor.  If the
180  * user specifies that system errors should go to standard output,
181  * then closes standard output, we don't want the system errors to a
182  * file that has been given file descriptor 1 or 0.  We want to send
183  * the error to the invalid descriptor. */
184
185 static int
186 fix_fd (int fd)
187 {
188   int input, output, error;
189
190   input = output = error = 0;
191
192   /* Unix allocates the lowest descriptors first, so a loop is not
193      required, but this order is. */
194
195   if (fd == STDIN_FILENO)
196     {
197       fd = dup (fd);
198       input = 1;
199     }
200   if (fd == STDOUT_FILENO)
201     {
202       fd = dup (fd);
203       output = 1;
204     }
205   if (fd == STDERR_FILENO)
206     {
207       fd = dup (fd);
208       error = 1;
209     }
210
211   if (input)
212     close (STDIN_FILENO);
213   if (output)
214     close (STDOUT_FILENO);
215   if (error)
216     close (STDERR_FILENO);
217
218   return fd;
219 }
220
221
222 /* write()-- Write a buffer to a descriptor, allowing for short writes */
223
224 static int
225 writen (int fd, char *buffer, int len)
226 {
227   int n, n0;
228
229   n0 = len;
230
231   while (len > 0)
232     {
233       n = write (fd, buffer, len);
234       if (n < 0)
235         return n;
236
237       buffer += n;
238       len -= n;
239     }
240
241   return n0;
242 }
243
244
245 #if 0
246 /* readn()-- Read bytes into a buffer, allowing for short reads.  If
247  * fewer than len bytes are returned, it is because we've hit the end
248  * of file. */
249
250 static int
251 readn (int fd, char *buffer, int len)
252 {
253   int nread, n;
254
255   nread = 0;
256
257   while (len > 0)
258     {
259       n = read (fd, buffer, len);
260       if (n < 0)
261         return n;
262
263       if (n == 0)
264         return nread;
265
266       buffer += n;
267       nread += n;
268       len -= n;
269     }
270
271   return nread;
272 }
273 #endif
274
275
276 /* get_oserror()-- Get the most recent operating system error.  For
277  * unix, this is errno. */
278
279 const char *
280 get_oserror (void)
281 {
282   return strerror (errno);
283 }
284
285
286 /* sys_exit()-- Terminate the program with an exit code */
287
288 void
289 sys_exit (int code)
290 {
291   exit (code);
292 }
293
294
295 /*********************************************************************
296     File descriptor stream functions
297 *********************************************************************/
298
299 /* fd_flush()-- Write bytes that need to be written */
300
301 static try
302 fd_flush (unix_stream * s)
303 {
304   if (s->ndirty == 0)
305     return SUCCESS;;
306
307   if (s->physical_offset != s->dirty_offset &&
308       lseek (s->fd, s->dirty_offset, SEEK_SET) < 0)
309     return FAILURE;
310
311   if (writen (s->fd, s->buffer + (s->dirty_offset - s->buffer_offset),
312               s->ndirty) < 0)
313     return FAILURE;
314
315   s->physical_offset = s->dirty_offset + s->ndirty;
316
317   /* don't increment file_length if the file is non-seekable */
318   if (s->file_length != -1 && s->physical_offset > s->file_length)
319     s->file_length = s->physical_offset;
320   s->ndirty = 0;
321
322   return SUCCESS;
323 }
324
325
326 /* fd_alloc()-- Arrange a buffer such that the salloc() request can be
327  * satisfied.  This subroutine gets the buffer ready for whatever is
328  * to come next. */
329
330 static void
331 fd_alloc (unix_stream * s, gfc_offset where,
332           int *len __attribute__ ((unused)))
333 {
334   char *new_buffer;
335   int n, read_len;
336
337   if (*len <= BUFFER_SIZE)
338     {
339       new_buffer = s->small_buffer;
340       read_len = BUFFER_SIZE;
341     }
342   else
343     {
344       new_buffer = get_mem (*len);
345       read_len = *len;
346     }
347
348   /* Salvage bytes currently within the buffer.  This is important for
349    * devices that cannot seek. */
350
351   if (s->buffer != NULL && s->buffer_offset <= where &&
352       where <= s->buffer_offset + s->active)
353     {
354
355       n = s->active - (where - s->buffer_offset);
356       memmove (new_buffer, s->buffer + (where - s->buffer_offset), n);
357
358       s->active = n;
359     }
360   else
361     {                           /* new buffer starts off empty */
362       s->active = 0;
363     }
364
365   s->buffer_offset = where;
366
367   /* free the old buffer if necessary */
368
369   if (s->buffer != NULL && s->buffer != s->small_buffer)
370     free_mem (s->buffer);
371
372   s->buffer = new_buffer;
373   s->len = read_len;
374   s->mmaped = 0;
375 }
376
377
378 /* fd_alloc_r_at()-- Allocate a stream buffer for reading.  Either
379  * we've already buffered the data or we need to load it.  Returns
380  * NULL on I/O error. */
381
382 static char *
383 fd_alloc_r_at (unix_stream * s, int *len, gfc_offset where)
384 {
385   gfc_offset m;
386   int n;
387
388   if (where == -1)
389     where = s->logical_offset;
390
391   if (s->buffer != NULL && s->buffer_offset <= where &&
392       where + *len <= s->buffer_offset + s->active)
393     {
394
395       /* Return a position within the current buffer */
396
397       s->logical_offset = where + *len;
398       return s->buffer + where - s->buffer_offset;
399     }
400
401   fd_alloc (s, where, len);
402
403   m = where + s->active;
404
405   if (s->physical_offset != m && lseek (s->fd, m, SEEK_SET) < 0)
406     return NULL;
407
408   n = read (s->fd, s->buffer + s->active, s->len - s->active);
409   if (n < 0)
410     return NULL;
411
412   s->physical_offset = where + n;
413
414   s->active += n;
415   if (s->active < *len)
416     *len = s->active;           /* Bytes actually available */
417
418   s->logical_offset = where + *len;
419
420   return s->buffer;
421 }
422
423
424 /* fd_alloc_w_at()-- Allocate a stream buffer for writing.  Either
425  * we've already buffered the data or we need to load it. */
426
427 static char *
428 fd_alloc_w_at (unix_stream * s, int *len, gfc_offset where)
429 {
430   gfc_offset n;
431
432   if (where == -1)
433     where = s->logical_offset;
434
435   if (s->buffer == NULL || s->buffer_offset > where ||
436       where + *len > s->buffer_offset + s->len)
437     {
438
439       if (fd_flush (s) == FAILURE)
440         return NULL;
441       fd_alloc (s, where, len);
442     }
443
444   /* Return a position within the current buffer */
445   if (s->ndirty == 0 
446       || where > s->dirty_offset + s->ndirty    
447       || s->dirty_offset > where + *len)
448     {  /* Discontiguous blocks, start with a clean buffer.  */  
449         /* Flush the buffer.  */  
450        if (s->ndirty != 0)    
451          fd_flush (s);  
452        s->dirty_offset = where;  
453        s->ndirty = *len;
454     }
455   else
456     {  
457       gfc_offset start;  /* Merge with the existing data.  */  
458       if (where < s->dirty_offset)    
459         start = where;  
460       else    
461         start = s->dirty_offset;  
462       if (where + *len > s->dirty_offset + s->ndirty)    
463         s->ndirty = where + *len - start;  
464       else    
465         s->ndirty = s->dirty_offset + s->ndirty - start;  
466         s->dirty_offset = start;
467     }
468
469   s->logical_offset = where + *len;
470
471   if (where + *len > s->file_length)
472     s->file_length = where + *len;
473
474   n = s->logical_offset - s->buffer_offset;
475   if (n > s->active)
476     s->active = n;
477
478   return s->buffer + where - s->buffer_offset;
479 }
480
481
482 static try
483 fd_sfree (unix_stream * s)
484 {
485   if (s->ndirty != 0 &&
486       (s->buffer != s->small_buffer || options.all_unbuffered ||
487        s->unbuffered))
488     return fd_flush (s);
489
490   return SUCCESS;
491 }
492
493
494 static int
495 fd_seek (unix_stream * s, gfc_offset offset)
496 {
497   s->physical_offset = s->logical_offset = offset;
498
499   return (lseek (s->fd, offset, SEEK_SET) < 0) ? FAILURE : SUCCESS;
500 }
501
502
503 /* truncate_file()-- Given a unit, truncate the file at the current
504  * position.  Sets the physical location to the new end of the file.
505  * Returns nonzero on error. */
506
507 static try
508 fd_truncate (unix_stream * s)
509 {
510   if (lseek (s->fd, s->logical_offset, SEEK_SET) == -1)
511     return FAILURE;
512
513   /* non-seekable files, like terminals and fifo's fail the lseek.
514      Using ftruncate on a seekable special file (like /dev/null)
515      is undefined, so we treat it as if the ftruncate failed.
516   */
517 #ifdef HAVE_FTRUNCATE
518   if (s->special_file || ftruncate (s->fd, s->logical_offset))
519 #else
520 #ifdef HAVE_CHSIZE
521   if (s->special_file || chsize (s->fd, s->logical_offset))
522 #endif
523 #endif
524     {
525       s->physical_offset = s->file_length = 0;
526       return FAILURE;
527     }
528
529   s->physical_offset = s->file_length = s->logical_offset;
530
531   return SUCCESS;
532 }
533
534
535 static try
536 fd_close (unix_stream * s)
537 {
538   if (fd_flush (s) == FAILURE)
539     return FAILURE;
540
541   if (s->buffer != NULL && s->buffer != s->small_buffer)
542     free_mem (s->buffer);
543
544   if (s->fd != STDOUT_FILENO && s->fd != STDERR_FILENO)
545     {
546       if (close (s->fd) < 0)
547         return FAILURE;
548     }
549
550   free_mem (s);
551
552   return SUCCESS;
553 }
554
555
556 static void
557 fd_open (unix_stream * s)
558 {
559   if (isatty (s->fd))
560     s->unbuffered = 1;
561
562   s->st.alloc_r_at = (void *) fd_alloc_r_at;
563   s->st.alloc_w_at = (void *) fd_alloc_w_at;
564   s->st.sfree = (void *) fd_sfree;
565   s->st.close = (void *) fd_close;
566   s->st.seek = (void *) fd_seek;
567   s->st.truncate = (void *) fd_truncate;
568
569   s->buffer = NULL;
570 }
571
572
573 /*********************************************************************
574     mmap stream functions
575
576  Because mmap() is not capable of extending a file, we have to keep
577  track of how long the file is.  We also have to be able to detect end
578  of file conditions.  If there are multiple writers to the file (which
579  can only happen outside the current program), things will get
580  confused.  Then again, things will get confused anyway.
581
582 *********************************************************************/
583
584 #if HAVE_MMAP
585
586 static int page_size, page_mask;
587
588 /* mmap_flush()-- Deletes a memory mapping if something is mapped. */
589
590 static try
591 mmap_flush (unix_stream * s)
592 {
593   if (!s->mmaped)
594     return fd_flush (s);
595
596   if (s->buffer == NULL)
597     return SUCCESS;
598
599   if (munmap (s->buffer, s->active))
600     return FAILURE;
601
602   s->buffer = NULL;
603   s->active = 0;
604
605   return SUCCESS;
606 }
607
608
609 /* mmap_alloc()-- mmap() a section of the file.  The whole section is
610  * guaranteed to be mappable. */
611
612 static try
613 mmap_alloc (unix_stream * s, gfc_offset where,
614             int *len __attribute__ ((unused)))
615 {
616   gfc_offset offset;
617   int length;
618   char *p;
619
620   if (mmap_flush (s) == FAILURE)
621     return FAILURE;
622
623   offset = where & page_mask;   /* Round down to the next page */
624
625   length = ((where - offset) & page_mask) + 2 * page_size;
626
627   p = mmap (NULL, length, s->prot, MAP_SHARED, s->fd, offset);
628   if (p == (char *) MAP_FAILED)
629     return FAILURE;
630
631   s->mmaped = 1;
632   s->buffer = p;
633   s->buffer_offset = offset;
634   s->active = length;
635
636   return SUCCESS;
637 }
638
639
640 static char *
641 mmap_alloc_r_at (unix_stream * s, int *len, gfc_offset where)
642 {
643   gfc_offset m;
644
645   if (where == -1)
646     where = s->logical_offset;
647
648   m = where + *len;
649
650   if ((s->buffer == NULL || s->buffer_offset > where ||
651        m > s->buffer_offset + s->active) &&
652       mmap_alloc (s, where, len) == FAILURE)
653     return NULL;
654
655   if (m > s->file_length)
656     {
657       *len = s->file_length - s->logical_offset;
658       s->logical_offset = s->file_length;
659     }
660   else
661     s->logical_offset = m;
662
663   return s->buffer + (where - s->buffer_offset);
664 }
665
666
667 static char *
668 mmap_alloc_w_at (unix_stream * s, int *len, gfc_offset where)
669 {
670   if (where == -1)
671     where = s->logical_offset;
672
673   /* If we're extending the file, we have to use file descriptor
674    * methods. */
675
676   if (where + *len > s->file_length)
677     {
678       if (s->mmaped)
679         mmap_flush (s);
680       return fd_alloc_w_at (s, len, where);
681     }
682
683   if ((s->buffer == NULL || s->buffer_offset > where ||
684        where + *len > s->buffer_offset + s->active ||
685        where < s->buffer_offset + s->active) &&
686       mmap_alloc (s, where, len) == FAILURE)
687     return NULL;
688
689   s->logical_offset = where + *len;
690
691   return s->buffer + where - s->buffer_offset;
692 }
693
694
695 static int
696 mmap_seek (unix_stream * s, gfc_offset offset)
697 {
698   s->logical_offset = offset;
699   return SUCCESS;
700 }
701
702
703 static try
704 mmap_close (unix_stream * s)
705 {
706   try t;
707
708   t = mmap_flush (s);
709
710   if (close (s->fd) < 0)
711     t = FAILURE;
712   free_mem (s);
713
714   return t;
715 }
716
717
718 static try
719 mmap_sfree (unix_stream * s __attribute__ ((unused)))
720 {
721   return SUCCESS;
722 }
723
724
725 /* mmap_open()-- mmap_specific open.  If the particular file cannot be
726  * mmap()-ed, we fall back to the file descriptor functions. */
727
728 static try
729 mmap_open (unix_stream * s __attribute__ ((unused)))
730 {
731   char *p;
732   int i;
733
734   page_size = getpagesize ();
735   page_mask = ~0;
736
737   p = mmap (0, page_size, s->prot, MAP_SHARED, s->fd, 0);
738   if (p == (char *) MAP_FAILED)
739     {
740       fd_open (s);
741       return SUCCESS;
742     }
743
744   munmap (p, page_size);
745
746   i = page_size >> 1;
747   while (i != 0)
748     {
749       page_mask <<= 1;
750       i >>= 1;
751     }
752
753   s->st.alloc_r_at = (void *) mmap_alloc_r_at;
754   s->st.alloc_w_at = (void *) mmap_alloc_w_at;
755   s->st.sfree = (void *) mmap_sfree;
756   s->st.close = (void *) mmap_close;
757   s->st.seek = (void *) mmap_seek;
758   s->st.truncate = (void *) fd_truncate;
759
760   if (lseek (s->fd, s->file_length, SEEK_SET) < 0)
761     return FAILURE;
762
763   return SUCCESS;
764 }
765
766 #endif
767
768
769 /*********************************************************************
770   memory stream functions - These are used for internal files
771
772   The idea here is that a single stream structure is created and all
773   requests must be satisfied from it.  The location and size of the
774   buffer is the character variable supplied to the READ or WRITE
775   statement.
776
777 *********************************************************************/
778
779
780 static char *
781 mem_alloc_r_at (unix_stream * s, int *len, gfc_offset where)
782 {
783   gfc_offset n;
784
785   if (where == -1)
786     where = s->logical_offset;
787
788   if (where < s->buffer_offset || where > s->buffer_offset + s->active)
789     return NULL;
790
791   s->logical_offset = where + *len;
792
793   n = s->buffer_offset + s->active - where;
794   if (*len > n)
795     *len = n;
796
797   return s->buffer + (where - s->buffer_offset);
798 }
799
800
801 static char *
802 mem_alloc_w_at (unix_stream * s, int *len, gfc_offset where)
803 {
804   gfc_offset m;
805
806   if (where == -1)
807     where = s->logical_offset;
808
809   m = where + *len;
810
811   if (where < s->buffer_offset || m > s->buffer_offset + s->active)
812     return NULL;
813
814   s->logical_offset = m;
815
816   return s->buffer + (where - s->buffer_offset);
817 }
818
819
820 static int
821 mem_seek (unix_stream * s, gfc_offset offset)
822 {
823   if (offset > s->file_length)
824     {
825       errno = ESPIPE;
826       return FAILURE;
827     }
828
829   s->logical_offset = offset;
830   return SUCCESS;
831 }
832
833
834 static int
835 mem_truncate (unix_stream * s __attribute__ ((unused)))
836 {
837   return SUCCESS;
838 }
839
840
841 static try
842 mem_close (unix_stream * s)
843 {
844   free_mem (s);
845
846   return SUCCESS;
847 }
848
849
850 static try
851 mem_sfree (unix_stream * s __attribute__ ((unused)))
852 {
853   return SUCCESS;
854 }
855
856
857
858 /*********************************************************************
859   Public functions -- A reimplementation of this module needs to
860   define functional equivalents of the following.
861 *********************************************************************/
862
863 /* empty_internal_buffer()-- Zero the buffer of Internal file */
864
865 void
866 empty_internal_buffer(stream *strm)
867 {
868   unix_stream * s = (unix_stream *) strm;
869   memset(s->buffer, ' ', s->file_length);
870 }
871
872 /* open_internal()-- Returns a stream structure from an internal file */
873
874 stream *
875 open_internal (char *base, int length)
876 {
877   unix_stream *s;
878
879   s = get_mem (sizeof (unix_stream));
880   memset (s, '\0', sizeof (unix_stream));
881
882   s->buffer = base;
883   s->buffer_offset = 0;
884
885   s->logical_offset = 0;
886   s->active = s->file_length = length;
887
888   s->st.alloc_r_at = (void *) mem_alloc_r_at;
889   s->st.alloc_w_at = (void *) mem_alloc_w_at;
890   s->st.sfree = (void *) mem_sfree;
891   s->st.close = (void *) mem_close;
892   s->st.seek = (void *) mem_seek;
893   s->st.truncate = (void *) mem_truncate;
894
895   return (stream *) s;
896 }
897
898
899 /* fd_to_stream()-- Given an open file descriptor, build a stream
900  * around it. */
901
902 static stream *
903 fd_to_stream (int fd, int prot, int avoid_mmap)
904 {
905   struct stat statbuf;
906   unix_stream *s;
907
908   s = get_mem (sizeof (unix_stream));
909   memset (s, '\0', sizeof (unix_stream));
910
911   s->fd = fd;
912   s->buffer_offset = 0;
913   s->physical_offset = 0;
914   s->logical_offset = 0;
915   s->prot = prot;
916
917   /* Get the current length of the file. */
918
919   fstat (fd, &statbuf);
920   s->file_length = S_ISREG (statbuf.st_mode) ? statbuf.st_size : -1;
921   s->special_file = !S_ISREG (statbuf.st_mode);
922
923 #if HAVE_MMAP
924   if (avoid_mmap)
925     fd_open (s);
926   else
927     mmap_open (s);
928 #else
929   fd_open (s);
930 #endif
931
932   return (stream *) s;
933 }
934
935
936 /* Given the Fortran unit number, convert it to a C file descriptor.  */
937
938 int
939 unit_to_fd(int unit)
940 {
941   gfc_unit *us;
942
943   us = find_unit(unit);
944   if (us == NULL)
945     return -1;
946
947   return ((unix_stream *) us->s)->fd;
948 }
949
950
951 /* unpack_filename()-- Given a fortran string and a pointer to a
952  * buffer that is PATH_MAX characters, convert the fortran string to a
953  * C string in the buffer.  Returns nonzero if this is not possible.  */
954
955 static int
956 unpack_filename (char *cstring, const char *fstring, int len)
957 {
958   len = fstrlen (fstring, len);
959   if (len >= PATH_MAX)
960     return 1;
961
962   memmove (cstring, fstring, len);
963   cstring[len] = '\0';
964
965   return 0;
966 }
967
968
969 /* tempfile()-- Generate a temporary filename for a scratch file and
970  * open it.  mkstemp() opens the file for reading and writing, but the
971  * library mode prevents anything that is not allowed.  The descriptor
972  * is returned, which is -1 on error.  The template is pointed to by 
973  * ioparm.file, which is copied into the unit structure
974  * and freed later. */
975
976 static int
977 tempfile (void)
978 {
979   const char *tempdir;
980   char *template;
981   int fd;
982
983   tempdir = getenv ("GFORTRAN_TMPDIR");
984   if (tempdir == NULL)
985     tempdir = getenv ("TMP");
986   if (tempdir == NULL)
987     tempdir = getenv ("TEMP");
988   if (tempdir == NULL)
989     tempdir = DEFAULT_TEMPDIR;
990
991   template = get_mem (strlen (tempdir) + 20);
992
993   st_sprintf (template, "%s/gfortrantmpXXXXXX", tempdir);
994
995 #ifdef HAVE_MKSTEMP
996
997   fd = mkstemp (template);
998
999 #else /* HAVE_MKSTEMP */
1000
1001   if (mktemp (template))
1002     do
1003       fd = open (template, O_RDWR | O_CREAT | O_EXCL, S_IREAD | S_IWRITE);
1004     while (!(fd == -1 && errno == EEXIST) && mktemp (template));
1005   else
1006     fd = -1;
1007
1008 #endif /* HAVE_MKSTEMP */
1009
1010   if (fd < 0)
1011     free_mem (template);
1012   else
1013     {
1014       ioparm.file = template;
1015       ioparm.file_len = strlen (template);      /* Don't include trailing nul */
1016     }
1017
1018   return fd;
1019 }
1020
1021
1022 /* regular_file()-- Open a regular file.
1023  * Change flags->action if it is ACTION_UNSPECIFIED on entry,
1024  * unless an error occurs.
1025  * Returns the descriptor, which is less than zero on error. */
1026
1027 static int
1028 regular_file (unit_flags *flags)
1029 {
1030   char path[PATH_MAX + 1];
1031   int mode;
1032   int rwflag;
1033   int crflag;
1034   int fd;
1035
1036   if (unpack_filename (path, ioparm.file, ioparm.file_len))
1037     {
1038       errno = ENOENT;           /* Fake an OS error */
1039       return -1;
1040     }
1041
1042   rwflag = 0;
1043
1044   switch (flags->action)
1045     {
1046     case ACTION_READ:
1047       rwflag = O_RDONLY;
1048       break;
1049
1050     case ACTION_WRITE:
1051       rwflag = O_WRONLY;
1052       break;
1053
1054     case ACTION_READWRITE:
1055     case ACTION_UNSPECIFIED:
1056       rwflag = O_RDWR;
1057       break;
1058
1059     default:
1060       internal_error ("regular_file(): Bad action");
1061     }
1062
1063   switch (flags->status)
1064     {
1065     case STATUS_NEW:
1066       crflag = O_CREAT | O_EXCL;
1067       break;
1068
1069     case STATUS_OLD:            /* open will fail if the file does not exist*/
1070       crflag = 0;
1071       break;
1072
1073     case STATUS_UNKNOWN:
1074     case STATUS_SCRATCH:
1075       crflag = O_CREAT;
1076       break;
1077
1078     case STATUS_REPLACE:
1079         crflag = O_CREAT | O_TRUNC;
1080       break;
1081
1082     default:
1083       internal_error ("regular_file(): Bad status");
1084     }
1085
1086   /* rwflag |= O_LARGEFILE; */
1087
1088   mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
1089   fd = open (path, rwflag | crflag, mode);
1090   if (flags->action != ACTION_UNSPECIFIED)
1091       return fd;
1092
1093   if (fd >= 0)
1094     {
1095       flags->action = ACTION_READWRITE;
1096       return fd;
1097     }
1098   if (errno != EACCES)
1099      return fd;
1100
1101   /* retry for read-only access */
1102   rwflag = O_RDONLY;
1103   fd = open (path, rwflag | crflag, mode);
1104   if (fd >=0)
1105     {
1106       flags->action = ACTION_READ;
1107       return fd;               /* success */
1108     }
1109   
1110   if (errno != EACCES)
1111     return fd;                 /* failure */
1112
1113   /* retry for write-only access */
1114   rwflag = O_WRONLY;
1115   fd = open (path, rwflag | crflag, mode);
1116   if (fd >=0)
1117     {
1118       flags->action = ACTION_WRITE;
1119       return fd;               /* success */
1120     }
1121   return fd;                   /* failure */
1122 }
1123
1124
1125 /* open_external()-- Open an external file, unix specific version.
1126  * Change flags->action if it is ACTION_UNSPECIFIED on entry.
1127  * Returns NULL on operating system error. */
1128
1129 stream *
1130 open_external (unit_flags *flags)
1131 {
1132   int fd, prot;
1133
1134   if (flags->status == STATUS_SCRATCH)
1135     {
1136       fd = tempfile ();
1137       if (flags->action == ACTION_UNSPECIFIED)
1138         flags->action = ACTION_READWRITE;
1139       /* We can unlink scratch files now and it will go away when closed. */
1140       unlink (ioparm.file);
1141     }
1142   else
1143     {
1144       /* regular_file resets flags->action if it is ACTION_UNSPECIFIED and
1145        * if it succeeds */
1146       fd = regular_file (flags);
1147     }
1148
1149   if (fd < 0)
1150     return NULL;
1151   fd = fix_fd (fd);
1152
1153   switch (flags->action)
1154     {
1155     case ACTION_READ:
1156       prot = PROT_READ;
1157       break;
1158
1159     case ACTION_WRITE:
1160       prot = PROT_WRITE;
1161       break;
1162
1163     case ACTION_READWRITE:
1164       prot = PROT_READ | PROT_WRITE;
1165       break;
1166
1167     default:
1168       internal_error ("open_external(): Bad action");
1169     }
1170
1171   return fd_to_stream (fd, prot, 0);
1172 }
1173
1174
1175 /* input_stream()-- Return a stream pointer to the default input stream.
1176  * Called on initialization. */
1177
1178 stream *
1179 input_stream (void)
1180 {
1181   return fd_to_stream (STDIN_FILENO, PROT_READ, 1);
1182 }
1183
1184
1185 /* output_stream()-- Return a stream pointer to the default output stream.
1186  * Called on initialization. */
1187
1188 stream *
1189 output_stream (void)
1190 {
1191   return fd_to_stream (STDOUT_FILENO, PROT_WRITE, 1);
1192 }
1193
1194
1195 /* error_stream()-- Return a stream pointer to the default error stream.
1196  * Called on initialization. */
1197
1198 stream *
1199 error_stream (void)
1200 {
1201   return fd_to_stream (STDERR_FILENO, PROT_WRITE, 1);
1202 }
1203
1204 /* init_error_stream()-- Return a pointer to the error stream.  This
1205  * subroutine is called when the stream is needed, rather than at
1206  * initialization.  We want to work even if memory has been seriously
1207  * corrupted. */
1208
1209 stream *
1210 init_error_stream (void)
1211 {
1212   static unix_stream error;
1213
1214   memset (&error, '\0', sizeof (error));
1215
1216   error.fd = options.use_stderr ? STDERR_FILENO : STDOUT_FILENO;
1217
1218   error.st.alloc_w_at = (void *) fd_alloc_w_at;
1219   error.st.sfree = (void *) fd_sfree;
1220
1221   error.unbuffered = 1;
1222   error.buffer = error.small_buffer;
1223
1224   return (stream *) & error;
1225 }
1226
1227
1228 /* compare_file_filename()-- Given an open stream and a fortran string
1229  * that is a filename, figure out if the file is the same as the
1230  * filename. */
1231
1232 int
1233 compare_file_filename (stream * s, const char *name, int len)
1234 {
1235   char path[PATH_MAX + 1];
1236   struct stat st1, st2;
1237
1238   if (unpack_filename (path, name, len))
1239     return 0;                   /* Can't be the same */
1240
1241   /* If the filename doesn't exist, then there is no match with the
1242    * existing file. */
1243
1244   if (stat (path, &st1) < 0)
1245     return 0;
1246
1247   fstat (((unix_stream *) s)->fd, &st2);
1248
1249   return (st1.st_dev == st2.st_dev) && (st1.st_ino == st2.st_ino);
1250 }
1251
1252
1253 /* find_file0()-- Recursive work function for find_file() */
1254
1255 static gfc_unit *
1256 find_file0 (gfc_unit * u, struct stat *st1)
1257 {
1258   struct stat st2;
1259   gfc_unit *v;
1260
1261   if (u == NULL)
1262     return NULL;
1263
1264   if (fstat (((unix_stream *) u->s)->fd, &st2) >= 0 &&
1265       st1->st_dev == st2.st_dev && st1->st_ino == st2.st_ino)
1266     return u;
1267
1268   v = find_file0 (u->left, st1);
1269   if (v != NULL)
1270     return v;
1271
1272   v = find_file0 (u->right, st1);
1273   if (v != NULL)
1274     return v;
1275
1276   return NULL;
1277 }
1278
1279
1280 /* find_file()-- Take the current filename and see if there is a unit
1281  * that has the file already open.  Returns a pointer to the unit if so. */
1282
1283 gfc_unit *
1284 find_file (void)
1285 {
1286   char path[PATH_MAX + 1];
1287   struct stat statbuf;
1288
1289   if (unpack_filename (path, ioparm.file, ioparm.file_len))
1290     return NULL;
1291
1292   if (stat (path, &statbuf) < 0)
1293     return NULL;
1294
1295   return find_file0 (g.unit_root, &statbuf);
1296 }
1297
1298
1299 /* stream_at_bof()-- Returns nonzero if the stream is at the beginning
1300  * of the file. */
1301
1302 int
1303 stream_at_bof (stream * s)
1304 {
1305   unix_stream *us;
1306
1307   if (!is_seekable (s))
1308     return 0;
1309
1310   us = (unix_stream *) s;
1311
1312   return us->logical_offset == 0;
1313 }
1314
1315
1316 /* stream_at_eof()-- Returns nonzero if the stream is at the beginning
1317  * of the file. */
1318
1319 int
1320 stream_at_eof (stream * s)
1321 {
1322   unix_stream *us;
1323
1324   if (!is_seekable (s))
1325     return 0;
1326
1327   us = (unix_stream *) s;
1328
1329   return us->logical_offset == us->dirty_offset;
1330 }
1331
1332
1333 /* delete_file()-- Given a unit structure, delete the file associated
1334  * with the unit.  Returns nonzero if something went wrong. */
1335
1336 int
1337 delete_file (gfc_unit * u)
1338 {
1339   char path[PATH_MAX + 1];
1340
1341   if (unpack_filename (path, u->file, u->file_len))
1342     {                           /* Shouldn't be possible */
1343       errno = ENOENT;
1344       return 1;
1345     }
1346
1347   return unlink (path);
1348 }
1349
1350
1351 /* file_exists()-- Returns nonzero if the current filename exists on
1352  * the system */
1353
1354 int
1355 file_exists (void)
1356 {
1357   char path[PATH_MAX + 1];
1358   struct stat statbuf;
1359
1360   if (unpack_filename (path, ioparm.file, ioparm.file_len))
1361     return 0;
1362
1363   if (stat (path, &statbuf) < 0)
1364     return 0;
1365
1366   return 1;
1367 }
1368
1369
1370
1371 static const char *yes = "YES", *no = "NO", *unknown = "UNKNOWN";
1372
1373 /* inquire_sequential()-- Given a fortran string, determine if the
1374  * file is suitable for sequential access.  Returns a C-style
1375  * string. */
1376
1377 const char *
1378 inquire_sequential (const char *string, int len)
1379 {
1380   char path[PATH_MAX + 1];
1381   struct stat statbuf;
1382
1383   if (string == NULL ||
1384       unpack_filename (path, string, len) || stat (path, &statbuf) < 0)
1385     return unknown;
1386
1387   if (S_ISREG (statbuf.st_mode) ||
1388       S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode))
1389     return yes;
1390
1391   if (S_ISDIR (statbuf.st_mode) || S_ISBLK (statbuf.st_mode))
1392     return no;
1393
1394   return unknown;
1395 }
1396
1397
1398 /* inquire_direct()-- Given a fortran string, determine if the file is
1399  * suitable for direct access.  Returns a C-style string. */
1400
1401 const char *
1402 inquire_direct (const char *string, int len)
1403 {
1404   char path[PATH_MAX + 1];
1405   struct stat statbuf;
1406
1407   if (string == NULL ||
1408       unpack_filename (path, string, len) || stat (path, &statbuf) < 0)
1409     return unknown;
1410
1411   if (S_ISREG (statbuf.st_mode) || S_ISBLK (statbuf.st_mode))
1412     return yes;
1413
1414   if (S_ISDIR (statbuf.st_mode) ||
1415       S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode))
1416     return no;
1417
1418   return unknown;
1419 }
1420
1421
1422 /* inquire_formatted()-- Given a fortran string, determine if the file
1423  * is suitable for formatted form.  Returns a C-style string. */
1424
1425 const char *
1426 inquire_formatted (const char *string, int len)
1427 {
1428   char path[PATH_MAX + 1];
1429   struct stat statbuf;
1430
1431   if (string == NULL ||
1432       unpack_filename (path, string, len) || stat (path, &statbuf) < 0)
1433     return unknown;
1434
1435   if (S_ISREG (statbuf.st_mode) ||
1436       S_ISBLK (statbuf.st_mode) ||
1437       S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode))
1438     return yes;
1439
1440   if (S_ISDIR (statbuf.st_mode))
1441     return no;
1442
1443   return unknown;
1444 }
1445
1446
1447 /* inquire_unformatted()-- Given a fortran string, determine if the file
1448  * is suitable for unformatted form.  Returns a C-style string. */
1449
1450 const char *
1451 inquire_unformatted (const char *string, int len)
1452 {
1453   return inquire_formatted (string, len);
1454 }
1455
1456
1457 /* inquire_access()-- Given a fortran string, determine if the file is
1458  * suitable for access. */
1459
1460 static const char *
1461 inquire_access (const char *string, int len, int mode)
1462 {
1463   char path[PATH_MAX + 1];
1464
1465   if (string == NULL || unpack_filename (path, string, len) ||
1466       access (path, mode) < 0)
1467     return no;
1468
1469   return yes;
1470 }
1471
1472
1473 /* inquire_read()-- Given a fortran string, determine if the file is
1474  * suitable for READ access. */
1475
1476 const char *
1477 inquire_read (const char *string, int len)
1478 {
1479   return inquire_access (string, len, R_OK);
1480 }
1481
1482
1483 /* inquire_write()-- Given a fortran string, determine if the file is
1484  * suitable for READ access. */
1485
1486 const char *
1487 inquire_write (const char *string, int len)
1488 {
1489   return inquire_access (string, len, W_OK);
1490 }
1491
1492
1493 /* inquire_readwrite()-- Given a fortran string, determine if the file is
1494  * suitable for read and write access. */
1495
1496 const char *
1497 inquire_readwrite (const char *string, int len)
1498 {
1499   return inquire_access (string, len, R_OK | W_OK);
1500 }
1501
1502
1503 /* file_length()-- Return the file length in bytes, -1 if unknown */
1504
1505 gfc_offset
1506 file_length (stream * s)
1507 {
1508   return ((unix_stream *) s)->file_length;
1509 }
1510
1511
1512 /* file_position()-- Return the current position of the file */
1513
1514 gfc_offset
1515 file_position (stream * s)
1516 {
1517   return ((unix_stream *) s)->logical_offset;
1518 }
1519
1520
1521 /* is_seekable()-- Return nonzero if the stream is seekable, zero if
1522  * it is not */
1523
1524 int
1525 is_seekable (stream * s)
1526 {
1527   /* by convention, if file_length == -1, the file is not seekable
1528      note that a mmapped file is always seekable, an fd_ file may
1529      or may not be. */
1530   return ((unix_stream *) s)->file_length!=-1;
1531 }
1532
1533 try
1534 flush (stream *s)
1535 {
1536   return fd_flush( (unix_stream *) s);
1537 }
1538
1539
1540 /* How files are stored:  This is an operating-system specific issue,
1541    and therefore belongs here.  There are three cases to consider.
1542
1543    Direct Access:
1544       Records are written as block of bytes corresponding to the record
1545       length of the file.  This goes for both formatted and unformatted
1546       records.  Positioning is done explicitly for each data transfer,
1547       so positioning is not much of an issue.
1548
1549    Sequential Formatted:
1550       Records are separated by newline characters.  The newline character
1551       is prohibited from appearing in a string.  If it does, this will be
1552       messed up on the next read.  End of file is also the end of a record.
1553
1554    Sequential Unformatted:
1555       In this case, we are merely copying bytes to and from main storage,
1556       yet we need to keep track of varying record lengths.  We adopt
1557       the solution used by f2c.  Each record contains a pair of length
1558       markers:
1559
1560         Length of record n in bytes
1561         Data of record n
1562         Length of record n in bytes
1563
1564         Length of record n+1 in bytes
1565         Data of record n+1
1566         Length of record n+1 in bytes
1567
1568      The length is stored at the end of a record to allow backspacing to the
1569      previous record.  Between data transfer statements, the file pointer
1570      is left pointing to the first length of the current record.
1571
1572      ENDFILE records are never explicitly stored.
1573
1574 */