OSDN Git Service

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