1 /* Copyright (C) 2002, 2003, 2004, 2005
2 Free Software Foundation, Inc.
3 Contributed by Andy Vaught
5 This file is part of the GNU Fortran 95 runtime library (libgfortran).
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)
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
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.
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. */
31 /* Unix stream I/O module */
46 #include "libgfortran.h"
61 /* These flags aren't defined on all targets (mingw32), so provide them
79 /* This implementation of stream I/O is based on the paper:
81 * "Exploiting the advantages of mapped files for stream I/O",
82 * O. Krieger, M. Stumm and R. Umrau, "Proceedings of the 1992 Winter
83 * USENIX conference", p. 27-42.
85 * It differs in a number of ways from the version described in the
86 * paper. First of all, threads are not an issue during I/O and we
87 * also don't have to worry about having multiple regions, since
88 * fortran's I/O model only allows you to be one place at a time.
90 * On the other hand, we have to be able to writing at the end of a
91 * stream, read from the start of a stream or read and write blocks of
92 * bytes from an arbitrary position. After opening a file, a pointer
93 * to a stream structure is returned, which is used to handle file
94 * accesses until the file is closed.
96 * salloc_at_r(stream, len, where)-- Given a stream pointer, return a
97 * pointer to a block of memory that mirror the file at position
98 * 'where' that is 'len' bytes long. The len integer is updated to
99 * reflect how many bytes were actually read. The only reason for a
100 * short read is end of file. The file pointer is updated. The
101 * pointer is valid until the next call to salloc_*.
103 * salloc_at_w(stream, len, where)-- Given the stream pointer, returns
104 * a pointer to a block of memory that is updated to reflect the state
105 * of the file. The length of the buffer is always equal to that
106 * requested. The buffer must be completely set by the caller. When
107 * data has been written, the sfree() function must be called to
108 * indicate that the caller is done writing data to the buffer. This
109 * may or may not cause a physical write.
111 * Short forms of these are salloc_r() and salloc_w() which drop the
112 * 'where' parameter and use the current file pointer. */
115 #define BUFFER_SIZE 8192
122 gfc_offset buffer_offset
; /* File offset of the start of the buffer */
123 gfc_offset physical_offset
; /* Current physical file offset */
124 gfc_offset logical_offset
; /* Current logical file offset */
125 gfc_offset dirty_offset
; /* Start of modified bytes in buffer */
126 gfc_offset file_length
; /* Length of the file, -1 if not seekable. */
129 int len
; /* Physical length of the current buffer */
130 int active
; /* Length of valid bytes in the buffer */
133 int ndirty
; /* Dirty bytes starting at dirty_offset */
135 int special_file
; /* =1 if the fd refers to a special file */
137 unsigned unbuffered
:1;
139 char small_buffer
[BUFFER_SIZE
];
144 /*move_pos_offset()-- Move the record pointer right or left
145 *relative to current position */
148 move_pos_offset (stream
* st
, int pos_off
)
150 unix_stream
* str
= (unix_stream
*)st
;
153 str
->logical_offset
+= pos_off
;
155 if (str
->dirty_offset
+ str
->ndirty
> str
->logical_offset
)
157 if (str
->ndirty
+ pos_off
> 0)
158 str
->ndirty
+= pos_off
;
161 str
->dirty_offset
+= pos_off
+ pos_off
;
172 /* fix_fd()-- Given a file descriptor, make sure it is not one of the
173 * standard descriptors, returning a non-standard descriptor. If the
174 * user specifies that system errors should go to standard output,
175 * then closes standard output, we don't want the system errors to a
176 * file that has been given file descriptor 1 or 0. We want to send
177 * the error to the invalid descriptor. */
182 int input
, output
, error
;
184 input
= output
= error
= 0;
186 /* Unix allocates the lowest descriptors first, so a loop is not
187 required, but this order is. */
189 if (fd
== STDIN_FILENO
)
194 if (fd
== STDOUT_FILENO
)
199 if (fd
== STDERR_FILENO
)
206 close (STDIN_FILENO
);
208 close (STDOUT_FILENO
);
210 close (STDERR_FILENO
);
216 is_preconnected (stream
* s
)
220 fd
= ((unix_stream
*) s
)->fd
;
221 if (fd
== STDIN_FILENO
|| fd
== STDOUT_FILENO
|| fd
== STDERR_FILENO
)
228 /* Reset a stream after reading/writing. Assumes that the buffers have
232 reset_stream (unix_stream
* s
, size_t bytes_rw
)
234 s
->physical_offset
+= bytes_rw
;
235 s
->logical_offset
= s
->physical_offset
;
236 if (s
->file_length
!= -1 && s
->physical_offset
> s
->file_length
)
237 s
->file_length
= s
->physical_offset
;
241 /* Read bytes into a buffer, allowing for short reads. If the nbytes
242 * argument is less on return than on entry, it is because we've hit
243 * the end of file. */
246 do_read (unix_stream
* s
, void * buf
, size_t * nbytes
)
254 bytes_left
= *nbytes
;
255 buf_st
= (char *) buf
;
257 /* We must read in a loop since some systems don't restart system
258 calls in case of a signal. */
259 while (bytes_left
> 0)
261 /* Requests between SSIZE_MAX and SIZE_MAX are undefined by SUSv3,
262 so we must read in chunks smaller than SSIZE_MAX. */
263 trans
= (bytes_left
< SSIZE_MAX
) ? bytes_left
: SSIZE_MAX
;
264 trans
= read (s
->fd
, buf_st
, trans
);
275 else if (trans
== 0) /* We hit EOF. */
281 *nbytes
-= bytes_left
;
286 /* Write a buffer to a stream, allowing for short writes. */
289 do_write (unix_stream
* s
, const void * buf
, size_t * nbytes
)
297 bytes_left
= *nbytes
;
298 buf_st
= (char *) buf
;
300 /* We must write in a loop since some systems don't restart system
301 calls in case of a signal. */
302 while (bytes_left
> 0)
304 /* Requests between SSIZE_MAX and SIZE_MAX are undefined by SUSv3,
305 so we must write in chunks smaller than SSIZE_MAX. */
306 trans
= (bytes_left
< SSIZE_MAX
) ? bytes_left
: SSIZE_MAX
;
307 trans
= write (s
->fd
, buf_st
, trans
);
322 *nbytes
-= bytes_left
;
327 /* get_oserror()-- Get the most recent operating system error. For
328 * unix, this is errno. */
333 return strerror (errno
);
337 /* sys_exit()-- Terminate the program with an exit code */
346 /*********************************************************************
347 File descriptor stream functions
348 *********************************************************************/
351 /* fd_flush()-- Write bytes that need to be written */
354 fd_flush (unix_stream
* s
)
361 if (s
->physical_offset
!= s
->dirty_offset
&&
362 lseek (s
->fd
, s
->dirty_offset
, SEEK_SET
) < 0)
365 writelen
= s
->ndirty
;
366 if (do_write (s
, s
->buffer
+ (s
->dirty_offset
- s
->buffer_offset
),
370 s
->physical_offset
= s
->dirty_offset
+ writelen
;
372 /* don't increment file_length if the file is non-seekable */
373 if (s
->file_length
!= -1 && s
->physical_offset
> s
->file_length
)
374 s
->file_length
= s
->physical_offset
;
376 s
->ndirty
-= writelen
;
384 /* fd_alloc()-- Arrange a buffer such that the salloc() request can be
385 * satisfied. This subroutine gets the buffer ready for whatever is
389 fd_alloc (unix_stream
* s
, gfc_offset where
,
390 int *len
__attribute__ ((unused
)))
395 if (*len
<= BUFFER_SIZE
)
397 new_buffer
= s
->small_buffer
;
398 read_len
= BUFFER_SIZE
;
402 new_buffer
= get_mem (*len
);
406 /* Salvage bytes currently within the buffer. This is important for
407 * devices that cannot seek. */
409 if (s
->buffer
!= NULL
&& s
->buffer_offset
<= where
&&
410 where
<= s
->buffer_offset
+ s
->active
)
413 n
= s
->active
- (where
- s
->buffer_offset
);
414 memmove (new_buffer
, s
->buffer
+ (where
- s
->buffer_offset
), n
);
419 { /* new buffer starts off empty */
423 s
->buffer_offset
= where
;
425 /* free the old buffer if necessary */
427 if (s
->buffer
!= NULL
&& s
->buffer
!= s
->small_buffer
)
428 free_mem (s
->buffer
);
430 s
->buffer
= new_buffer
;
435 /* fd_alloc_r_at()-- Allocate a stream buffer for reading. Either
436 * we've already buffered the data or we need to load it. Returns
437 * NULL on I/O error. */
440 fd_alloc_r_at (unix_stream
* s
, int *len
, gfc_offset where
)
446 where
= s
->logical_offset
;
448 if (s
->buffer
!= NULL
&& s
->buffer_offset
<= where
&&
449 where
+ *len
<= s
->buffer_offset
+ s
->active
)
452 /* Return a position within the current buffer */
454 s
->logical_offset
= where
+ *len
;
455 return s
->buffer
+ where
- s
->buffer_offset
;
458 fd_alloc (s
, where
, len
);
460 m
= where
+ s
->active
;
462 if (s
->physical_offset
!= m
&& lseek (s
->fd
, m
, SEEK_SET
) < 0)
465 n
= read (s
->fd
, s
->buffer
+ s
->active
, s
->len
- s
->active
);
469 s
->physical_offset
= where
+ n
;
472 if (s
->active
< *len
)
473 *len
= s
->active
; /* Bytes actually available */
475 s
->logical_offset
= where
+ *len
;
481 /* fd_alloc_w_at()-- Allocate a stream buffer for writing. Either
482 * we've already buffered the data or we need to load it. */
485 fd_alloc_w_at (unix_stream
* s
, int *len
, gfc_offset where
)
490 where
= s
->logical_offset
;
492 if (s
->buffer
== NULL
|| s
->buffer_offset
> where
||
493 where
+ *len
> s
->buffer_offset
+ s
->len
)
496 if (fd_flush (s
) == FAILURE
)
498 fd_alloc (s
, where
, len
);
501 /* Return a position within the current buffer */
503 || where
> s
->dirty_offset
+ s
->ndirty
504 || s
->dirty_offset
> where
+ *len
)
505 { /* Discontiguous blocks, start with a clean buffer. */
506 /* Flush the buffer. */
509 s
->dirty_offset
= where
;
514 gfc_offset start
; /* Merge with the existing data. */
515 if (where
< s
->dirty_offset
)
518 start
= s
->dirty_offset
;
519 if (where
+ *len
> s
->dirty_offset
+ s
->ndirty
)
520 s
->ndirty
= where
+ *len
- start
;
522 s
->ndirty
= s
->dirty_offset
+ s
->ndirty
- start
;
523 s
->dirty_offset
= start
;
526 s
->logical_offset
= where
+ *len
;
528 if (where
+ *len
> s
->file_length
)
529 s
->file_length
= where
+ *len
;
531 n
= s
->logical_offset
- s
->buffer_offset
;
535 return s
->buffer
+ where
- s
->buffer_offset
;
540 fd_sfree (unix_stream
* s
)
542 if (s
->ndirty
!= 0 &&
543 (s
->buffer
!= s
->small_buffer
|| options
.all_unbuffered
||
552 fd_seek (unix_stream
* s
, gfc_offset offset
)
554 if (s
->physical_offset
== offset
) /* Are we lucky and avoid syscall? */
556 s
->logical_offset
= offset
;
560 s
->physical_offset
= s
->logical_offset
= offset
;
562 return (lseek (s
->fd
, offset
, SEEK_SET
) < 0) ? FAILURE
: SUCCESS
;
566 /* truncate_file()-- Given a unit, truncate the file at the current
567 * position. Sets the physical location to the new end of the file.
568 * Returns nonzero on error. */
571 fd_truncate (unix_stream
* s
)
573 if (lseek (s
->fd
, s
->logical_offset
, SEEK_SET
) == -1)
576 /* non-seekable files, like terminals and fifo's fail the lseek.
577 Using ftruncate on a seekable special file (like /dev/null)
578 is undefined, so we treat it as if the ftruncate failed.
580 #ifdef HAVE_FTRUNCATE
581 if (s
->special_file
|| ftruncate (s
->fd
, s
->logical_offset
))
584 if (s
->special_file
|| chsize (s
->fd
, s
->logical_offset
))
588 s
->physical_offset
= s
->file_length
= 0;
592 s
->physical_offset
= s
->file_length
= s
->logical_offset
;
600 /* Stream read function. Avoids using a buffer for big reads. The
601 interface is like POSIX read(), but the nbytes argument is a
602 pointer; on return it contains the number of bytes written. The
603 function return value is the status indicator (0 for success). */
606 fd_read (unix_stream
* s
, void * buf
, size_t * nbytes
)
611 if (*nbytes
< BUFFER_SIZE
&& !s
->unbuffered
)
614 p
= fd_alloc_r_at (s
, &tmp
, -1);
618 memcpy (buf
, p
, *nbytes
);
628 /* If the request is bigger than BUFFER_SIZE we flush the buffers
629 and read directly. */
630 if (fd_flush (s
) == FAILURE
)
636 if (is_seekable ((stream
*) s
) && fd_seek (s
, s
->logical_offset
) == FAILURE
)
642 status
= do_read (s
, buf
, nbytes
);
643 reset_stream (s
, *nbytes
);
648 /* Stream write function. Avoids using a buffer for big writes. The
649 interface is like POSIX write(), but the nbytes argument is a
650 pointer; on return it contains the number of bytes written. The
651 function return value is the status indicator (0 for success). */
654 fd_write (unix_stream
* s
, const void * buf
, size_t * nbytes
)
659 if (*nbytes
< BUFFER_SIZE
&& !s
->unbuffered
)
662 p
= fd_alloc_w_at (s
, &tmp
, -1);
666 memcpy (p
, buf
, *nbytes
);
676 /* If the request is bigger than BUFFER_SIZE we flush the buffers
677 and write directly. */
678 if (fd_flush (s
) == FAILURE
)
684 if (is_seekable ((stream
*) s
) && fd_seek (s
, s
->logical_offset
) == FAILURE
)
690 status
= do_write (s
, buf
, nbytes
);
691 reset_stream (s
, *nbytes
);
697 fd_close (unix_stream
* s
)
699 if (fd_flush (s
) == FAILURE
)
702 if (s
->buffer
!= NULL
&& s
->buffer
!= s
->small_buffer
)
703 free_mem (s
->buffer
);
705 if (s
->fd
!= STDOUT_FILENO
&& s
->fd
!= STDERR_FILENO
)
707 if (close (s
->fd
) < 0)
718 fd_open (unix_stream
* s
)
723 s
->st
.alloc_r_at
= (void *) fd_alloc_r_at
;
724 s
->st
.alloc_w_at
= (void *) fd_alloc_w_at
;
725 s
->st
.sfree
= (void *) fd_sfree
;
726 s
->st
.close
= (void *) fd_close
;
727 s
->st
.seek
= (void *) fd_seek
;
728 s
->st
.truncate
= (void *) fd_truncate
;
729 s
->st
.read
= (void *) fd_read
;
730 s
->st
.write
= (void *) fd_write
;
738 /*********************************************************************
739 memory stream functions - These are used for internal files
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
746 *********************************************************************/
750 mem_alloc_r_at (unix_stream
* s
, int *len
, gfc_offset where
)
755 where
= s
->logical_offset
;
757 if (where
< s
->buffer_offset
|| where
> s
->buffer_offset
+ s
->active
)
760 s
->logical_offset
= where
+ *len
;
762 n
= s
->buffer_offset
+ s
->active
- where
;
766 return s
->buffer
+ (where
- s
->buffer_offset
);
771 mem_alloc_w_at (unix_stream
* s
, int *len
, gfc_offset where
)
775 assert (*len
>= 0); /* Negative values not allowed. */
778 where
= s
->logical_offset
;
782 if (where
< s
->buffer_offset
)
785 if (m
> s
->file_length
)
788 s
->logical_offset
= m
;
790 return s
->buffer
+ (where
- s
->buffer_offset
);
794 /* Stream read function for internal units. This is not actually used
795 at the moment, as all internal IO is formatted and the formatted IO
796 routines use mem_alloc_r_at. */
799 mem_read (unix_stream
* s
, void * buf
, size_t * nbytes
)
805 p
= mem_alloc_r_at (s
, &tmp
, -1);
809 memcpy (buf
, p
, *nbytes
);
820 /* Stream write function for internal units. This is not actually used
821 at the moment, as all internal IO is formatted and the formatted IO
822 routines use mem_alloc_w_at. */
825 mem_write (unix_stream
* s
, const void * buf
, size_t * nbytes
)
833 p
= mem_alloc_w_at (s
, &tmp
, -1);
837 memcpy (p
, buf
, *nbytes
);
849 mem_seek (unix_stream
* s
, gfc_offset offset
)
851 if (offset
> s
->file_length
)
857 s
->logical_offset
= offset
;
863 mem_truncate (unix_stream
* s
__attribute__ ((unused
)))
870 mem_close (unix_stream
* s
)
879 mem_sfree (unix_stream
* s
__attribute__ ((unused
)))
886 /*********************************************************************
887 Public functions -- A reimplementation of this module needs to
888 define functional equivalents of the following.
889 *********************************************************************/
891 /* empty_internal_buffer()-- Zero the buffer of Internal file */
894 empty_internal_buffer(stream
*strm
)
896 unix_stream
* s
= (unix_stream
*) strm
;
897 memset(s
->buffer
, ' ', s
->file_length
);
900 /* open_internal()-- Returns a stream structure from an internal file */
903 open_internal (char *base
, int length
)
907 s
= get_mem (sizeof (unix_stream
));
908 memset (s
, '\0', sizeof (unix_stream
));
911 s
->buffer_offset
= 0;
913 s
->logical_offset
= 0;
914 s
->active
= s
->file_length
= length
;
916 s
->st
.alloc_r_at
= (void *) mem_alloc_r_at
;
917 s
->st
.alloc_w_at
= (void *) mem_alloc_w_at
;
918 s
->st
.sfree
= (void *) mem_sfree
;
919 s
->st
.close
= (void *) mem_close
;
920 s
->st
.seek
= (void *) mem_seek
;
921 s
->st
.truncate
= (void *) mem_truncate
;
922 s
->st
.read
= (void *) mem_read
;
923 s
->st
.write
= (void *) mem_write
;
929 /* fd_to_stream()-- Given an open file descriptor, build a stream
933 fd_to_stream (int fd
, int prot
)
938 s
= get_mem (sizeof (unix_stream
));
939 memset (s
, '\0', sizeof (unix_stream
));
942 s
->buffer_offset
= 0;
943 s
->physical_offset
= 0;
944 s
->logical_offset
= 0;
947 /* Get the current length of the file. */
949 fstat (fd
, &statbuf
);
950 s
->file_length
= S_ISREG (statbuf
.st_mode
) ? statbuf
.st_size
: -1;
951 s
->special_file
= !S_ISREG (statbuf
.st_mode
);
959 /* Given the Fortran unit number, convert it to a C file descriptor. */
966 us
= find_unit(unit
);
970 return ((unix_stream
*) us
->s
)->fd
;
974 /* unpack_filename()-- Given a fortran string and a pointer to a
975 * buffer that is PATH_MAX characters, convert the fortran string to a
976 * C string in the buffer. Returns nonzero if this is not possible. */
979 unpack_filename (char *cstring
, const char *fstring
, int len
)
981 len
= fstrlen (fstring
, len
);
985 memmove (cstring
, fstring
, len
);
992 /* tempfile()-- Generate a temporary filename for a scratch file and
993 * open it. mkstemp() opens the file for reading and writing, but the
994 * library mode prevents anything that is not allowed. The descriptor
995 * is returned, which is -1 on error. The template is pointed to by
996 * ioparm.file, which is copied into the unit structure
997 * and freed later. */
1002 const char *tempdir
;
1006 tempdir
= getenv ("GFORTRAN_TMPDIR");
1007 if (tempdir
== NULL
)
1008 tempdir
= getenv ("TMP");
1009 if (tempdir
== NULL
)
1010 tempdir
= getenv ("TEMP");
1011 if (tempdir
== NULL
)
1012 tempdir
= DEFAULT_TEMPDIR
;
1014 template = get_mem (strlen (tempdir
) + 20);
1016 st_sprintf (template, "%s/gfortrantmpXXXXXX", tempdir
);
1020 fd
= mkstemp (template);
1022 #else /* HAVE_MKSTEMP */
1024 if (mktemp (template))
1027 fd
= open (template, O_RDWR
| O_CREAT
| O_EXCL
| O_BINARY
,
1028 S_IREAD
| S_IWRITE
);
1030 fd
= open (template, O_RDWR
| O_CREAT
| O_EXCL
, S_IREAD
| S_IWRITE
);
1032 while (!(fd
== -1 && errno
== EEXIST
) && mktemp (template));
1036 #endif /* HAVE_MKSTEMP */
1039 free_mem (template);
1042 ioparm
.file
= template;
1043 ioparm
.file_len
= strlen (template); /* Don't include trailing nul */
1050 /* regular_file()-- Open a regular file.
1051 * Change flags->action if it is ACTION_UNSPECIFIED on entry,
1052 * unless an error occurs.
1053 * Returns the descriptor, which is less than zero on error. */
1056 regular_file (unit_flags
*flags
)
1058 char path
[PATH_MAX
+ 1];
1064 if (unpack_filename (path
, ioparm
.file
, ioparm
.file_len
))
1066 errno
= ENOENT
; /* Fake an OS error */
1072 switch (flags
->action
)
1082 case ACTION_READWRITE
:
1083 case ACTION_UNSPECIFIED
:
1088 internal_error ("regular_file(): Bad action");
1091 switch (flags
->status
)
1094 crflag
= O_CREAT
| O_EXCL
;
1097 case STATUS_OLD
: /* open will fail if the file does not exist*/
1101 case STATUS_UNKNOWN
:
1102 case STATUS_SCRATCH
:
1106 case STATUS_REPLACE
:
1107 crflag
= O_CREAT
| O_TRUNC
;
1111 internal_error ("regular_file(): Bad status");
1114 /* rwflag |= O_LARGEFILE; */
1120 mode
= S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IWGRP
| S_IROTH
| S_IWOTH
;
1121 fd
= open (path
, rwflag
| crflag
, mode
);
1122 if (flags
->action
!= ACTION_UNSPECIFIED
)
1127 flags
->action
= ACTION_READWRITE
;
1130 if (errno
!= EACCES
)
1133 /* retry for read-only access */
1135 fd
= open (path
, rwflag
| crflag
, mode
);
1138 flags
->action
= ACTION_READ
;
1139 return fd
; /* success */
1142 if (errno
!= EACCES
)
1143 return fd
; /* failure */
1145 /* retry for write-only access */
1147 fd
= open (path
, rwflag
| crflag
, mode
);
1150 flags
->action
= ACTION_WRITE
;
1151 return fd
; /* success */
1153 return fd
; /* failure */
1157 /* open_external()-- Open an external file, unix specific version.
1158 * Change flags->action if it is ACTION_UNSPECIFIED on entry.
1159 * Returns NULL on operating system error. */
1162 open_external (unit_flags
*flags
)
1166 if (flags
->status
== STATUS_SCRATCH
)
1169 if (flags
->action
== ACTION_UNSPECIFIED
)
1170 flags
->action
= ACTION_READWRITE
;
1172 #if HAVE_UNLINK_OPEN_FILE
1173 /* We can unlink scratch files now and it will go away when closed. */
1174 unlink (ioparm
.file
);
1179 /* regular_file resets flags->action if it is ACTION_UNSPECIFIED and
1181 fd
= regular_file (flags
);
1188 switch (flags
->action
)
1198 case ACTION_READWRITE
:
1199 prot
= PROT_READ
| PROT_WRITE
;
1203 internal_error ("open_external(): Bad action");
1206 return fd_to_stream (fd
, prot
);
1210 /* input_stream()-- Return a stream pointer to the default input stream.
1211 * Called on initialization. */
1216 return fd_to_stream (STDIN_FILENO
, PROT_READ
);
1220 /* output_stream()-- Return a stream pointer to the default output stream.
1221 * Called on initialization. */
1224 output_stream (void)
1226 return fd_to_stream (STDOUT_FILENO
, PROT_WRITE
);
1230 /* error_stream()-- Return a stream pointer to the default error stream.
1231 * Called on initialization. */
1236 return fd_to_stream (STDERR_FILENO
, PROT_WRITE
);
1239 /* init_error_stream()-- Return a pointer to the error stream. This
1240 * subroutine is called when the stream is needed, rather than at
1241 * initialization. We want to work even if memory has been seriously
1245 init_error_stream (void)
1247 static unix_stream error
;
1249 memset (&error
, '\0', sizeof (error
));
1251 error
.fd
= options
.use_stderr
? STDERR_FILENO
: STDOUT_FILENO
;
1253 error
.st
.alloc_w_at
= (void *) fd_alloc_w_at
;
1254 error
.st
.sfree
= (void *) fd_sfree
;
1256 error
.unbuffered
= 1;
1257 error
.buffer
= error
.small_buffer
;
1259 return (stream
*) & error
;
1263 /* compare_file_filename()-- Given an open stream and a fortran string
1264 * that is a filename, figure out if the file is the same as the
1268 compare_file_filename (stream
* s
, const char *name
, int len
)
1270 char path
[PATH_MAX
+ 1];
1271 struct stat st1
, st2
;
1273 if (unpack_filename (path
, name
, len
))
1274 return 0; /* Can't be the same */
1276 /* If the filename doesn't exist, then there is no match with the
1279 if (stat (path
, &st1
) < 0)
1282 fstat (((unix_stream
*) s
)->fd
, &st2
);
1284 return (st1
.st_dev
== st2
.st_dev
) && (st1
.st_ino
== st2
.st_ino
);
1288 /* find_file0()-- Recursive work function for find_file() */
1291 find_file0 (gfc_unit
* u
, struct stat
*st1
)
1299 if (fstat (((unix_stream
*) u
->s
)->fd
, &st2
) >= 0 &&
1300 st1
->st_dev
== st2
.st_dev
&& st1
->st_ino
== st2
.st_ino
)
1303 v
= find_file0 (u
->left
, st1
);
1307 v
= find_file0 (u
->right
, st1
);
1315 /* find_file()-- Take the current filename and see if there is a unit
1316 * that has the file already open. Returns a pointer to the unit if so. */
1321 char path
[PATH_MAX
+ 1];
1322 struct stat statbuf
;
1324 if (unpack_filename (path
, ioparm
.file
, ioparm
.file_len
))
1327 if (stat (path
, &statbuf
) < 0)
1330 return find_file0 (g
.unit_root
, &statbuf
);
1334 /* stream_at_bof()-- Returns nonzero if the stream is at the beginning
1338 stream_at_bof (stream
* s
)
1342 if (!is_seekable (s
))
1345 us
= (unix_stream
*) s
;
1347 return us
->logical_offset
== 0;
1351 /* stream_at_eof()-- Returns nonzero if the stream is at the beginning
1355 stream_at_eof (stream
* s
)
1359 if (!is_seekable (s
))
1362 us
= (unix_stream
*) s
;
1364 return us
->logical_offset
== us
->dirty_offset
;
1368 /* delete_file()-- Given a unit structure, delete the file associated
1369 * with the unit. Returns nonzero if something went wrong. */
1372 delete_file (gfc_unit
* u
)
1374 char path
[PATH_MAX
+ 1];
1376 if (unpack_filename (path
, u
->file
, u
->file_len
))
1377 { /* Shouldn't be possible */
1382 return unlink (path
);
1386 /* file_exists()-- Returns nonzero if the current filename exists on
1392 char path
[PATH_MAX
+ 1];
1393 struct stat statbuf
;
1395 if (unpack_filename (path
, ioparm
.file
, ioparm
.file_len
))
1398 if (stat (path
, &statbuf
) < 0)
1406 static const char yes
[] = "YES", no
[] = "NO", unknown
[] = "UNKNOWN";
1408 /* inquire_sequential()-- Given a fortran string, determine if the
1409 * file is suitable for sequential access. Returns a C-style
1413 inquire_sequential (const char *string
, int len
)
1415 char path
[PATH_MAX
+ 1];
1416 struct stat statbuf
;
1418 if (string
== NULL
||
1419 unpack_filename (path
, string
, len
) || stat (path
, &statbuf
) < 0)
1422 if (S_ISREG (statbuf
.st_mode
) ||
1423 S_ISCHR (statbuf
.st_mode
) || S_ISFIFO (statbuf
.st_mode
))
1426 if (S_ISDIR (statbuf
.st_mode
) || S_ISBLK (statbuf
.st_mode
))
1433 /* inquire_direct()-- Given a fortran string, determine if the file is
1434 * suitable for direct access. Returns a C-style string. */
1437 inquire_direct (const char *string
, int len
)
1439 char path
[PATH_MAX
+ 1];
1440 struct stat statbuf
;
1442 if (string
== NULL
||
1443 unpack_filename (path
, string
, len
) || stat (path
, &statbuf
) < 0)
1446 if (S_ISREG (statbuf
.st_mode
) || S_ISBLK (statbuf
.st_mode
))
1449 if (S_ISDIR (statbuf
.st_mode
) ||
1450 S_ISCHR (statbuf
.st_mode
) || S_ISFIFO (statbuf
.st_mode
))
1457 /* inquire_formatted()-- Given a fortran string, determine if the file
1458 * is suitable for formatted form. Returns a C-style string. */
1461 inquire_formatted (const char *string
, int len
)
1463 char path
[PATH_MAX
+ 1];
1464 struct stat statbuf
;
1466 if (string
== NULL
||
1467 unpack_filename (path
, string
, len
) || stat (path
, &statbuf
) < 0)
1470 if (S_ISREG (statbuf
.st_mode
) ||
1471 S_ISBLK (statbuf
.st_mode
) ||
1472 S_ISCHR (statbuf
.st_mode
) || S_ISFIFO (statbuf
.st_mode
))
1475 if (S_ISDIR (statbuf
.st_mode
))
1482 /* inquire_unformatted()-- Given a fortran string, determine if the file
1483 * is suitable for unformatted form. Returns a C-style string. */
1486 inquire_unformatted (const char *string
, int len
)
1488 return inquire_formatted (string
, len
);
1492 /* inquire_access()-- Given a fortran string, determine if the file is
1493 * suitable for access. */
1496 inquire_access (const char *string
, int len
, int mode
)
1498 char path
[PATH_MAX
+ 1];
1500 if (string
== NULL
|| unpack_filename (path
, string
, len
) ||
1501 access (path
, mode
) < 0)
1508 /* inquire_read()-- Given a fortran string, determine if the file is
1509 * suitable for READ access. */
1512 inquire_read (const char *string
, int len
)
1514 return inquire_access (string
, len
, R_OK
);
1518 /* inquire_write()-- Given a fortran string, determine if the file is
1519 * suitable for READ access. */
1522 inquire_write (const char *string
, int len
)
1524 return inquire_access (string
, len
, W_OK
);
1528 /* inquire_readwrite()-- Given a fortran string, determine if the file is
1529 * suitable for read and write access. */
1532 inquire_readwrite (const char *string
, int len
)
1534 return inquire_access (string
, len
, R_OK
| W_OK
);
1538 /* file_length()-- Return the file length in bytes, -1 if unknown */
1541 file_length (stream
* s
)
1543 return ((unix_stream
*) s
)->file_length
;
1547 /* file_position()-- Return the current position of the file */
1550 file_position (stream
* s
)
1552 return ((unix_stream
*) s
)->logical_offset
;
1556 /* is_seekable()-- Return nonzero if the stream is seekable, zero if
1560 is_seekable (stream
* s
)
1562 /* By convention, if file_length == -1, the file is not
1564 return ((unix_stream
*) s
)->file_length
!=-1;
1570 return fd_flush( (unix_stream
*) s
);
1574 stream_isatty (stream
*s
)
1576 return isatty (((unix_stream
*) s
)->fd
);
1580 stream_ttyname (stream
*s
)
1583 return ttyname (((unix_stream
*) s
)->fd
);
1590 /* How files are stored: This is an operating-system specific issue,
1591 and therefore belongs here. There are three cases to consider.
1594 Records are written as block of bytes corresponding to the record
1595 length of the file. This goes for both formatted and unformatted
1596 records. Positioning is done explicitly for each data transfer,
1597 so positioning is not much of an issue.
1599 Sequential Formatted:
1600 Records are separated by newline characters. The newline character
1601 is prohibited from appearing in a string. If it does, this will be
1602 messed up on the next read. End of file is also the end of a record.
1604 Sequential Unformatted:
1605 In this case, we are merely copying bytes to and from main storage,
1606 yet we need to keep track of varying record lengths. We adopt
1607 the solution used by f2c. Each record contains a pair of length
1610 Length of record n in bytes
1612 Length of record n in bytes
1614 Length of record n+1 in bytes
1616 Length of record n+1 in bytes
1618 The length is stored at the end of a record to allow backspacing to the
1619 previous record. Between data transfer statements, the file pointer
1620 is left pointing to the first length of the current record.
1622 ENDFILE records are never explicitly stored.