1 /* Copyright (C) 2002-2013 Free Software Foundation, Inc.
2 Contributed by Andy Vaught
3 F2003 I/O support contributed by Jerry DeLisle
5 This file is part of the GNU Fortran 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 3, or (at your option)
12 Libgfortran is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 Under Section 7 of GPL version 3, you are granted additional
18 permissions described in the GCC Runtime Library Exception, version
19 3.1, as published by the Free Software Foundation.
21 You should have received a copy of the GNU General Public License and
22 a copy of the GCC Runtime Library Exception along with this program;
23 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24 <http://www.gnu.org/licenses/>. */
26 /* Unix stream I/O module */
42 /* For mingw, we don't identify files by their inode number, but by a
43 64-bit identifier created from a BY_HANDLE_FILE_INFORMATION. */
46 #define WIN32_LEAN_AND_MEAN
49 #if !defined(_FILE_OFFSET_BITS) || _FILE_OFFSET_BITS != 64
51 #define lseek _lseeki64
53 #define fstat _fstati64
58 #ifndef HAVE_WORKING_STAT
60 id_from_handle (HANDLE hFile
)
62 BY_HANDLE_FILE_INFORMATION FileInformation
;
64 if (hFile
== INVALID_HANDLE_VALUE
)
67 memset (&FileInformation
, 0, sizeof(FileInformation
));
68 if (!GetFileInformationByHandle (hFile
, &FileInformation
))
71 return ((uint64_t) FileInformation
.nFileIndexLow
)
72 | (((uint64_t) FileInformation
.nFileIndexHigh
) << 32);
77 id_from_path (const char *path
)
82 if (!path
|| !*path
|| access (path
, F_OK
))
85 hFile
= CreateFile (path
, 0, 0, NULL
, OPEN_EXISTING
,
86 FILE_FLAG_BACKUP_SEMANTICS
| FILE_ATTRIBUTE_READONLY
,
88 res
= id_from_handle (hFile
);
95 id_from_fd (const int fd
)
97 return id_from_handle ((HANDLE
) _get_osfhandle (fd
));
100 #endif /* HAVE_WORKING_STAT */
101 #endif /* __MINGW32__ */
104 /* min macro that evaluates its arguments only once. */
110 ({ typeof (a) _a = (a); \
111 typeof (b) _b = (b); \
112 _a < _b ? _a : _b; })
115 #define PATH_MAX 1024
118 /* These flags aren't defined on all targets (mingw32), so provide them
151 /* Fallback implementation of access() on systems that don't have it.
152 Only modes R_OK, W_OK and F_OK are used in this file. */
155 fallback_access (const char *path
, int mode
)
159 if ((mode
& R_OK
) && (fd
= open (path
, O_RDONLY
)) < 0)
163 if ((mode
& W_OK
) && (fd
= open (path
, O_WRONLY
)) < 0)
170 return stat (path
, &st
);
177 #define access fallback_access
181 /* Fallback directory for creating temporary files. P_tmpdir is
182 defined on many POSIX platforms. */
185 #define P_tmpdir _P_tmpdir /* MinGW */
187 #define P_tmpdir "/tmp"
192 /* Unix and internal stream I/O module */
194 static const int BUFFER_SIZE
= 8192;
200 gfc_offset buffer_offset
; /* File offset of the start of the buffer */
201 gfc_offset physical_offset
; /* Current physical file offset */
202 gfc_offset logical_offset
; /* Current logical file offset */
203 gfc_offset file_length
; /* Length of the file. */
205 char *buffer
; /* Pointer to the buffer. */
206 int fd
; /* The POSIX file descriptor. */
208 int active
; /* Length of valid bytes in the buffer */
210 int ndirty
; /* Dirty bytes starting at buffer_offset */
212 /* Cached stat(2) values. */
219 /* fix_fd()-- Given a file descriptor, make sure it is not one of the
220 * standard descriptors, returning a non-standard descriptor. If the
221 * user specifies that system errors should go to standard output,
222 * then closes standard output, we don't want the system errors to a
223 * file that has been given file descriptor 1 or 0. We want to send
224 * the error to the invalid descriptor. */
230 int input
, output
, error
;
232 input
= output
= error
= 0;
234 /* Unix allocates the lowest descriptors first, so a loop is not
235 required, but this order is. */
236 if (fd
== STDIN_FILENO
)
241 if (fd
== STDOUT_FILENO
)
246 if (fd
== STDERR_FILENO
)
253 close (STDIN_FILENO
);
255 close (STDOUT_FILENO
);
257 close (STDERR_FILENO
);
264 /* If the stream corresponds to a preconnected unit, we flush the
265 corresponding C stream. This is bugware for mixed C-Fortran codes
266 where the C code doesn't flush I/O before returning. */
268 flush_if_preconnected (stream
* s
)
272 fd
= ((unix_stream
*) s
)->fd
;
273 if (fd
== STDIN_FILENO
)
275 else if (fd
== STDOUT_FILENO
)
277 else if (fd
== STDERR_FILENO
)
282 /********************************************************************
283 Raw I/O functions (read, write, seek, tell, truncate, close).
285 These functions wrap the basic POSIX I/O syscalls. Any deviation in
286 semantics is a bug, except the following: write restarts in case
287 of being interrupted by a signal, and as the first argument the
288 functions take the unix_stream struct rather than an integer file
289 descriptor. Also, for POSIX read() and write() a nbyte argument larger
290 than SSIZE_MAX is undefined; here the type of nbyte is ssize_t rather
291 than size_t as for POSIX read/write.
292 *********************************************************************/
295 raw_flush (unix_stream
* s
__attribute__ ((unused
)))
301 raw_read (unix_stream
* s
, void * buf
, ssize_t nbyte
)
303 /* For read we can't do I/O in a loop like raw_write does, because
304 that will break applications that wait for interactive I/O. */
305 return read (s
->fd
, buf
, nbyte
);
309 raw_write (unix_stream
* s
, const void * buf
, ssize_t nbyte
)
311 ssize_t trans
, bytes_left
;
315 buf_st
= (char *) buf
;
317 /* We must write in a loop since some systems don't restart system
318 calls in case of a signal. */
319 while (bytes_left
> 0)
321 trans
= write (s
->fd
, buf_st
, bytes_left
);
333 return nbyte
- bytes_left
;
337 raw_seek (unix_stream
* s
, gfc_offset offset
, int whence
)
339 return lseek (s
->fd
, offset
, whence
);
343 raw_tell (unix_stream
* s
)
345 return lseek (s
->fd
, 0, SEEK_CUR
);
349 raw_size (unix_stream
* s
)
352 int ret
= fstat (s
->fd
, &statbuf
);
355 if (S_ISREG (statbuf
.st_mode
))
356 return statbuf
.st_size
;
362 raw_truncate (unix_stream
* s
, gfc_offset length
)
373 h
= (HANDLE
) _get_osfhandle (s
->fd
);
374 if (h
== INVALID_HANDLE_VALUE
)
379 cur
= lseek (s
->fd
, 0, SEEK_CUR
);
382 if (lseek (s
->fd
, length
, SEEK_SET
) == -1)
384 if (!SetEndOfFile (h
))
389 if (lseek (s
->fd
, cur
, SEEK_SET
) == -1)
393 lseek (s
->fd
, cur
, SEEK_SET
);
395 #elif defined HAVE_FTRUNCATE
396 return ftruncate (s
->fd
, length
);
397 #elif defined HAVE_CHSIZE
398 return chsize (s
->fd
, length
);
400 runtime_error ("required ftruncate or chsize support not present");
406 raw_close (unix_stream
* s
)
410 if (s
->fd
!= STDOUT_FILENO
411 && s
->fd
!= STDERR_FILENO
412 && s
->fd
!= STDIN_FILENO
)
413 retval
= close (s
->fd
);
420 static const struct stream_vtable raw_vtable
= {
421 .read
= (void *) raw_read
,
422 .write
= (void *) raw_write
,
423 .seek
= (void *) raw_seek
,
424 .tell
= (void *) raw_tell
,
425 .size
= (void *) raw_size
,
426 .trunc
= (void *) raw_truncate
,
427 .close
= (void *) raw_close
,
428 .flush
= (void *) raw_flush
432 raw_init (unix_stream
* s
)
434 s
->st
.vptr
= &raw_vtable
;
441 /*********************************************************************
442 Buffered I/O functions. These functions have the same semantics as the
443 raw I/O functions above, except that they are buffered in order to
444 improve performance. The buffer must be flushed when switching from
445 reading to writing and vice versa. Only supported for regular files.
446 *********************************************************************/
449 buf_flush (unix_stream
* s
)
453 /* Flushing in read mode means discarding read bytes. */
459 if (s
->physical_offset
!= s
->buffer_offset
460 && lseek (s
->fd
, s
->buffer_offset
, SEEK_SET
) < 0)
463 writelen
= raw_write (s
, s
->buffer
, s
->ndirty
);
465 s
->physical_offset
= s
->buffer_offset
+ writelen
;
467 if (s
->physical_offset
> s
->file_length
)
468 s
->file_length
= s
->physical_offset
;
470 s
->ndirty
-= writelen
;
478 buf_read (unix_stream
* s
, void * buf
, ssize_t nbyte
)
481 s
->buffer_offset
= s
->logical_offset
;
483 /* Is the data we want in the buffer? */
484 if (s
->logical_offset
+ nbyte
<= s
->buffer_offset
+ s
->active
485 && s
->buffer_offset
<= s
->logical_offset
)
486 memcpy (buf
, s
->buffer
+ (s
->logical_offset
- s
->buffer_offset
), nbyte
);
489 /* First copy the active bytes if applicable, then read the rest
490 either directly or filling the buffer. */
493 ssize_t to_read
, did_read
;
494 gfc_offset new_logical
;
497 if (s
->logical_offset
>= s
->buffer_offset
498 && s
->buffer_offset
+ s
->active
>= s
->logical_offset
)
500 nread
= s
->active
- (s
->logical_offset
- s
->buffer_offset
);
501 memcpy (buf
, s
->buffer
+ (s
->logical_offset
- s
->buffer_offset
),
505 /* At this point we consider all bytes in the buffer discarded. */
506 to_read
= nbyte
- nread
;
507 new_logical
= s
->logical_offset
+ nread
;
508 if (s
->physical_offset
!= new_logical
509 && lseek (s
->fd
, new_logical
, SEEK_SET
) < 0)
511 s
->buffer_offset
= s
->physical_offset
= new_logical
;
512 if (to_read
<= BUFFER_SIZE
/2)
514 did_read
= raw_read (s
, s
->buffer
, BUFFER_SIZE
);
515 s
->physical_offset
+= did_read
;
516 s
->active
= did_read
;
517 did_read
= (did_read
> to_read
) ? to_read
: did_read
;
518 memcpy (p
, s
->buffer
, did_read
);
522 did_read
= raw_read (s
, p
, to_read
);
523 s
->physical_offset
+= did_read
;
526 nbyte
= did_read
+ nread
;
528 s
->logical_offset
+= nbyte
;
533 buf_write (unix_stream
* s
, const void * buf
, ssize_t nbyte
)
536 s
->buffer_offset
= s
->logical_offset
;
538 /* Does the data fit into the buffer? As a special case, if the
539 buffer is empty and the request is bigger than BUFFER_SIZE/2,
540 write directly. This avoids the case where the buffer would have
541 to be flushed at every write. */
542 if (!(s
->ndirty
== 0 && nbyte
> BUFFER_SIZE
/2)
543 && s
->logical_offset
+ nbyte
<= s
->buffer_offset
+ BUFFER_SIZE
544 && s
->buffer_offset
<= s
->logical_offset
545 && s
->buffer_offset
+ s
->ndirty
>= s
->logical_offset
)
547 memcpy (s
->buffer
+ (s
->logical_offset
- s
->buffer_offset
), buf
, nbyte
);
548 int nd
= (s
->logical_offset
- s
->buffer_offset
) + nbyte
;
554 /* Flush, and either fill the buffer with the new data, or if
555 the request is bigger than the buffer size, write directly
556 bypassing the buffer. */
558 if (nbyte
<= BUFFER_SIZE
/2)
560 memcpy (s
->buffer
, buf
, nbyte
);
561 s
->buffer_offset
= s
->logical_offset
;
566 if (s
->physical_offset
!= s
->logical_offset
)
568 if (lseek (s
->fd
, s
->logical_offset
, SEEK_SET
) < 0)
570 s
->physical_offset
= s
->logical_offset
;
573 nbyte
= raw_write (s
, buf
, nbyte
);
574 s
->physical_offset
+= nbyte
;
577 s
->logical_offset
+= nbyte
;
578 if (s
->logical_offset
> s
->file_length
)
579 s
->file_length
= s
->logical_offset
;
584 buf_seek (unix_stream
* s
, gfc_offset offset
, int whence
)
591 offset
+= s
->logical_offset
;
594 offset
+= s
->file_length
;
604 s
->logical_offset
= offset
;
609 buf_tell (unix_stream
* s
)
611 return buf_seek (s
, 0, SEEK_CUR
);
615 buf_size (unix_stream
* s
)
617 return s
->file_length
;
621 buf_truncate (unix_stream
* s
, gfc_offset length
)
625 if (buf_flush (s
) != 0)
627 r
= raw_truncate (s
, length
);
629 s
->file_length
= length
;
634 buf_close (unix_stream
* s
)
636 if (buf_flush (s
) != 0)
639 return raw_close (s
);
642 static const struct stream_vtable buf_vtable
= {
643 .read
= (void *) buf_read
,
644 .write
= (void *) buf_write
,
645 .seek
= (void *) buf_seek
,
646 .tell
= (void *) buf_tell
,
647 .size
= (void *) buf_size
,
648 .trunc
= (void *) buf_truncate
,
649 .close
= (void *) buf_close
,
650 .flush
= (void *) buf_flush
654 buf_init (unix_stream
* s
)
656 s
->st
.vptr
= &buf_vtable
;
658 s
->buffer
= xmalloc (BUFFER_SIZE
);
663 /*********************************************************************
664 memory stream functions - These are used for internal files
666 The idea here is that a single stream structure is created and all
667 requests must be satisfied from it. The location and size of the
668 buffer is the character variable supplied to the READ or WRITE
671 *********************************************************************/
674 mem_alloc_r (stream
* strm
, int * len
)
676 unix_stream
* s
= (unix_stream
*) strm
;
678 gfc_offset where
= s
->logical_offset
;
680 if (where
< s
->buffer_offset
|| where
> s
->buffer_offset
+ s
->active
)
683 n
= s
->buffer_offset
+ s
->active
- where
;
687 s
->logical_offset
= where
+ *len
;
689 return s
->buffer
+ (where
- s
->buffer_offset
);
694 mem_alloc_r4 (stream
* strm
, int * len
)
696 unix_stream
* s
= (unix_stream
*) strm
;
698 gfc_offset where
= s
->logical_offset
;
700 if (where
< s
->buffer_offset
|| where
> s
->buffer_offset
+ s
->active
)
703 n
= s
->buffer_offset
+ s
->active
- where
;
707 s
->logical_offset
= where
+ *len
;
709 return s
->buffer
+ (where
- s
->buffer_offset
) * 4;
714 mem_alloc_w (stream
* strm
, int * len
)
716 unix_stream
* s
= (unix_stream
*) strm
;
718 gfc_offset where
= s
->logical_offset
;
722 if (where
< s
->buffer_offset
)
725 if (m
> s
->file_length
)
728 s
->logical_offset
= m
;
730 return s
->buffer
+ (where
- s
->buffer_offset
);
735 mem_alloc_w4 (stream
* strm
, int * len
)
737 unix_stream
* s
= (unix_stream
*) strm
;
739 gfc_offset where
= s
->logical_offset
;
740 gfc_char4_t
*result
= (gfc_char4_t
*) s
->buffer
;
744 if (where
< s
->buffer_offset
)
747 if (m
> s
->file_length
)
750 s
->logical_offset
= m
;
751 return &result
[where
- s
->buffer_offset
];
755 /* Stream read function for character(kind=1) internal units. */
758 mem_read (stream
* s
, void * buf
, ssize_t nbytes
)
763 p
= mem_alloc_r (s
, &nb
);
774 /* Stream read function for chracter(kind=4) internal units. */
777 mem_read4 (stream
* s
, void * buf
, ssize_t nbytes
)
782 p
= mem_alloc_r (s
, &nb
);
793 /* Stream write function for character(kind=1) internal units. */
796 mem_write (stream
* s
, const void * buf
, ssize_t nbytes
)
801 p
= mem_alloc_w (s
, &nb
);
812 /* Stream write function for character(kind=4) internal units. */
815 mem_write4 (stream
* s
, const void * buf
, ssize_t nwords
)
820 p
= mem_alloc_w4 (s
, &nw
);
824 *p
++ = (gfc_char4_t
) *((char *) buf
);
833 mem_seek (stream
* strm
, gfc_offset offset
, int whence
)
835 unix_stream
* s
= (unix_stream
*) strm
;
841 offset
+= s
->logical_offset
;
844 offset
+= s
->file_length
;
850 /* Note that for internal array I/O it's actually possible to have a
851 negative offset, so don't check for that. */
852 if (offset
> s
->file_length
)
858 s
->logical_offset
= offset
;
860 /* Returning < 0 is the error indicator for sseek(), so return 0 if
861 offset is negative. Thus if the return value is 0, the caller
862 has to use stell() to get the real value of logical_offset. */
870 mem_tell (stream
* s
)
872 return ((unix_stream
*)s
)->logical_offset
;
877 mem_truncate (unix_stream
* s
__attribute__ ((unused
)),
878 gfc_offset length
__attribute__ ((unused
)))
885 mem_flush (unix_stream
* s
__attribute__ ((unused
)))
892 mem_close (unix_stream
* s
)
899 static const struct stream_vtable mem_vtable
= {
900 .read
= (void *) mem_read
,
901 .write
= (void *) mem_write
,
902 .seek
= (void *) mem_seek
,
903 .tell
= (void *) mem_tell
,
904 /* buf_size is not a typo, we just reuse an identical
906 .size
= (void *) buf_size
,
907 .trunc
= (void *) mem_truncate
,
908 .close
= (void *) mem_close
,
909 .flush
= (void *) mem_flush
912 static const struct stream_vtable mem4_vtable
= {
913 .read
= (void *) mem_read4
,
914 .write
= (void *) mem_write4
,
915 .seek
= (void *) mem_seek
,
916 .tell
= (void *) mem_tell
,
917 /* buf_size is not a typo, we just reuse an identical
919 .size
= (void *) buf_size
,
920 .trunc
= (void *) mem_truncate
,
921 .close
= (void *) mem_close
,
922 .flush
= (void *) mem_flush
925 /*********************************************************************
926 Public functions -- A reimplementation of this module needs to
927 define functional equivalents of the following.
928 *********************************************************************/
930 /* open_internal()-- Returns a stream structure from a character(kind=1)
934 open_internal (char *base
, int length
, gfc_offset offset
)
938 s
= xcalloc (1, sizeof (unix_stream
));
941 s
->buffer_offset
= offset
;
943 s
->active
= s
->file_length
= length
;
945 s
->st
.vptr
= &mem_vtable
;
950 /* open_internal4()-- Returns a stream structure from a character(kind=4)
954 open_internal4 (char *base
, int length
, gfc_offset offset
)
958 s
= xcalloc (1, sizeof (unix_stream
));
961 s
->buffer_offset
= offset
;
963 s
->active
= s
->file_length
= length
* sizeof (gfc_char4_t
);
965 s
->st
.vptr
= &mem4_vtable
;
971 /* fd_to_stream()-- Given an open file descriptor, build a stream
975 fd_to_stream (int fd
)
980 s
= xcalloc (1, sizeof (unix_stream
));
984 /* Get the current length of the file. */
986 fstat (fd
, &statbuf
);
988 s
->st_dev
= statbuf
.st_dev
;
989 s
->st_ino
= statbuf
.st_ino
;
990 s
->file_length
= statbuf
.st_size
;
992 /* Only use buffered IO for regular files. */
993 if (S_ISREG (statbuf
.st_mode
)
994 && !options
.all_unbuffered
995 && !(options
.unbuffered_preconnected
&&
996 (s
->fd
== STDIN_FILENO
997 || s
->fd
== STDOUT_FILENO
998 || s
->fd
== STDERR_FILENO
)))
1003 return (stream
*) s
;
1007 /* Given the Fortran unit number, convert it to a C file descriptor. */
1010 unit_to_fd (int unit
)
1015 us
= find_unit (unit
);
1019 fd
= ((unix_stream
*) us
->s
)->fd
;
1025 /* unpack_filename()-- Given a fortran string and a pointer to a
1026 * buffer that is PATH_MAX characters, convert the fortran string to a
1027 * C string in the buffer. Returns nonzero if this is not possible. */
1030 unpack_filename (char *cstring
, const char *fstring
, int len
)
1032 if (fstring
== NULL
)
1034 len
= fstrlen (fstring
, len
);
1035 if (len
>= PATH_MAX
)
1036 return ENAMETOOLONG
;
1038 memmove (cstring
, fstring
, len
);
1039 cstring
[len
] = '\0';
1045 /* Helper function for tempfile(). Tries to open a temporary file in
1046 the directory specified by tempdir. If successful, the file name is
1047 stored in fname and the descriptor returned. Returns -1 on
1051 tempfile_open (const char *tempdir
, char **fname
)
1054 const char *slash
= "/";
1055 #if defined(HAVE_UMASK) && defined(HAVE_MKSTEMP)
1062 /* Check for the special case that tempdir ends with a slash or
1064 size_t tempdirlen
= strlen (tempdir
);
1065 if (*tempdir
== 0 || tempdir
[tempdirlen
- 1] == '/'
1067 || tempdir
[tempdirlen
- 1] == '\\'
1072 // Take care that the template is longer in the mktemp() branch.
1073 char * template = xmalloc (tempdirlen
+ 23);
1076 snprintf (template, tempdirlen
+ 23, "%s%sgfortrantmpXXXXXX",
1080 /* Temporarily set the umask such that the file has 0600 permissions. */
1081 mode_mask
= umask (S_IXUSR
| S_IRWXG
| S_IRWXO
);
1084 fd
= mkstemp (template);
1087 (void) umask (mode_mask
);
1090 #else /* HAVE_MKSTEMP */
1093 size_t slashlen
= strlen (slash
);
1096 snprintf (template, tempdirlen
+ 23, "%s%sgfortrantmpaaaXXXXXX",
1101 template[tempdirlen
+ slashlen
+ 13] = 'a' + (c
% 26);
1103 template[tempdirlen
+ slashlen
+ 12] = 'a' + (c
% 26);
1105 template[tempdirlen
+ slashlen
+ 11] = 'a' + (c
% 26);
1110 if (!mktemp (template))
1117 #if defined(HAVE_CRLF) && defined(O_BINARY)
1118 fd
= open (template, O_RDWR
| O_CREAT
| O_EXCL
| O_BINARY
,
1121 fd
= open (template, O_RDWR
| O_CREAT
| O_EXCL
, S_IRUSR
| S_IWUSR
);
1124 while (fd
== -1 && errno
== EEXIST
);
1125 #endif /* HAVE_MKSTEMP */
1132 /* tempfile()-- Generate a temporary filename for a scratch file and
1133 * open it. mkstemp() opens the file for reading and writing, but the
1134 * library mode prevents anything that is not allowed. The descriptor
1135 * is returned, which is -1 on error. The template is pointed to by
1136 * opp->file, which is copied into the unit structure
1137 * and freed later. */
1140 tempfile (st_parameter_open
*opp
)
1142 const char *tempdir
;
1146 tempdir
= secure_getenv ("TMPDIR");
1147 fd
= tempfile_open (tempdir
, &fname
);
1151 char buffer
[MAX_PATH
+ 1];
1153 ret
= GetTempPath (MAX_PATH
, buffer
);
1154 /* If we are not able to get a temp-directory, we use
1155 current directory. */
1156 if (ret
> MAX_PATH
|| !ret
)
1160 tempdir
= strdup (buffer
);
1161 fd
= tempfile_open (tempdir
, &fname
);
1163 #elif defined(__CYGWIN__)
1166 tempdir
= secure_getenv ("TMP");
1167 fd
= tempfile_open (tempdir
, &fname
);
1171 tempdir
= secure_getenv ("TEMP");
1172 fd
= tempfile_open (tempdir
, &fname
);
1176 fd
= tempfile_open (P_tmpdir
, &fname
);
1179 opp
->file_len
= strlen (fname
); /* Don't include trailing nul */
1185 /* regular_file()-- Open a regular file.
1186 * Change flags->action if it is ACTION_UNSPECIFIED on entry,
1187 * unless an error occurs.
1188 * Returns the descriptor, which is less than zero on error. */
1191 regular_file (st_parameter_open
*opp
, unit_flags
*flags
)
1193 char path
[min(PATH_MAX
, opp
->file_len
+ 1)];
1200 err
= unpack_filename (path
, opp
->file
, opp
->file_len
);
1203 errno
= err
; /* Fake an OS error */
1208 if (opp
->file_len
== 7)
1210 if (strncmp (path
, "CONOUT$", 7) == 0
1211 || strncmp (path
, "CONERR$", 7) == 0)
1213 fd
= open ("/dev/conout", O_WRONLY
);
1214 flags
->action
= ACTION_WRITE
;
1219 if (opp
->file_len
== 6 && strncmp (path
, "CONIN$", 6) == 0)
1221 fd
= open ("/dev/conin", O_RDONLY
);
1222 flags
->action
= ACTION_READ
;
1229 if (opp
->file_len
== 7)
1231 if (strncmp (path
, "CONOUT$", 7) == 0
1232 || strncmp (path
, "CONERR$", 7) == 0)
1234 fd
= open ("CONOUT$", O_WRONLY
);
1235 flags
->action
= ACTION_WRITE
;
1240 if (opp
->file_len
== 6 && strncmp (path
, "CONIN$", 6) == 0)
1242 fd
= open ("CONIN$", O_RDONLY
);
1243 flags
->action
= ACTION_READ
;
1250 switch (flags
->action
)
1260 case ACTION_READWRITE
:
1261 case ACTION_UNSPECIFIED
:
1266 internal_error (&opp
->common
, "regular_file(): Bad action");
1269 switch (flags
->status
)
1272 crflag
= O_CREAT
| O_EXCL
;
1275 case STATUS_OLD
: /* open will fail if the file does not exist*/
1279 case STATUS_UNKNOWN
:
1280 case STATUS_SCRATCH
:
1284 case STATUS_REPLACE
:
1285 crflag
= O_CREAT
| O_TRUNC
;
1289 internal_error (&opp
->common
, "regular_file(): Bad status");
1292 /* rwflag |= O_LARGEFILE; */
1294 #if defined(HAVE_CRLF) && defined(O_BINARY)
1298 mode
= S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IWGRP
| S_IROTH
| S_IWOTH
;
1299 fd
= open (path
, rwflag
| crflag
, mode
);
1300 if (flags
->action
!= ACTION_UNSPECIFIED
)
1305 flags
->action
= ACTION_READWRITE
;
1308 if (errno
!= EACCES
&& errno
!= EROFS
)
1311 /* retry for read-only access */
1313 fd
= open (path
, rwflag
| crflag
, mode
);
1316 flags
->action
= ACTION_READ
;
1317 return fd
; /* success */
1320 if (errno
!= EACCES
)
1321 return fd
; /* failure */
1323 /* retry for write-only access */
1325 fd
= open (path
, rwflag
| crflag
, mode
);
1328 flags
->action
= ACTION_WRITE
;
1329 return fd
; /* success */
1331 return fd
; /* failure */
1335 /* open_external()-- Open an external file, unix specific version.
1336 * Change flags->action if it is ACTION_UNSPECIFIED on entry.
1337 * Returns NULL on operating system error. */
1340 open_external (st_parameter_open
*opp
, unit_flags
*flags
)
1344 if (flags
->status
== STATUS_SCRATCH
)
1346 fd
= tempfile (opp
);
1347 if (flags
->action
== ACTION_UNSPECIFIED
)
1348 flags
->action
= ACTION_READWRITE
;
1350 #if HAVE_UNLINK_OPEN_FILE
1351 /* We can unlink scratch files now and it will go away when closed. */
1358 /* regular_file resets flags->action if it is ACTION_UNSPECIFIED and
1360 fd
= regular_file (opp
, flags
);
1367 return fd_to_stream (fd
);
1371 /* input_stream()-- Return a stream pointer to the default input stream.
1372 * Called on initialization. */
1377 return fd_to_stream (STDIN_FILENO
);
1381 /* output_stream()-- Return a stream pointer to the default output stream.
1382 * Called on initialization. */
1385 output_stream (void)
1389 #if defined(HAVE_CRLF) && defined(HAVE_SETMODE)
1390 setmode (STDOUT_FILENO
, O_BINARY
);
1393 s
= fd_to_stream (STDOUT_FILENO
);
1398 /* error_stream()-- Return a stream pointer to the default error stream.
1399 * Called on initialization. */
1406 #if defined(HAVE_CRLF) && defined(HAVE_SETMODE)
1407 setmode (STDERR_FILENO
, O_BINARY
);
1410 s
= fd_to_stream (STDERR_FILENO
);
1415 /* compare_file_filename()-- Given an open stream and a fortran string
1416 * that is a filename, figure out if the file is the same as the
1420 compare_file_filename (gfc_unit
*u
, const char *name
, int len
)
1422 char path
[min(PATH_MAX
, len
+ 1)];
1424 #ifdef HAVE_WORKING_STAT
1432 if (unpack_filename (path
, name
, len
))
1433 return 0; /* Can't be the same */
1435 /* If the filename doesn't exist, then there is no match with the
1438 if (stat (path
, &st
) < 0)
1441 #ifdef HAVE_WORKING_STAT
1442 s
= (unix_stream
*) (u
->s
);
1443 return (st
.st_dev
== s
->st_dev
) && (st
.st_ino
== s
->st_ino
);
1447 /* We try to match files by a unique ID. On some filesystems (network
1448 fs and FAT), we can't generate this unique ID, and will simply compare
1450 id1
= id_from_path (path
);
1451 id2
= id_from_fd (((unix_stream
*) (u
->s
))->fd
);
1453 return (id1
== id2
);
1456 if (len
!= u
->file_len
)
1458 return (memcmp(path
, u
->file
, len
) == 0);
1463 #ifdef HAVE_WORKING_STAT
1464 # define FIND_FILE0_DECL struct stat *st
1465 # define FIND_FILE0_ARGS st
1467 # define FIND_FILE0_DECL uint64_t id, const char *file, gfc_charlen_type file_len
1468 # define FIND_FILE0_ARGS id, file, file_len
1471 /* find_file0()-- Recursive work function for find_file() */
1474 find_file0 (gfc_unit
*u
, FIND_FILE0_DECL
)
1477 #if defined(__MINGW32__) && !HAVE_WORKING_STAT
1484 #ifdef HAVE_WORKING_STAT
1487 unix_stream
*s
= (unix_stream
*) (u
->s
);
1488 if (st
[0].st_dev
== s
->st_dev
&& st
[0].st_ino
== s
->st_ino
)
1493 if (u
->s
&& ((id1
= id_from_fd (((unix_stream
*) u
->s
)->fd
)) || id1
))
1500 if (compare_string (u
->file_len
, u
->file
, file_len
, file
) == 0)
1504 v
= find_file0 (u
->left
, FIND_FILE0_ARGS
);
1508 v
= find_file0 (u
->right
, FIND_FILE0_ARGS
);
1516 /* find_file()-- Take the current filename and see if there is a unit
1517 * that has the file already open. Returns a pointer to the unit if so. */
1520 find_file (const char *file
, gfc_charlen_type file_len
)
1522 char path
[min(PATH_MAX
, file_len
+ 1)];
1525 #if defined(__MINGW32__) && !HAVE_WORKING_STAT
1529 if (unpack_filename (path
, file
, file_len
))
1532 if (stat (path
, &st
[0]) < 0)
1535 #if defined(__MINGW32__) && !HAVE_WORKING_STAT
1536 id
= id_from_path (path
);
1539 __gthread_mutex_lock (&unit_lock
);
1541 u
= find_file0 (unit_root
, FIND_FILE0_ARGS
);
1545 if (! __gthread_mutex_trylock (&u
->lock
))
1547 /* assert (u->closed == 0); */
1548 __gthread_mutex_unlock (&unit_lock
);
1552 inc_waiting_locked (u
);
1554 __gthread_mutex_unlock (&unit_lock
);
1557 __gthread_mutex_lock (&u
->lock
);
1560 __gthread_mutex_lock (&unit_lock
);
1561 __gthread_mutex_unlock (&u
->lock
);
1562 if (predec_waiting_locked (u
) == 0)
1567 dec_waiting_unlocked (u
);
1573 flush_all_units_1 (gfc_unit
*u
, int min_unit
)
1577 if (u
->unit_number
> min_unit
)
1579 gfc_unit
*r
= flush_all_units_1 (u
->left
, min_unit
);
1583 if (u
->unit_number
>= min_unit
)
1585 if (__gthread_mutex_trylock (&u
->lock
))
1589 __gthread_mutex_unlock (&u
->lock
);
1597 flush_all_units (void)
1602 __gthread_mutex_lock (&unit_lock
);
1605 u
= flush_all_units_1 (unit_root
, min_unit
);
1607 inc_waiting_locked (u
);
1608 __gthread_mutex_unlock (&unit_lock
);
1612 __gthread_mutex_lock (&u
->lock
);
1614 min_unit
= u
->unit_number
+ 1;
1619 __gthread_mutex_lock (&unit_lock
);
1620 __gthread_mutex_unlock (&u
->lock
);
1621 (void) predec_waiting_locked (u
);
1625 __gthread_mutex_lock (&unit_lock
);
1626 __gthread_mutex_unlock (&u
->lock
);
1627 if (predec_waiting_locked (u
) == 0)
1635 /* delete_file()-- Given a unit structure, delete the file associated
1636 * with the unit. Returns nonzero if something went wrong. */
1639 delete_file (gfc_unit
* u
)
1641 char path
[min(PATH_MAX
, u
->file_len
+ 1)];
1642 int err
= unpack_filename (path
, u
->file
, u
->file_len
);
1645 { /* Shouldn't be possible */
1650 return unlink (path
);
1654 /* file_exists()-- Returns nonzero if the current filename exists on
1658 file_exists (const char *file
, gfc_charlen_type file_len
)
1660 char path
[min(PATH_MAX
, file_len
+ 1)];
1662 if (unpack_filename (path
, file
, file_len
))
1665 return !(access (path
, F_OK
));
1669 /* file_size()-- Returns the size of the file. */
1672 file_size (const char *file
, gfc_charlen_type file_len
)
1674 char path
[min(PATH_MAX
, file_len
+ 1)];
1675 struct stat statbuf
;
1677 if (unpack_filename (path
, file
, file_len
))
1680 if (stat (path
, &statbuf
) < 0)
1683 return (GFC_IO_INT
) statbuf
.st_size
;
1686 static const char yes
[] = "YES", no
[] = "NO", unknown
[] = "UNKNOWN";
1688 /* inquire_sequential()-- Given a fortran string, determine if the
1689 * file is suitable for sequential access. Returns a C-style
1693 inquire_sequential (const char *string
, int len
)
1695 char path
[min(PATH_MAX
, len
+ 1)];
1696 struct stat statbuf
;
1698 if (string
== NULL
||
1699 unpack_filename (path
, string
, len
) || stat (path
, &statbuf
) < 0)
1702 if (S_ISREG (statbuf
.st_mode
) ||
1703 S_ISCHR (statbuf
.st_mode
) || S_ISFIFO (statbuf
.st_mode
))
1706 if (S_ISDIR (statbuf
.st_mode
) || S_ISBLK (statbuf
.st_mode
))
1713 /* inquire_direct()-- Given a fortran string, determine if the file is
1714 * suitable for direct access. Returns a C-style string. */
1717 inquire_direct (const char *string
, int len
)
1719 char path
[min(PATH_MAX
, len
+ 1)];
1720 struct stat statbuf
;
1722 if (string
== NULL
||
1723 unpack_filename (path
, string
, len
) || stat (path
, &statbuf
) < 0)
1726 if (S_ISREG (statbuf
.st_mode
) || S_ISBLK (statbuf
.st_mode
))
1729 if (S_ISDIR (statbuf
.st_mode
) ||
1730 S_ISCHR (statbuf
.st_mode
) || S_ISFIFO (statbuf
.st_mode
))
1737 /* inquire_formatted()-- Given a fortran string, determine if the file
1738 * is suitable for formatted form. Returns a C-style string. */
1741 inquire_formatted (const char *string
, int len
)
1743 char path
[min(PATH_MAX
, len
+ 1)];
1744 struct stat statbuf
;
1746 if (string
== NULL
||
1747 unpack_filename (path
, string
, len
) || stat (path
, &statbuf
) < 0)
1750 if (S_ISREG (statbuf
.st_mode
) ||
1751 S_ISBLK (statbuf
.st_mode
) ||
1752 S_ISCHR (statbuf
.st_mode
) || S_ISFIFO (statbuf
.st_mode
))
1755 if (S_ISDIR (statbuf
.st_mode
))
1762 /* inquire_unformatted()-- Given a fortran string, determine if the file
1763 * is suitable for unformatted form. Returns a C-style string. */
1766 inquire_unformatted (const char *string
, int len
)
1768 return inquire_formatted (string
, len
);
1772 /* inquire_access()-- Given a fortran string, determine if the file is
1773 * suitable for access. */
1776 inquire_access (const char *string
, int len
, int mode
)
1778 char path
[min(PATH_MAX
, len
+ 1)];
1780 if (string
== NULL
|| unpack_filename (path
, string
, len
) ||
1781 access (path
, mode
) < 0)
1788 /* inquire_read()-- Given a fortran string, determine if the file is
1789 * suitable for READ access. */
1792 inquire_read (const char *string
, int len
)
1794 return inquire_access (string
, len
, R_OK
);
1798 /* inquire_write()-- Given a fortran string, determine if the file is
1799 * suitable for READ access. */
1802 inquire_write (const char *string
, int len
)
1804 return inquire_access (string
, len
, W_OK
);
1808 /* inquire_readwrite()-- Given a fortran string, determine if the file is
1809 * suitable for read and write access. */
1812 inquire_readwrite (const char *string
, int len
)
1814 return inquire_access (string
, len
, R_OK
| W_OK
);
1819 stream_isatty (stream
*s
)
1821 return isatty (((unix_stream
*) s
)->fd
);
1825 stream_ttyname (stream
*s
__attribute__ ((unused
)),
1826 char * buf
__attribute__ ((unused
)),
1827 size_t buflen
__attribute__ ((unused
)))
1829 #ifdef HAVE_TTYNAME_R
1830 return ttyname_r (((unix_stream
*) s
)->fd
, buf
, buflen
);
1831 #elif defined HAVE_TTYNAME
1834 p
= ttyname (((unix_stream
*) s
)->fd
);
1840 memcpy (buf
, p
, plen
);
1850 /* How files are stored: This is an operating-system specific issue,
1851 and therefore belongs here. There are three cases to consider.
1854 Records are written as block of bytes corresponding to the record
1855 length of the file. This goes for both formatted and unformatted
1856 records. Positioning is done explicitly for each data transfer,
1857 so positioning is not much of an issue.
1859 Sequential Formatted:
1860 Records are separated by newline characters. The newline character
1861 is prohibited from appearing in a string. If it does, this will be
1862 messed up on the next read. End of file is also the end of a record.
1864 Sequential Unformatted:
1865 In this case, we are merely copying bytes to and from main storage,
1866 yet we need to keep track of varying record lengths. We adopt
1867 the solution used by f2c. Each record contains a pair of length
1870 Length of record n in bytes
1872 Length of record n in bytes
1874 Length of record n+1 in bytes
1876 Length of record n+1 in bytes
1878 The length is stored at the end of a record to allow backspacing to the
1879 previous record. Between data transfer statements, the file pointer
1880 is left pointing to the first length of the current record.
1882 ENDFILE records are never explicitly stored.