OSDN Git Service

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