1 /* Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
3 Free Software Foundation, Inc.
4 Contributed by Andy Vaught
5 F2003 I/O support contributed by Jerry DeLisle
7 This file is part of the GNU Fortran runtime library (libgfortran).
9 Libgfortran is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3, or (at your option)
14 Libgfortran is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 Under Section 7 of GPL version 3, you are granted additional
20 permissions described in the GCC Runtime Library Exception, version
21 3.1, as published by the Free Software Foundation.
23 You should have received a copy of the GNU General Public License and
24 a copy of the GCC Runtime Library Exception along with this program;
25 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
26 <http://www.gnu.org/licenses/>. */
28 /* Unix stream I/O module */
44 /* For mingw, we don't identify files by their inode number, but by a
45 64-bit identifier created from a BY_HANDLE_FILE_INFORMATION. */
48 #define WIN32_LEAN_AND_MEAN
51 #if !defined(_FILE_OFFSET_BITS) || _FILE_OFFSET_BITS != 64
53 #define lseek _lseeki64
55 #define fstat _fstati64
60 #ifndef HAVE_WORKING_STAT
62 id_from_handle (HANDLE hFile
)
64 BY_HANDLE_FILE_INFORMATION FileInformation
;
66 if (hFile
== INVALID_HANDLE_VALUE
)
69 memset (&FileInformation
, 0, sizeof(FileInformation
));
70 if (!GetFileInformationByHandle (hFile
, &FileInformation
))
73 return ((uint64_t) FileInformation
.nFileIndexLow
)
74 | (((uint64_t) FileInformation
.nFileIndexHigh
) << 32);
79 id_from_path (const char *path
)
84 if (!path
|| !*path
|| access (path
, F_OK
))
87 hFile
= CreateFile (path
, 0, 0, NULL
, OPEN_EXISTING
,
88 FILE_FLAG_BACKUP_SEMANTICS
| FILE_ATTRIBUTE_READONLY
,
90 res
= id_from_handle (hFile
);
97 id_from_fd (const int fd
)
99 return id_from_handle ((HANDLE
) _get_osfhandle (fd
));
102 #endif /* HAVE_WORKING_STAT */
103 #endif /* __MINGW32__ */
106 /* min macro that evaluates its arguments only once. */
112 ({ typeof (a) _a = (a); \
113 typeof (b) _b = (b); \
114 _a < _b ? _a : _b; })
117 #define PATH_MAX 1024
120 /* These flags aren't defined on all targets (mingw32), so provide them
153 /* Fallback implementation of access() on systems that don't have it.
154 Only modes R_OK, W_OK and F_OK are used in this file. */
157 fallback_access (const char *path
, int mode
)
161 if ((mode
& R_OK
) && (fd
= open (path
, O_RDONLY
)) < 0)
165 if ((mode
& W_OK
) && (fd
= open (path
, O_WRONLY
)) < 0)
172 return stat (path
, &st
);
179 #define access fallback_access
183 /* Fallback directory for creating temporary files. P_tmpdir is
184 defined on many POSIX platforms. */
187 #define P_tmpdir _P_tmpdir /* MinGW */
189 #define P_tmpdir "/tmp"
194 /* Unix and internal stream I/O module */
196 static const int BUFFER_SIZE
= 8192;
202 gfc_offset buffer_offset
; /* File offset of the start of the buffer */
203 gfc_offset physical_offset
; /* Current physical file offset */
204 gfc_offset logical_offset
; /* Current logical file offset */
205 gfc_offset file_length
; /* Length of the file. */
207 char *buffer
; /* Pointer to the buffer. */
208 int fd
; /* The POSIX file descriptor. */
210 int active
; /* Length of valid bytes in the buffer */
212 int ndirty
; /* Dirty bytes starting at buffer_offset */
214 /* Cached stat(2) values. */
221 /* fix_fd()-- Given a file descriptor, make sure it is not one of the
222 * standard descriptors, returning a non-standard descriptor. If the
223 * user specifies that system errors should go to standard output,
224 * then closes standard output, we don't want the system errors to a
225 * file that has been given file descriptor 1 or 0. We want to send
226 * the error to the invalid descriptor. */
232 int input
, output
, error
;
234 input
= output
= error
= 0;
236 /* Unix allocates the lowest descriptors first, so a loop is not
237 required, but this order is. */
238 if (fd
== STDIN_FILENO
)
243 if (fd
== STDOUT_FILENO
)
248 if (fd
== STDERR_FILENO
)
255 close (STDIN_FILENO
);
257 close (STDOUT_FILENO
);
259 close (STDERR_FILENO
);
266 /* If the stream corresponds to a preconnected unit, we flush the
267 corresponding C stream. This is bugware for mixed C-Fortran codes
268 where the C code doesn't flush I/O before returning. */
270 flush_if_preconnected (stream
* s
)
274 fd
= ((unix_stream
*) s
)->fd
;
275 if (fd
== STDIN_FILENO
)
277 else if (fd
== STDOUT_FILENO
)
279 else if (fd
== STDERR_FILENO
)
284 /********************************************************************
285 Raw I/O functions (read, write, seek, tell, truncate, close).
287 These functions wrap the basic POSIX I/O syscalls. Any deviation in
288 semantics is a bug, except the following: write restarts in case
289 of being interrupted by a signal, and as the first argument the
290 functions take the unix_stream struct rather than an integer file
291 descriptor. Also, for POSIX read() and write() a nbyte argument larger
292 than SSIZE_MAX is undefined; here the type of nbyte is ssize_t rather
293 than size_t as for POSIX read/write.
294 *********************************************************************/
297 raw_flush (unix_stream
* s
__attribute__ ((unused
)))
303 raw_read (unix_stream
* s
, void * buf
, ssize_t nbyte
)
305 /* For read we can't do I/O in a loop like raw_write does, because
306 that will break applications that wait for interactive I/O. */
307 return read (s
->fd
, buf
, nbyte
);
311 raw_write (unix_stream
* s
, const void * buf
, ssize_t nbyte
)
313 ssize_t trans
, bytes_left
;
317 buf_st
= (char *) buf
;
319 /* We must write in a loop since some systems don't restart system
320 calls in case of a signal. */
321 while (bytes_left
> 0)
323 trans
= write (s
->fd
, buf_st
, bytes_left
);
335 return nbyte
- bytes_left
;
339 raw_seek (unix_stream
* s
, gfc_offset offset
, int whence
)
341 return lseek (s
->fd
, offset
, whence
);
345 raw_tell (unix_stream
* s
)
347 return lseek (s
->fd
, 0, SEEK_CUR
);
351 raw_size (unix_stream
* s
)
354 int ret
= fstat (s
->fd
, &statbuf
);
357 return statbuf
.st_size
;
361 raw_truncate (unix_stream
* s
, gfc_offset length
)
372 h
= (HANDLE
) _get_osfhandle (s
->fd
);
373 if (h
== INVALID_HANDLE_VALUE
)
378 cur
= lseek (s
->fd
, 0, SEEK_CUR
);
381 if (lseek (s
->fd
, length
, SEEK_SET
) == -1)
383 if (!SetEndOfFile (h
))
388 if (lseek (s
->fd
, cur
, SEEK_SET
) == -1)
392 lseek (s
->fd
, cur
, SEEK_SET
);
394 #elif defined HAVE_FTRUNCATE
395 return ftruncate (s
->fd
, length
);
396 #elif defined HAVE_CHSIZE
397 return chsize (s
->fd
, length
);
399 runtime_error ("required ftruncate or chsize support not present");
405 raw_close (unix_stream
* s
)
409 if (s
->fd
!= STDOUT_FILENO
410 && s
->fd
!= STDERR_FILENO
411 && s
->fd
!= STDIN_FILENO
)
412 retval
= close (s
->fd
);
419 static const struct stream_vtable raw_vtable
= {
420 .read
= (void *) raw_read
,
421 .write
= (void *) raw_write
,
422 .seek
= (void *) raw_seek
,
423 .tell
= (void *) raw_tell
,
424 .size
= (void *) raw_size
,
425 .trunc
= (void *) raw_truncate
,
426 .close
= (void *) raw_close
,
427 .flush
= (void *) raw_flush
431 raw_init (unix_stream
* s
)
433 s
->st
.vptr
= &raw_vtable
;
440 /*********************************************************************
441 Buffered I/O functions. These functions have the same semantics as the
442 raw I/O functions above, except that they are buffered in order to
443 improve performance. The buffer must be flushed when switching from
444 reading to writing and vice versa. Only supported for regular files.
445 *********************************************************************/
448 buf_flush (unix_stream
* s
)
452 /* Flushing in read mode means discarding read bytes. */
458 if (s
->physical_offset
!= s
->buffer_offset
459 && lseek (s
->fd
, s
->buffer_offset
, SEEK_SET
) < 0)
462 writelen
= raw_write (s
, s
->buffer
, s
->ndirty
);
464 s
->physical_offset
= s
->buffer_offset
+ writelen
;
466 if (s
->physical_offset
> s
->file_length
)
467 s
->file_length
= s
->physical_offset
;
469 s
->ndirty
-= writelen
;
477 buf_read (unix_stream
* s
, void * buf
, ssize_t nbyte
)
480 s
->buffer_offset
= s
->logical_offset
;
482 /* Is the data we want in the buffer? */
483 if (s
->logical_offset
+ nbyte
<= s
->buffer_offset
+ s
->active
484 && s
->buffer_offset
<= s
->logical_offset
)
485 memcpy (buf
, s
->buffer
+ (s
->logical_offset
- s
->buffer_offset
), nbyte
);
488 /* First copy the active bytes if applicable, then read the rest
489 either directly or filling the buffer. */
492 ssize_t to_read
, did_read
;
493 gfc_offset new_logical
;
496 if (s
->logical_offset
>= s
->buffer_offset
497 && s
->buffer_offset
+ s
->active
>= s
->logical_offset
)
499 nread
= s
->active
- (s
->logical_offset
- s
->buffer_offset
);
500 memcpy (buf
, s
->buffer
+ (s
->logical_offset
- s
->buffer_offset
),
504 /* At this point we consider all bytes in the buffer discarded. */
505 to_read
= nbyte
- nread
;
506 new_logical
= s
->logical_offset
+ nread
;
507 if (s
->physical_offset
!= new_logical
508 && lseek (s
->fd
, new_logical
, SEEK_SET
) < 0)
510 s
->buffer_offset
= s
->physical_offset
= new_logical
;
511 if (to_read
<= BUFFER_SIZE
/2)
513 did_read
= raw_read (s
, s
->buffer
, BUFFER_SIZE
);
514 s
->physical_offset
+= did_read
;
515 s
->active
= did_read
;
516 did_read
= (did_read
> to_read
) ? to_read
: did_read
;
517 memcpy (p
, s
->buffer
, did_read
);
521 did_read
= raw_read (s
, p
, to_read
);
522 s
->physical_offset
+= did_read
;
525 nbyte
= did_read
+ nread
;
527 s
->logical_offset
+= nbyte
;
532 buf_write (unix_stream
* s
, const void * buf
, ssize_t nbyte
)
535 s
->buffer_offset
= s
->logical_offset
;
537 /* Does the data fit into the buffer? As a special case, if the
538 buffer is empty and the request is bigger than BUFFER_SIZE/2,
539 write directly. This avoids the case where the buffer would have
540 to be flushed at every write. */
541 if (!(s
->ndirty
== 0 && nbyte
> BUFFER_SIZE
/2)
542 && s
->logical_offset
+ nbyte
<= s
->buffer_offset
+ BUFFER_SIZE
543 && s
->buffer_offset
<= s
->logical_offset
544 && s
->buffer_offset
+ s
->ndirty
>= s
->logical_offset
)
546 memcpy (s
->buffer
+ (s
->logical_offset
- s
->buffer_offset
), buf
, nbyte
);
547 int nd
= (s
->logical_offset
- s
->buffer_offset
) + nbyte
;
553 /* Flush, and either fill the buffer with the new data, or if
554 the request is bigger than the buffer size, write directly
555 bypassing the buffer. */
557 if (nbyte
<= BUFFER_SIZE
/2)
559 memcpy (s
->buffer
, buf
, nbyte
);
560 s
->buffer_offset
= s
->logical_offset
;
565 if (s
->physical_offset
!= s
->logical_offset
)
567 if (lseek (s
->fd
, s
->logical_offset
, SEEK_SET
) < 0)
569 s
->physical_offset
= s
->logical_offset
;
572 nbyte
= raw_write (s
, buf
, nbyte
);
573 s
->physical_offset
+= nbyte
;
576 s
->logical_offset
+= nbyte
;
577 if (s
->logical_offset
> s
->file_length
)
578 s
->file_length
= s
->logical_offset
;
583 buf_seek (unix_stream
* s
, gfc_offset offset
, int whence
)
590 offset
+= s
->logical_offset
;
593 offset
+= s
->file_length
;
603 s
->logical_offset
= offset
;
608 buf_tell (unix_stream
* s
)
610 return buf_seek (s
, 0, SEEK_CUR
);
614 buf_size (unix_stream
* s
)
616 return s
->file_length
;
620 buf_truncate (unix_stream
* s
, gfc_offset length
)
624 if (buf_flush (s
) != 0)
626 r
= raw_truncate (s
, length
);
628 s
->file_length
= length
;
633 buf_close (unix_stream
* s
)
635 if (buf_flush (s
) != 0)
638 return raw_close (s
);
641 static const struct stream_vtable buf_vtable
= {
642 .read
= (void *) buf_read
,
643 .write
= (void *) buf_write
,
644 .seek
= (void *) buf_seek
,
645 .tell
= (void *) buf_tell
,
646 .size
= (void *) buf_size
,
647 .trunc
= (void *) buf_truncate
,
648 .close
= (void *) buf_close
,
649 .flush
= (void *) buf_flush
653 buf_init (unix_stream
* s
)
655 s
->st
.vptr
= &buf_vtable
;
657 s
->buffer
= xmalloc (BUFFER_SIZE
);
662 /*********************************************************************
663 memory stream functions - These are used for internal files
665 The idea here is that a single stream structure is created and all
666 requests must be satisfied from it. The location and size of the
667 buffer is the character variable supplied to the READ or WRITE
670 *********************************************************************/
673 mem_alloc_r (stream
* strm
, int * len
)
675 unix_stream
* s
= (unix_stream
*) strm
;
677 gfc_offset where
= s
->logical_offset
;
679 if (where
< s
->buffer_offset
|| where
> s
->buffer_offset
+ s
->active
)
682 n
= s
->buffer_offset
+ s
->active
- where
;
686 s
->logical_offset
= where
+ *len
;
688 return s
->buffer
+ (where
- s
->buffer_offset
);
693 mem_alloc_r4 (stream
* strm
, int * len
)
695 unix_stream
* s
= (unix_stream
*) strm
;
697 gfc_offset where
= s
->logical_offset
;
699 if (where
< s
->buffer_offset
|| where
> s
->buffer_offset
+ s
->active
)
702 n
= s
->buffer_offset
+ s
->active
- where
;
706 s
->logical_offset
= where
+ *len
;
708 return s
->buffer
+ (where
- s
->buffer_offset
) * 4;
713 mem_alloc_w (stream
* strm
, int * len
)
715 unix_stream
* s
= (unix_stream
*) strm
;
717 gfc_offset where
= s
->logical_offset
;
721 if (where
< s
->buffer_offset
)
724 if (m
> s
->file_length
)
727 s
->logical_offset
= m
;
729 return s
->buffer
+ (where
- s
->buffer_offset
);
734 mem_alloc_w4 (stream
* strm
, int * len
)
736 unix_stream
* s
= (unix_stream
*) strm
;
738 gfc_offset where
= s
->logical_offset
;
739 gfc_char4_t
*result
= (gfc_char4_t
*) s
->buffer
;
743 if (where
< s
->buffer_offset
)
746 if (m
> s
->file_length
)
749 s
->logical_offset
= m
;
750 return &result
[where
- s
->buffer_offset
];
754 /* Stream read function for character(kind=1) internal units. */
757 mem_read (stream
* s
, void * buf
, ssize_t nbytes
)
762 p
= mem_alloc_r (s
, &nb
);
773 /* Stream read function for chracter(kind=4) internal units. */
776 mem_read4 (stream
* s
, void * buf
, ssize_t nbytes
)
781 p
= mem_alloc_r (s
, &nb
);
792 /* Stream write function for character(kind=1) internal units. */
795 mem_write (stream
* s
, const void * buf
, ssize_t nbytes
)
800 p
= mem_alloc_w (s
, &nb
);
811 /* Stream write function for character(kind=4) internal units. */
814 mem_write4 (stream
* s
, const void * buf
, ssize_t nwords
)
819 p
= mem_alloc_w4 (s
, &nw
);
823 *p
++ = (gfc_char4_t
) *((char *) buf
);
832 mem_seek (stream
* strm
, gfc_offset offset
, int whence
)
834 unix_stream
* s
= (unix_stream
*) strm
;
840 offset
+= s
->logical_offset
;
843 offset
+= s
->file_length
;
849 /* Note that for internal array I/O it's actually possible to have a
850 negative offset, so don't check for that. */
851 if (offset
> s
->file_length
)
857 s
->logical_offset
= offset
;
859 /* Returning < 0 is the error indicator for sseek(), so return 0 if
860 offset is negative. Thus if the return value is 0, the caller
861 has to use stell() to get the real value of logical_offset. */
869 mem_tell (stream
* s
)
871 return ((unix_stream
*)s
)->logical_offset
;
876 mem_truncate (unix_stream
* s
__attribute__ ((unused
)),
877 gfc_offset length
__attribute__ ((unused
)))
884 mem_flush (unix_stream
* s
__attribute__ ((unused
)))
891 mem_close (unix_stream
* s
)
898 static const struct stream_vtable mem_vtable
= {
899 .read
= (void *) mem_read
,
900 .write
= (void *) mem_write
,
901 .seek
= (void *) mem_seek
,
902 .tell
= (void *) mem_tell
,
903 /* buf_size is not a typo, we just reuse an identical
905 .size
= (void *) buf_size
,
906 .trunc
= (void *) mem_truncate
,
907 .close
= (void *) mem_close
,
908 .flush
= (void *) mem_flush
911 static const struct stream_vtable mem4_vtable
= {
912 .read
= (void *) mem_read4
,
913 .write
= (void *) mem_write4
,
914 .seek
= (void *) mem_seek
,
915 .tell
= (void *) mem_tell
,
916 /* buf_size is not a typo, we just reuse an identical
918 .size
= (void *) buf_size
,
919 .trunc
= (void *) mem_truncate
,
920 .close
= (void *) mem_close
,
921 .flush
= (void *) mem_flush
924 /*********************************************************************
925 Public functions -- A reimplementation of this module needs to
926 define functional equivalents of the following.
927 *********************************************************************/
929 /* open_internal()-- Returns a stream structure from a character(kind=1)
933 open_internal (char *base
, int length
, gfc_offset offset
)
937 s
= xcalloc (1, sizeof (unix_stream
));
940 s
->buffer_offset
= offset
;
942 s
->active
= s
->file_length
= length
;
944 s
->st
.vptr
= &mem_vtable
;
949 /* open_internal4()-- Returns a stream structure from a character(kind=4)
953 open_internal4 (char *base
, int length
, gfc_offset offset
)
957 s
= xcalloc (1, sizeof (unix_stream
));
960 s
->buffer_offset
= offset
;
962 s
->active
= s
->file_length
= length
* sizeof (gfc_char4_t
);
964 s
->st
.vptr
= &mem4_vtable
;
970 /* fd_to_stream()-- Given an open file descriptor, build a stream
974 fd_to_stream (int fd
)
979 s
= xcalloc (1, sizeof (unix_stream
));
983 /* Get the current length of the file. */
985 fstat (fd
, &statbuf
);
987 s
->st_dev
= statbuf
.st_dev
;
988 s
->st_ino
= statbuf
.st_ino
;
989 s
->file_length
= statbuf
.st_size
;
991 /* Only use buffered IO for regular files. */
992 if (S_ISREG (statbuf
.st_mode
)
993 && !options
.all_unbuffered
994 && !(options
.unbuffered_preconnected
&&
995 (s
->fd
== STDIN_FILENO
996 || s
->fd
== STDOUT_FILENO
997 || s
->fd
== STDERR_FILENO
)))
1002 return (stream
*) s
;
1006 /* Given the Fortran unit number, convert it to a C file descriptor. */
1009 unit_to_fd (int unit
)
1014 us
= find_unit (unit
);
1018 fd
= ((unix_stream
*) us
->s
)->fd
;
1024 /* unpack_filename()-- Given a fortran string and a pointer to a
1025 * buffer that is PATH_MAX characters, convert the fortran string to a
1026 * C string in the buffer. Returns nonzero if this is not possible. */
1029 unpack_filename (char *cstring
, const char *fstring
, int len
)
1031 if (fstring
== NULL
)
1033 len
= fstrlen (fstring
, len
);
1034 if (len
>= PATH_MAX
)
1035 return ENAMETOOLONG
;
1037 memmove (cstring
, fstring
, len
);
1038 cstring
[len
] = '\0';
1044 /* Helper function for tempfile(). Tries to open a temporary file in
1045 the directory specified by tempdir. If successful, the file name is
1046 stored in fname and the descriptor returned. Returns -1 on
1050 tempfile_open (const char *tempdir
, char **fname
)
1053 const char *slash
= "/";
1054 #if defined(HAVE_UMASK) && defined(HAVE_MKSTEMP)
1061 /* Check for the special case that tempdir ends with a slash or
1063 size_t tempdirlen
= strlen (tempdir
);
1064 if (*tempdir
== 0 || tempdir
[tempdirlen
- 1] == '/'
1066 || tempdir
[tempdirlen
- 1] == '\\'
1071 // Take care that the template is longer in the mktemp() branch.
1072 char * template = xmalloc (tempdirlen
+ 23);
1075 snprintf (template, tempdirlen
+ 23, "%s%sgfortrantmpXXXXXX",
1079 /* Temporarily set the umask such that the file has 0600 permissions. */
1080 mode_mask
= umask (S_IXUSR
| S_IRWXG
| S_IRWXO
);
1083 fd
= mkstemp (template);
1086 (void) umask (mode_mask
);
1089 #else /* HAVE_MKSTEMP */
1092 size_t slashlen
= strlen (slash
);
1095 snprintf (template, tempdirlen
+ 23, "%s%sgfortrantmpaaaXXXXXX",
1100 template[tempdirlen
+ slashlen
+ 13] = 'a' + (c
% 26);
1102 template[tempdirlen
+ slashlen
+ 12] = 'a' + (c
% 26);
1104 template[tempdirlen
+ slashlen
+ 11] = 'a' + (c
% 26);
1109 if (!mktemp (template))
1116 #if defined(HAVE_CRLF) && defined(O_BINARY)
1117 fd
= open (template, O_RDWR
| O_CREAT
| O_EXCL
| O_BINARY
,
1120 fd
= open (template, O_RDWR
| O_CREAT
| O_EXCL
, S_IRUSR
| S_IWUSR
);
1123 while (fd
== -1 && errno
== EEXIST
);
1124 #endif /* HAVE_MKSTEMP */
1131 /* tempfile()-- Generate a temporary filename for a scratch file and
1132 * open it. mkstemp() opens the file for reading and writing, but the
1133 * library mode prevents anything that is not allowed. The descriptor
1134 * is returned, which is -1 on error. The template is pointed to by
1135 * opp->file, which is copied into the unit structure
1136 * and freed later. */
1139 tempfile (st_parameter_open
*opp
)
1141 const char *tempdir
;
1145 tempdir
= secure_getenv ("TMPDIR");
1146 fd
= tempfile_open (tempdir
, &fname
);
1150 char buffer
[MAX_PATH
+ 1];
1152 ret
= GetTempPath (MAX_PATH
, buffer
);
1153 /* If we are not able to get a temp-directory, we use
1154 current directory. */
1155 if (ret
> MAX_PATH
|| !ret
)
1159 tempdir
= strdup (buffer
);
1160 fd
= tempfile_open (tempdir
, &fname
);
1162 #elif defined(__CYGWIN__)
1165 tempdir
= secure_getenv ("TMP");
1166 fd
= tempfile_open (tempdir
, &fname
);
1170 tempdir
= secure_getenv ("TEMP");
1171 fd
= tempfile_open (tempdir
, &fname
);
1175 fd
= tempfile_open (P_tmpdir
, &fname
);
1178 opp
->file_len
= strlen (fname
); /* Don't include trailing nul */
1184 /* regular_file()-- Open a regular file.
1185 * Change flags->action if it is ACTION_UNSPECIFIED on entry,
1186 * unless an error occurs.
1187 * Returns the descriptor, which is less than zero on error. */
1190 regular_file (st_parameter_open
*opp
, unit_flags
*flags
)
1192 char path
[min(PATH_MAX
, opp
->file_len
+ 1)];
1199 err
= unpack_filename (path
, opp
->file
, opp
->file_len
);
1202 errno
= err
; /* Fake an OS error */
1207 if (opp
->file_len
== 7)
1209 if (strncmp (path
, "CONOUT$", 7) == 0
1210 || strncmp (path
, "CONERR$", 7) == 0)
1212 fd
= open ("/dev/conout", O_WRONLY
);
1213 flags
->action
= ACTION_WRITE
;
1218 if (opp
->file_len
== 6 && strncmp (path
, "CONIN$", 6) == 0)
1220 fd
= open ("/dev/conin", O_RDONLY
);
1221 flags
->action
= ACTION_READ
;
1228 if (opp
->file_len
== 7)
1230 if (strncmp (path
, "CONOUT$", 7) == 0
1231 || strncmp (path
, "CONERR$", 7) == 0)
1233 fd
= open ("CONOUT$", O_WRONLY
);
1234 flags
->action
= ACTION_WRITE
;
1239 if (opp
->file_len
== 6 && strncmp (path
, "CONIN$", 6) == 0)
1241 fd
= open ("CONIN$", O_RDONLY
);
1242 flags
->action
= ACTION_READ
;
1249 switch (flags
->action
)
1259 case ACTION_READWRITE
:
1260 case ACTION_UNSPECIFIED
:
1265 internal_error (&opp
->common
, "regular_file(): Bad action");
1268 switch (flags
->status
)
1271 crflag
= O_CREAT
| O_EXCL
;
1274 case STATUS_OLD
: /* open will fail if the file does not exist*/
1278 case STATUS_UNKNOWN
:
1279 case STATUS_SCRATCH
:
1283 case STATUS_REPLACE
:
1284 crflag
= O_CREAT
| O_TRUNC
;
1288 internal_error (&opp
->common
, "regular_file(): Bad status");
1291 /* rwflag |= O_LARGEFILE; */
1293 #if defined(HAVE_CRLF) && defined(O_BINARY)
1297 mode
= S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IWGRP
| S_IROTH
| S_IWOTH
;
1298 fd
= open (path
, rwflag
| crflag
, mode
);
1299 if (flags
->action
!= ACTION_UNSPECIFIED
)
1304 flags
->action
= ACTION_READWRITE
;
1307 if (errno
!= EACCES
&& errno
!= EROFS
)
1310 /* retry for read-only access */
1312 fd
= open (path
, rwflag
| crflag
, mode
);
1315 flags
->action
= ACTION_READ
;
1316 return fd
; /* success */
1319 if (errno
!= EACCES
)
1320 return fd
; /* failure */
1322 /* retry for write-only access */
1324 fd
= open (path
, rwflag
| crflag
, mode
);
1327 flags
->action
= ACTION_WRITE
;
1328 return fd
; /* success */
1330 return fd
; /* failure */
1334 /* open_external()-- Open an external file, unix specific version.
1335 * Change flags->action if it is ACTION_UNSPECIFIED on entry.
1336 * Returns NULL on operating system error. */
1339 open_external (st_parameter_open
*opp
, unit_flags
*flags
)
1343 if (flags
->status
== STATUS_SCRATCH
)
1345 fd
= tempfile (opp
);
1346 if (flags
->action
== ACTION_UNSPECIFIED
)
1347 flags
->action
= ACTION_READWRITE
;
1349 #if HAVE_UNLINK_OPEN_FILE
1350 /* We can unlink scratch files now and it will go away when closed. */
1357 /* regular_file resets flags->action if it is ACTION_UNSPECIFIED and
1359 fd
= regular_file (opp
, flags
);
1366 return fd_to_stream (fd
);
1370 /* input_stream()-- Return a stream pointer to the default input stream.
1371 * Called on initialization. */
1376 return fd_to_stream (STDIN_FILENO
);
1380 /* output_stream()-- Return a stream pointer to the default output stream.
1381 * Called on initialization. */
1384 output_stream (void)
1388 #if defined(HAVE_CRLF) && defined(HAVE_SETMODE)
1389 setmode (STDOUT_FILENO
, O_BINARY
);
1392 s
= fd_to_stream (STDOUT_FILENO
);
1397 /* error_stream()-- Return a stream pointer to the default error stream.
1398 * Called on initialization. */
1405 #if defined(HAVE_CRLF) && defined(HAVE_SETMODE)
1406 setmode (STDERR_FILENO
, O_BINARY
);
1409 s
= fd_to_stream (STDERR_FILENO
);
1414 /* compare_file_filename()-- Given an open stream and a fortran string
1415 * that is a filename, figure out if the file is the same as the
1419 compare_file_filename (gfc_unit
*u
, const char *name
, int len
)
1421 char path
[min(PATH_MAX
, len
+ 1)];
1423 #ifdef HAVE_WORKING_STAT
1431 if (unpack_filename (path
, name
, len
))
1432 return 0; /* Can't be the same */
1434 /* If the filename doesn't exist, then there is no match with the
1437 if (stat (path
, &st
) < 0)
1440 #ifdef HAVE_WORKING_STAT
1441 s
= (unix_stream
*) (u
->s
);
1442 return (st
.st_dev
== s
->st_dev
) && (st
.st_ino
== s
->st_ino
);
1446 /* We try to match files by a unique ID. On some filesystems (network
1447 fs and FAT), we can't generate this unique ID, and will simply compare
1449 id1
= id_from_path (path
);
1450 id2
= id_from_fd (((unix_stream
*) (u
->s
))->fd
);
1452 return (id1
== id2
);
1455 if (len
!= u
->file_len
)
1457 return (memcmp(path
, u
->file
, len
) == 0);
1462 #ifdef HAVE_WORKING_STAT
1463 # define FIND_FILE0_DECL struct stat *st
1464 # define FIND_FILE0_ARGS st
1466 # define FIND_FILE0_DECL uint64_t id, const char *file, gfc_charlen_type file_len
1467 # define FIND_FILE0_ARGS id, file, file_len
1470 /* find_file0()-- Recursive work function for find_file() */
1473 find_file0 (gfc_unit
*u
, FIND_FILE0_DECL
)
1476 #if defined(__MINGW32__) && !HAVE_WORKING_STAT
1483 #ifdef HAVE_WORKING_STAT
1486 unix_stream
*s
= (unix_stream
*) (u
->s
);
1487 if (st
[0].st_dev
== s
->st_dev
&& st
[0].st_ino
== s
->st_ino
)
1492 if (u
->s
&& ((id1
= id_from_fd (((unix_stream
*) u
->s
)->fd
)) || id1
))
1499 if (compare_string (u
->file_len
, u
->file
, file_len
, file
) == 0)
1503 v
= find_file0 (u
->left
, FIND_FILE0_ARGS
);
1507 v
= find_file0 (u
->right
, FIND_FILE0_ARGS
);
1515 /* find_file()-- Take the current filename and see if there is a unit
1516 * that has the file already open. Returns a pointer to the unit if so. */
1519 find_file (const char *file
, gfc_charlen_type file_len
)
1521 char path
[min(PATH_MAX
, file_len
+ 1)];
1524 #if defined(__MINGW32__) && !HAVE_WORKING_STAT
1528 if (unpack_filename (path
, file
, file_len
))
1531 if (stat (path
, &st
[0]) < 0)
1534 #if defined(__MINGW32__) && !HAVE_WORKING_STAT
1535 id
= id_from_path (path
);
1538 __gthread_mutex_lock (&unit_lock
);
1540 u
= find_file0 (unit_root
, FIND_FILE0_ARGS
);
1544 if (! __gthread_mutex_trylock (&u
->lock
))
1546 /* assert (u->closed == 0); */
1547 __gthread_mutex_unlock (&unit_lock
);
1551 inc_waiting_locked (u
);
1553 __gthread_mutex_unlock (&unit_lock
);
1556 __gthread_mutex_lock (&u
->lock
);
1559 __gthread_mutex_lock (&unit_lock
);
1560 __gthread_mutex_unlock (&u
->lock
);
1561 if (predec_waiting_locked (u
) == 0)
1566 dec_waiting_unlocked (u
);
1572 flush_all_units_1 (gfc_unit
*u
, int min_unit
)
1576 if (u
->unit_number
> min_unit
)
1578 gfc_unit
*r
= flush_all_units_1 (u
->left
, min_unit
);
1582 if (u
->unit_number
>= min_unit
)
1584 if (__gthread_mutex_trylock (&u
->lock
))
1588 __gthread_mutex_unlock (&u
->lock
);
1596 flush_all_units (void)
1601 __gthread_mutex_lock (&unit_lock
);
1604 u
= flush_all_units_1 (unit_root
, min_unit
);
1606 inc_waiting_locked (u
);
1607 __gthread_mutex_unlock (&unit_lock
);
1611 __gthread_mutex_lock (&u
->lock
);
1613 min_unit
= u
->unit_number
+ 1;
1618 __gthread_mutex_lock (&unit_lock
);
1619 __gthread_mutex_unlock (&u
->lock
);
1620 (void) predec_waiting_locked (u
);
1624 __gthread_mutex_lock (&unit_lock
);
1625 __gthread_mutex_unlock (&u
->lock
);
1626 if (predec_waiting_locked (u
) == 0)
1634 /* delete_file()-- Given a unit structure, delete the file associated
1635 * with the unit. Returns nonzero if something went wrong. */
1638 delete_file (gfc_unit
* u
)
1640 char path
[min(PATH_MAX
, u
->file_len
+ 1)];
1641 int err
= unpack_filename (path
, u
->file
, u
->file_len
);
1644 { /* Shouldn't be possible */
1649 return unlink (path
);
1653 /* file_exists()-- Returns nonzero if the current filename exists on
1657 file_exists (const char *file
, gfc_charlen_type file_len
)
1659 char path
[min(PATH_MAX
, file_len
+ 1)];
1661 if (unpack_filename (path
, file
, file_len
))
1664 return !(access (path
, F_OK
));
1668 /* file_size()-- Returns the size of the file. */
1671 file_size (const char *file
, gfc_charlen_type file_len
)
1673 char path
[min(PATH_MAX
, file_len
+ 1)];
1674 struct stat statbuf
;
1676 if (unpack_filename (path
, file
, file_len
))
1679 if (stat (path
, &statbuf
) < 0)
1682 return (GFC_IO_INT
) statbuf
.st_size
;
1685 static const char yes
[] = "YES", no
[] = "NO", unknown
[] = "UNKNOWN";
1687 /* inquire_sequential()-- Given a fortran string, determine if the
1688 * file is suitable for sequential access. Returns a C-style
1692 inquire_sequential (const char *string
, int len
)
1694 char path
[min(PATH_MAX
, len
+ 1)];
1695 struct stat statbuf
;
1697 if (string
== NULL
||
1698 unpack_filename (path
, string
, len
) || stat (path
, &statbuf
) < 0)
1701 if (S_ISREG (statbuf
.st_mode
) ||
1702 S_ISCHR (statbuf
.st_mode
) || S_ISFIFO (statbuf
.st_mode
))
1705 if (S_ISDIR (statbuf
.st_mode
) || S_ISBLK (statbuf
.st_mode
))
1712 /* inquire_direct()-- Given a fortran string, determine if the file is
1713 * suitable for direct access. Returns a C-style string. */
1716 inquire_direct (const char *string
, int len
)
1718 char path
[min(PATH_MAX
, len
+ 1)];
1719 struct stat statbuf
;
1721 if (string
== NULL
||
1722 unpack_filename (path
, string
, len
) || stat (path
, &statbuf
) < 0)
1725 if (S_ISREG (statbuf
.st_mode
) || S_ISBLK (statbuf
.st_mode
))
1728 if (S_ISDIR (statbuf
.st_mode
) ||
1729 S_ISCHR (statbuf
.st_mode
) || S_ISFIFO (statbuf
.st_mode
))
1736 /* inquire_formatted()-- Given a fortran string, determine if the file
1737 * is suitable for formatted form. Returns a C-style string. */
1740 inquire_formatted (const char *string
, int len
)
1742 char path
[min(PATH_MAX
, len
+ 1)];
1743 struct stat statbuf
;
1745 if (string
== NULL
||
1746 unpack_filename (path
, string
, len
) || stat (path
, &statbuf
) < 0)
1749 if (S_ISREG (statbuf
.st_mode
) ||
1750 S_ISBLK (statbuf
.st_mode
) ||
1751 S_ISCHR (statbuf
.st_mode
) || S_ISFIFO (statbuf
.st_mode
))
1754 if (S_ISDIR (statbuf
.st_mode
))
1761 /* inquire_unformatted()-- Given a fortran string, determine if the file
1762 * is suitable for unformatted form. Returns a C-style string. */
1765 inquire_unformatted (const char *string
, int len
)
1767 return inquire_formatted (string
, len
);
1771 /* inquire_access()-- Given a fortran string, determine if the file is
1772 * suitable for access. */
1775 inquire_access (const char *string
, int len
, int mode
)
1777 char path
[min(PATH_MAX
, len
+ 1)];
1779 if (string
== NULL
|| unpack_filename (path
, string
, len
) ||
1780 access (path
, mode
) < 0)
1787 /* inquire_read()-- Given a fortran string, determine if the file is
1788 * suitable for READ access. */
1791 inquire_read (const char *string
, int len
)
1793 return inquire_access (string
, len
, R_OK
);
1797 /* inquire_write()-- Given a fortran string, determine if the file is
1798 * suitable for READ access. */
1801 inquire_write (const char *string
, int len
)
1803 return inquire_access (string
, len
, W_OK
);
1807 /* inquire_readwrite()-- Given a fortran string, determine if the file is
1808 * suitable for read and write access. */
1811 inquire_readwrite (const char *string
, int len
)
1813 return inquire_access (string
, len
, R_OK
| W_OK
);
1818 stream_isatty (stream
*s
)
1820 return isatty (((unix_stream
*) s
)->fd
);
1824 stream_ttyname (stream
*s
__attribute__ ((unused
)),
1825 char * buf
__attribute__ ((unused
)),
1826 size_t buflen
__attribute__ ((unused
)))
1828 #ifdef HAVE_TTYNAME_R
1829 return ttyname_r (((unix_stream
*) s
)->fd
, buf
, buflen
);
1830 #elif defined HAVE_TTYNAME
1833 p
= ttyname (((unix_stream
*) s
)->fd
);
1839 memcpy (buf
, p
, plen
);
1849 /* How files are stored: This is an operating-system specific issue,
1850 and therefore belongs here. There are three cases to consider.
1853 Records are written as block of bytes corresponding to the record
1854 length of the file. This goes for both formatted and unformatted
1855 records. Positioning is done explicitly for each data transfer,
1856 so positioning is not much of an issue.
1858 Sequential Formatted:
1859 Records are separated by newline characters. The newline character
1860 is prohibited from appearing in a string. If it does, this will be
1861 messed up on the next read. End of file is also the end of a record.
1863 Sequential Unformatted:
1864 In this case, we are merely copying bytes to and from main storage,
1865 yet we need to keep track of varying record lengths. We adopt
1866 the solution used by f2c. Each record contains a pair of length
1869 Length of record n in bytes
1871 Length of record n in bytes
1873 Length of record n+1 in bytes
1875 Length of record n+1 in bytes
1877 The length is stored at the end of a record to allow backspacing to the
1878 previous record. Between data transfer statements, the file pointer
1879 is left pointing to the first length of the current record.
1881 ENDFILE records are never explicitly stored.