1 /* Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
2 Free Software Foundation, Inc.
3 Contributed by Andy Vaught
4 F2003 I/O support contributed by Jerry DeLisle
6 This file is part of the GNU Fortran 95 runtime library (libgfortran).
8 Libgfortran is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 Libgfortran is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 Under Section 7 of GPL version 3, you are granted additional
19 permissions described in the GCC Runtime Library Exception, version
20 3.1, as published by the Free Software Foundation.
22 You should have received a copy of the GNU General Public License and
23 a copy of the GCC Runtime Library Exception along with this program;
24 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
25 <http://www.gnu.org/licenses/>. */
27 /* 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. */
44 #if defined(__MINGW32__) && !HAVE_WORKING_STAT
46 #define WIN32_LEAN_AND_MEAN
50 id_from_handle (HANDLE hFile)
52 BY_HANDLE_FILE_INFORMATION FileInformation;
54 if (hFile == INVALID_HANDLE_VALUE)
57 memset (&FileInformation, 0, sizeof(FileInformation));
58 if (!GetFileInformationByHandle (hFile, &FileInformation))
61 return ((uint64_t) FileInformation.nFileIndexLow)
62 | (((uint64_t) FileInformation.nFileIndexHigh) << 32);
67 id_from_path (const char *path)
72 if (!path || !*path || access (path, F_OK))
75 hFile = CreateFile (path, 0, 0, NULL, OPEN_EXISTING,
76 FILE_FLAG_BACKUP_SEMANTICS | FILE_ATTRIBUTE_READONLY,
78 res = id_from_handle (hFile);
85 id_from_fd (const int fd)
87 return id_from_handle ((HANDLE) _get_osfhandle (fd));
104 /* These flags aren't defined on all targets (mingw32), so provide them
123 /* Unix and internal stream I/O module */
125 static const int BUFFER_SIZE = 8192;
131 gfc_offset buffer_offset; /* File offset of the start of the buffer */
132 gfc_offset physical_offset; /* Current physical file offset */
133 gfc_offset logical_offset; /* Current logical file offset */
134 gfc_offset file_length; /* Length of the file, -1 if not seekable. */
136 char *buffer; /* Pointer to the buffer. */
137 int fd; /* The POSIX file descriptor. */
139 int active; /* Length of valid bytes in the buffer */
142 int ndirty; /* Dirty bytes starting at buffer_offset */
144 int special_file; /* =1 if the fd refers to a special file */
149 /* fix_fd()-- Given a file descriptor, make sure it is not one of the
150 * standard descriptors, returning a non-standard descriptor. If the
151 * user specifies that system errors should go to standard output,
152 * then closes standard output, we don't want the system errors to a
153 * file that has been given file descriptor 1 or 0. We want to send
154 * the error to the invalid descriptor. */
160 int input, output, error;
162 input = output = error = 0;
164 /* Unix allocates the lowest descriptors first, so a loop is not
165 required, but this order is. */
166 if (fd == STDIN_FILENO)
171 if (fd == STDOUT_FILENO)
176 if (fd == STDERR_FILENO)
183 close (STDIN_FILENO);
185 close (STDOUT_FILENO);
187 close (STDERR_FILENO);
194 /* If the stream corresponds to a preconnected unit, we flush the
195 corresponding C stream. This is bugware for mixed C-Fortran codes
196 where the C code doesn't flush I/O before returning. */
198 flush_if_preconnected (stream * s)
202 fd = ((unix_stream *) s)->fd;
203 if (fd == STDIN_FILENO)
205 else if (fd == STDOUT_FILENO)
207 else if (fd == STDERR_FILENO)
212 /* get_oserror()-- Get the most recent operating system error. For
213 * unix, this is errno. */
218 return strerror (errno);
222 /********************************************************************
223 Raw I/O functions (read, write, seek, tell, truncate, close).
225 These functions wrap the basic POSIX I/O syscalls. Any deviation in
226 semantics is a bug, except the following: write restarts in case
227 of being interrupted by a signal, and as the first argument the
228 functions take the unix_stream struct rather than an integer file
229 descriptor. Also, for POSIX read() and write() a nbyte argument larger
230 than SSIZE_MAX is undefined; here the type of nbyte is ssize_t rather
231 than size_t as for POSIX read/write.
232 *********************************************************************/
235 raw_flush (unix_stream * s __attribute__ ((unused)))
241 raw_read (unix_stream * s, void * buf, ssize_t nbyte)
243 /* For read we can't do I/O in a loop like raw_write does, because
244 that will break applications that wait for interactive I/O. */
245 return read (s->fd, buf, nbyte);
249 raw_write (unix_stream * s, const void * buf, ssize_t nbyte)
251 ssize_t trans, bytes_left;
255 buf_st = (char *) buf;
257 /* We must write in a loop since some systems don't restart system
258 calls in case of a signal. */
259 while (bytes_left > 0)
261 trans = write (s->fd, buf_st, bytes_left);
273 return nbyte - bytes_left;
277 raw_seek (unix_stream * s, off_t offset, int whence)
279 return lseek (s->fd, offset, whence);
283 raw_tell (unix_stream * s)
285 return lseek (s->fd, 0, SEEK_CUR);
289 raw_truncate (unix_stream * s, off_t length)
291 #ifdef HAVE_FTRUNCATE
292 return ftruncate (s->fd, length);
293 #elif defined HAVE_CHSIZE
294 return chsize (s->fd, length);
296 runtime_error ("required ftruncate or chsize support not present");
302 raw_close (unix_stream * s)
306 if (s->fd != STDOUT_FILENO
307 && s->fd != STDERR_FILENO
308 && s->fd != STDIN_FILENO)
309 retval = close (s->fd);
317 raw_init (unix_stream * s)
319 s->st.read = (void *) raw_read;
320 s->st.write = (void *) raw_write;
321 s->st.seek = (void *) raw_seek;
322 s->st.tell = (void *) raw_tell;
323 s->st.trunc = (void *) raw_truncate;
324 s->st.close = (void *) raw_close;
325 s->st.flush = (void *) raw_flush;
332 /*********************************************************************
333 Buffered I/O functions. These functions have the same semantics as the
334 raw I/O functions above, except that they are buffered in order to
335 improve performance. The buffer must be flushed when switching from
336 reading to writing and vice versa.
337 *********************************************************************/
340 buf_flush (unix_stream * s)
344 /* Flushing in read mode means discarding read bytes. */
350 if (s->file_length != -1 && s->physical_offset != s->buffer_offset
351 && lseek (s->fd, s->buffer_offset, SEEK_SET) < 0)
354 writelen = raw_write (s, s->buffer, s->ndirty);
356 s->physical_offset = s->buffer_offset + writelen;
358 /* Don't increment file_length if the file is non-seekable. */
359 if (s->file_length != -1 && s->physical_offset > s->file_length)
360 s->file_length = s->physical_offset;
362 s->ndirty -= writelen;
370 buf_read (unix_stream * s, void * buf, ssize_t nbyte)
373 s->buffer_offset = s->logical_offset;
375 /* Is the data we want in the buffer? */
376 if (s->logical_offset + nbyte <= s->buffer_offset + s->active
377 && s->buffer_offset <= s->logical_offset)
378 memcpy (buf, s->buffer + (s->logical_offset - s->buffer_offset), nbyte);
381 /* First copy the active bytes if applicable, then read the rest
382 either directly or filling the buffer. */
385 ssize_t to_read, did_read;
386 gfc_offset new_logical;
389 if (s->logical_offset >= s->buffer_offset
390 && s->buffer_offset + s->active >= s->logical_offset)
392 nread = s->active - (s->logical_offset - s->buffer_offset);
393 memcpy (buf, s->buffer + (s->logical_offset - s->buffer_offset),
397 /* At this point we consider all bytes in the buffer discarded. */
398 to_read = nbyte - nread;
399 new_logical = s->logical_offset + nread;
400 if (s->file_length != -1 && s->physical_offset != new_logical
401 && lseek (s->fd, new_logical, SEEK_SET) < 0)
403 s->buffer_offset = s->physical_offset = new_logical;
404 if (to_read <= BUFFER_SIZE/2)
406 did_read = raw_read (s, s->buffer, BUFFER_SIZE);
407 s->physical_offset += did_read;
408 s->active = did_read;
409 did_read = (did_read > to_read) ? to_read : did_read;
410 memcpy (p, s->buffer, did_read);
414 did_read = raw_read (s, p, to_read);
415 s->physical_offset += did_read;
418 nbyte = did_read + nread;
420 s->logical_offset += nbyte;
425 buf_write (unix_stream * s, const void * buf, ssize_t nbyte)
428 s->buffer_offset = s->logical_offset;
430 /* Does the data fit into the buffer? As a special case, if the
431 buffer is empty and the request is bigger than BUFFER_SIZE/2,
432 write directly. This avoids the case where the buffer would have
433 to be flushed at every write. */
434 if (!(s->ndirty == 0 && nbyte > BUFFER_SIZE/2)
435 && s->logical_offset + nbyte <= s->buffer_offset + BUFFER_SIZE
436 && s->buffer_offset <= s->logical_offset
437 && s->buffer_offset + s->ndirty >= s->logical_offset)
439 memcpy (s->buffer + (s->logical_offset - s->buffer_offset), buf, nbyte);
440 int nd = (s->logical_offset - s->buffer_offset) + nbyte;
446 /* Flush, and either fill the buffer with the new data, or if
447 the request is bigger than the buffer size, write directly
448 bypassing the buffer. */
450 if (nbyte <= BUFFER_SIZE/2)
452 memcpy (s->buffer, buf, nbyte);
453 s->buffer_offset = s->logical_offset;
458 if (s->file_length != -1 && s->physical_offset != s->logical_offset
459 && lseek (s->fd, s->logical_offset, SEEK_SET) < 0)
461 nbyte = raw_write (s, buf, nbyte);
462 s->physical_offset += nbyte;
465 s->logical_offset += nbyte;
466 /* Don't increment file_length if the file is non-seekable. */
467 if (s->file_length != -1 && s->logical_offset > s->file_length)
468 s->file_length = s->logical_offset;
473 buf_seek (unix_stream * s, off_t offset, int whence)
480 offset += s->logical_offset;
483 offset += s->file_length;
493 s->logical_offset = offset;
498 buf_tell (unix_stream * s)
500 return s->logical_offset;
504 buf_truncate (unix_stream * s, off_t length)
508 if (buf_flush (s) != 0)
510 r = raw_truncate (s, length);
512 s->file_length = length;
517 buf_close (unix_stream * s)
519 if (buf_flush (s) != 0)
521 free_mem (s->buffer);
522 return raw_close (s);
526 buf_init (unix_stream * s)
528 s->st.read = (void *) buf_read;
529 s->st.write = (void *) buf_write;
530 s->st.seek = (void *) buf_seek;
531 s->st.tell = (void *) buf_tell;
532 s->st.trunc = (void *) buf_truncate;
533 s->st.close = (void *) buf_close;
534 s->st.flush = (void *) buf_flush;
536 s->buffer = get_mem (BUFFER_SIZE);
541 /*********************************************************************
542 memory stream functions - These are used for internal files
544 The idea here is that a single stream structure is created and all
545 requests must be satisfied from it. The location and size of the
546 buffer is the character variable supplied to the READ or WRITE
549 *********************************************************************/
553 mem_alloc_r (stream * strm, int * len)
555 unix_stream * s = (unix_stream *) strm;
557 gfc_offset where = s->logical_offset;
559 if (where < s->buffer_offset || where > s->buffer_offset + s->active)
562 n = s->buffer_offset + s->active - where;
566 s->logical_offset = where + *len;
568 return s->buffer + (where - s->buffer_offset);
573 mem_alloc_w (stream * strm, int * len)
575 unix_stream * s = (unix_stream *) strm;
577 gfc_offset where = s->logical_offset;
581 if (where < s->buffer_offset)
584 if (m > s->file_length)
587 s->logical_offset = m;
589 return s->buffer + (where - s->buffer_offset);
593 /* Stream read function for internal units. */
596 mem_read (stream * s, void * buf, ssize_t nbytes)
601 p = mem_alloc_r (s, &nb);
612 /* Stream write function for internal units. This is not actually used
613 at the moment, as all internal IO is formatted and the formatted IO
614 routines use mem_alloc_w_at. */
617 mem_write (stream * s, const void * buf, ssize_t nbytes)
622 p = mem_alloc_w (s, &nb);
634 mem_seek (stream * strm, off_t offset, int whence)
636 unix_stream * s = (unix_stream *) strm;
642 offset += s->logical_offset;
645 offset += s->file_length;
651 /* Note that for internal array I/O it's actually possible to have a
652 negative offset, so don't check for that. */
653 if (offset > s->file_length)
659 s->logical_offset = offset;
661 /* Returning < 0 is the error indicator for sseek(), so return 0 if
662 offset is negative. Thus if the return value is 0, the caller
663 has to use stell() to get the real value of logical_offset. */
671 mem_tell (stream * s)
673 return ((unix_stream *)s)->logical_offset;
678 mem_truncate (unix_stream * s __attribute__ ((unused)),
679 off_t length __attribute__ ((unused)))
686 mem_flush (unix_stream * s __attribute__ ((unused)))
693 mem_close (unix_stream * s)
702 /*********************************************************************
703 Public functions -- A reimplementation of this module needs to
704 define functional equivalents of the following.
705 *********************************************************************/
707 /* empty_internal_buffer()-- Zero the buffer of Internal file */
710 empty_internal_buffer(stream *strm)
712 unix_stream * s = (unix_stream *) strm;
713 memset(s->buffer, ' ', s->file_length);
716 /* open_internal()-- Returns a stream structure from an internal file */
719 open_internal (char *base, int length, gfc_offset offset)
723 s = get_mem (sizeof (unix_stream));
724 memset (s, '\0', sizeof (unix_stream));
727 s->buffer_offset = offset;
729 s->logical_offset = 0;
730 s->active = s->file_length = length;
732 s->st.close = (void *) mem_close;
733 s->st.seek = (void *) mem_seek;
734 s->st.tell = (void *) mem_tell;
735 s->st.trunc = (void *) mem_truncate;
736 s->st.read = (void *) mem_read;
737 s->st.write = (void *) mem_write;
738 s->st.flush = (void *) mem_flush;
744 /* fd_to_stream()-- Given an open file descriptor, build a stream
748 fd_to_stream (int fd, int prot)
753 s = get_mem (sizeof (unix_stream));
754 memset (s, '\0', sizeof (unix_stream));
757 s->buffer_offset = 0;
758 s->physical_offset = 0;
759 s->logical_offset = 0;
762 /* Get the current length of the file. */
764 fstat (fd, &statbuf);
766 if (lseek (fd, 0, SEEK_CUR) == (off_t) -1)
769 s->file_length = S_ISREG (statbuf.st_mode) ? statbuf.st_size : -1;
771 s->special_file = !S_ISREG (statbuf.st_mode);
773 if (isatty (s->fd) || options.all_unbuffered
774 ||(options.unbuffered_preconnected &&
775 (s->fd == STDIN_FILENO
776 || s->fd == STDOUT_FILENO
777 || s->fd == STDERR_FILENO)))
786 /* Given the Fortran unit number, convert it to a C file descriptor. */
789 unit_to_fd (int unit)
794 us = find_unit (unit);
798 fd = ((unix_stream *) us->s)->fd;
804 /* unpack_filename()-- Given a fortran string and a pointer to a
805 * buffer that is PATH_MAX characters, convert the fortran string to a
806 * C string in the buffer. Returns nonzero if this is not possible. */
809 unpack_filename (char *cstring, const char *fstring, int len)
811 len = fstrlen (fstring, len);
815 memmove (cstring, fstring, len);
822 /* tempfile()-- Generate a temporary filename for a scratch file and
823 * open it. mkstemp() opens the file for reading and writing, but the
824 * library mode prevents anything that is not allowed. The descriptor
825 * is returned, which is -1 on error. The template is pointed to by
826 * opp->file, which is copied into the unit structure
827 * and freed later. */
830 tempfile (st_parameter_open *opp)
836 tempdir = getenv ("GFORTRAN_TMPDIR");
838 tempdir = getenv ("TMP");
840 tempdir = getenv ("TEMP");
842 tempdir = DEFAULT_TEMPDIR;
844 template = get_mem (strlen (tempdir) + 20);
846 sprintf (template, "%s/gfortrantmpXXXXXX", tempdir);
850 fd = mkstemp (template);
852 #else /* HAVE_MKSTEMP */
854 if (mktemp (template))
856 #if defined(HAVE_CRLF) && defined(O_BINARY)
857 fd = open (template, O_RDWR | O_CREAT | O_EXCL | O_BINARY,
860 fd = open (template, O_RDWR | O_CREAT | O_EXCL, S_IREAD | S_IWRITE);
862 while (!(fd == -1 && errno == EEXIST) && mktemp (template));
866 #endif /* HAVE_MKSTEMP */
872 opp->file = template;
873 opp->file_len = strlen (template); /* Don't include trailing nul */
880 /* regular_file()-- Open a regular file.
881 * Change flags->action if it is ACTION_UNSPECIFIED on entry,
882 * unless an error occurs.
883 * Returns the descriptor, which is less than zero on error. */
886 regular_file (st_parameter_open *opp, unit_flags *flags)
888 char path[PATH_MAX + 1];
894 if (unpack_filename (path, opp->file, opp->file_len))
896 errno = ENOENT; /* Fake an OS error */
902 switch (flags->action)
912 case ACTION_READWRITE:
913 case ACTION_UNSPECIFIED:
918 internal_error (&opp->common, "regular_file(): Bad action");
921 switch (flags->status)
924 crflag = O_CREAT | O_EXCL;
927 case STATUS_OLD: /* open will fail if the file does not exist*/
937 crflag = O_CREAT | O_TRUNC;
941 internal_error (&opp->common, "regular_file(): Bad status");
944 /* rwflag |= O_LARGEFILE; */
946 #if defined(HAVE_CRLF) && defined(O_BINARY)
950 mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
951 fd = open (path, rwflag | crflag, mode);
952 if (flags->action != ACTION_UNSPECIFIED)
957 flags->action = ACTION_READWRITE;
960 if (errno != EACCES && errno != EROFS)
963 /* retry for read-only access */
965 fd = open (path, rwflag | crflag, mode);
968 flags->action = ACTION_READ;
969 return fd; /* success */
973 return fd; /* failure */
975 /* retry for write-only access */
977 fd = open (path, rwflag | crflag, mode);
980 flags->action = ACTION_WRITE;
981 return fd; /* success */
983 return fd; /* failure */
987 /* open_external()-- Open an external file, unix specific version.
988 * Change flags->action if it is ACTION_UNSPECIFIED on entry.
989 * Returns NULL on operating system error. */
992 open_external (st_parameter_open *opp, unit_flags *flags)
996 if (flags->status == STATUS_SCRATCH)
999 if (flags->action == ACTION_UNSPECIFIED)
1000 flags->action = ACTION_READWRITE;
1002 #if HAVE_UNLINK_OPEN_FILE
1003 /* We can unlink scratch files now and it will go away when closed. */
1010 /* regular_file resets flags->action if it is ACTION_UNSPECIFIED and
1012 fd = regular_file (opp, flags);
1019 switch (flags->action)
1029 case ACTION_READWRITE:
1030 prot = PROT_READ | PROT_WRITE;
1034 internal_error (&opp->common, "open_external(): Bad action");
1037 return fd_to_stream (fd, prot);
1041 /* input_stream()-- Return a stream pointer to the default input stream.
1042 * Called on initialization. */
1047 return fd_to_stream (STDIN_FILENO, PROT_READ);
1051 /* output_stream()-- Return a stream pointer to the default output stream.
1052 * Called on initialization. */
1055 output_stream (void)
1059 #if defined(HAVE_CRLF) && defined(HAVE_SETMODE)
1060 setmode (STDOUT_FILENO, O_BINARY);
1063 s = fd_to_stream (STDOUT_FILENO, PROT_WRITE);
1068 /* error_stream()-- Return a stream pointer to the default error stream.
1069 * Called on initialization. */
1076 #if defined(HAVE_CRLF) && defined(HAVE_SETMODE)
1077 setmode (STDERR_FILENO, O_BINARY);
1080 s = fd_to_stream (STDERR_FILENO, PROT_WRITE);
1085 /* st_vprintf()-- vprintf function for error output. To avoid buffer
1086 overruns, we limit the length of the buffer to ST_VPRINTF_SIZE. 2k
1087 is big enough to completely fill a 80x25 terminal, so it shuld be
1088 OK. We use a direct write() because it is simpler and least likely
1089 to be clobbered by memory corruption. Writing an error message
1090 longer than that is an error. */
1092 #define ST_VPRINTF_SIZE 2048
1095 st_vprintf (const char *format, va_list ap)
1097 static char buffer[ST_VPRINTF_SIZE];
1101 fd = options.use_stderr ? STDERR_FILENO : STDOUT_FILENO;
1102 #ifdef HAVE_VSNPRINTF
1103 written = vsnprintf(buffer, ST_VPRINTF_SIZE, format, ap);
1105 written = vsprintf(buffer, format, ap);
1107 if (written >= ST_VPRINTF_SIZE-1)
1109 /* The error message was longer than our buffer. Ouch. Because
1110 we may have messed up things badly, report the error and
1112 #define ERROR_MESSAGE "Internal error: buffer overrun in st_vprintf()\n"
1113 write (fd, buffer, ST_VPRINTF_SIZE-1);
1114 write (fd, ERROR_MESSAGE, strlen(ERROR_MESSAGE));
1116 #undef ERROR_MESSAGE
1121 written = write (fd, buffer, written);
1125 /* st_printf()-- printf() function for error output. This just calls
1126 st_vprintf() to do the actual work. */
1129 st_printf (const char *format, ...)
1133 va_start (ap, format);
1134 written = st_vprintf(format, ap);
1140 /* compare_file_filename()-- Given an open stream and a fortran string
1141 * that is a filename, figure out if the file is the same as the
1145 compare_file_filename (gfc_unit *u, const char *name, int len)
1147 char path[PATH_MAX + 1];
1149 #ifdef HAVE_WORKING_STAT
1157 if (unpack_filename (path, name, len))
1158 return 0; /* Can't be the same */
1160 /* If the filename doesn't exist, then there is no match with the
1163 if (stat (path, &st1) < 0)
1166 #ifdef HAVE_WORKING_STAT
1167 fstat (((unix_stream *) (u->s))->fd, &st2);
1168 return (st1.st_dev == st2.st_dev) && (st1.st_ino == st2.st_ino);
1172 /* We try to match files by a unique ID. On some filesystems (network
1173 fs and FAT), we can't generate this unique ID, and will simply compare
1175 id1 = id_from_path (path);
1176 id2 = id_from_fd (((unix_stream *) (u->s))->fd);
1178 return (id1 == id2);
1181 if (len != u->file_len)
1183 return (memcmp(path, u->file, len) == 0);
1188 #ifdef HAVE_WORKING_STAT
1189 # define FIND_FILE0_DECL struct stat *st
1190 # define FIND_FILE0_ARGS st
1192 # define FIND_FILE0_DECL uint64_t id, const char *file, gfc_charlen_type file_len
1193 # define FIND_FILE0_ARGS id, file, file_len
1196 /* find_file0()-- Recursive work function for find_file() */
1199 find_file0 (gfc_unit *u, FIND_FILE0_DECL)
1202 #if defined(__MINGW32__) && !HAVE_WORKING_STAT
1209 #ifdef HAVE_WORKING_STAT
1211 && fstat (((unix_stream *) u->s)->fd, &st[1]) >= 0 &&
1212 st[0].st_dev == st[1].st_dev && st[0].st_ino == st[1].st_ino)
1216 if (u->s && ((id1 = id_from_fd (((unix_stream *) u->s)->fd)) || id1))
1223 if (compare_string (u->file_len, u->file, file_len, file) == 0)
1227 v = find_file0 (u->left, FIND_FILE0_ARGS);
1231 v = find_file0 (u->right, FIND_FILE0_ARGS);
1239 /* find_file()-- Take the current filename and see if there is a unit
1240 * that has the file already open. Returns a pointer to the unit if so. */
1243 find_file (const char *file, gfc_charlen_type file_len)
1245 char path[PATH_MAX + 1];
1250 if (unpack_filename (path, file, file_len))
1253 if (stat (path, &st[0]) < 0)
1256 #if defined(__MINGW32__) && !HAVE_WORKING_STAT
1257 id = id_from_path (path);
1262 __gthread_mutex_lock (&unit_lock);
1264 u = find_file0 (unit_root, FIND_FILE0_ARGS);
1268 if (! __gthread_mutex_trylock (&u->lock))
1270 /* assert (u->closed == 0); */
1271 __gthread_mutex_unlock (&unit_lock);
1275 inc_waiting_locked (u);
1277 __gthread_mutex_unlock (&unit_lock);
1280 __gthread_mutex_lock (&u->lock);
1283 __gthread_mutex_lock (&unit_lock);
1284 __gthread_mutex_unlock (&u->lock);
1285 if (predec_waiting_locked (u) == 0)
1290 dec_waiting_unlocked (u);
1296 flush_all_units_1 (gfc_unit *u, int min_unit)
1300 if (u->unit_number > min_unit)
1302 gfc_unit *r = flush_all_units_1 (u->left, min_unit);
1306 if (u->unit_number >= min_unit)
1308 if (__gthread_mutex_trylock (&u->lock))
1312 __gthread_mutex_unlock (&u->lock);
1320 flush_all_units (void)
1325 __gthread_mutex_lock (&unit_lock);
1328 u = flush_all_units_1 (unit_root, min_unit);
1330 inc_waiting_locked (u);
1331 __gthread_mutex_unlock (&unit_lock);
1335 __gthread_mutex_lock (&u->lock);
1337 min_unit = u->unit_number + 1;
1342 __gthread_mutex_lock (&unit_lock);
1343 __gthread_mutex_unlock (&u->lock);
1344 (void) predec_waiting_locked (u);
1348 __gthread_mutex_lock (&unit_lock);
1349 __gthread_mutex_unlock (&u->lock);
1350 if (predec_waiting_locked (u) == 0)
1358 /* delete_file()-- Given a unit structure, delete the file associated
1359 * with the unit. Returns nonzero if something went wrong. */
1362 delete_file (gfc_unit * u)
1364 char path[PATH_MAX + 1];
1366 if (unpack_filename (path, u->file, u->file_len))
1367 { /* Shouldn't be possible */
1372 return unlink (path);
1376 /* file_exists()-- Returns nonzero if the current filename exists on
1380 file_exists (const char *file, gfc_charlen_type file_len)
1382 char path[PATH_MAX + 1];
1383 struct stat statbuf;
1385 if (unpack_filename (path, file, file_len))
1388 if (stat (path, &statbuf) < 0)
1396 static const char yes[] = "YES", no[] = "NO", unknown[] = "UNKNOWN";
1398 /* inquire_sequential()-- Given a fortran string, determine if the
1399 * file is suitable for sequential access. Returns a C-style
1403 inquire_sequential (const char *string, int len)
1405 char path[PATH_MAX + 1];
1406 struct stat statbuf;
1408 if (string == NULL ||
1409 unpack_filename (path, string, len) || stat (path, &statbuf) < 0)
1412 if (S_ISREG (statbuf.st_mode) ||
1413 S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode))
1416 if (S_ISDIR (statbuf.st_mode) || S_ISBLK (statbuf.st_mode))
1423 /* inquire_direct()-- Given a fortran string, determine if the file is
1424 * suitable for direct access. Returns a C-style string. */
1427 inquire_direct (const char *string, int len)
1429 char path[PATH_MAX + 1];
1430 struct stat statbuf;
1432 if (string == NULL ||
1433 unpack_filename (path, string, len) || stat (path, &statbuf) < 0)
1436 if (S_ISREG (statbuf.st_mode) || S_ISBLK (statbuf.st_mode))
1439 if (S_ISDIR (statbuf.st_mode) ||
1440 S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode))
1447 /* inquire_formatted()-- Given a fortran string, determine if the file
1448 * is suitable for formatted form. Returns a C-style string. */
1451 inquire_formatted (const char *string, int len)
1453 char path[PATH_MAX + 1];
1454 struct stat statbuf;
1456 if (string == NULL ||
1457 unpack_filename (path, string, len) || stat (path, &statbuf) < 0)
1460 if (S_ISREG (statbuf.st_mode) ||
1461 S_ISBLK (statbuf.st_mode) ||
1462 S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode))
1465 if (S_ISDIR (statbuf.st_mode))
1472 /* inquire_unformatted()-- Given a fortran string, determine if the file
1473 * is suitable for unformatted form. Returns a C-style string. */
1476 inquire_unformatted (const char *string, int len)
1478 return inquire_formatted (string, len);
1492 /* Fallback implementation of access() on systems that don't have it.
1493 Only modes R_OK and W_OK are used in this file. */
1496 fallback_access (const char *path, int mode)
1498 if ((mode & R_OK) && open (path, O_RDONLY) < 0)
1501 if ((mode & W_OK) && open (path, O_WRONLY) < 0)
1508 #define access fallback_access
1512 /* inquire_access()-- Given a fortran string, determine if the file is
1513 * suitable for access. */
1516 inquire_access (const char *string, int len, int mode)
1518 char path[PATH_MAX + 1];
1520 if (string == NULL || unpack_filename (path, string, len) ||
1521 access (path, mode) < 0)
1528 /* inquire_read()-- Given a fortran string, determine if the file is
1529 * suitable for READ access. */
1532 inquire_read (const char *string, int len)
1534 return inquire_access (string, len, R_OK);
1538 /* inquire_write()-- Given a fortran string, determine if the file is
1539 * suitable for READ access. */
1542 inquire_write (const char *string, int len)
1544 return inquire_access (string, len, W_OK);
1548 /* inquire_readwrite()-- Given a fortran string, determine if the file is
1549 * suitable for read and write access. */
1552 inquire_readwrite (const char *string, int len)
1554 return inquire_access (string, len, R_OK | W_OK);
1558 /* file_length()-- Return the file length in bytes, -1 if unknown */
1561 file_length (stream * s)
1564 if (!is_seekable (s))
1569 end = sseek (s, 0, SEEK_END);
1570 sseek (s, curr, SEEK_SET);
1575 /* is_seekable()-- Return nonzero if the stream is seekable, zero if
1579 is_seekable (stream *s)
1581 /* By convention, if file_length == -1, the file is not
1583 return ((unix_stream *) s)->file_length!=-1;
1587 /* is_special()-- Return nonzero if the stream is not a regular file. */
1590 is_special (stream *s)
1592 return ((unix_stream *) s)->special_file;
1597 stream_isatty (stream *s)
1599 return isatty (((unix_stream *) s)->fd);
1603 stream_ttyname (stream *s __attribute__ ((unused)))
1606 return ttyname (((unix_stream *) s)->fd);
1613 /* How files are stored: This is an operating-system specific issue,
1614 and therefore belongs here. There are three cases to consider.
1617 Records are written as block of bytes corresponding to the record
1618 length of the file. This goes for both formatted and unformatted
1619 records. Positioning is done explicitly for each data transfer,
1620 so positioning is not much of an issue.
1622 Sequential Formatted:
1623 Records are separated by newline characters. The newline character
1624 is prohibited from appearing in a string. If it does, this will be
1625 messed up on the next read. End of file is also the end of a record.
1627 Sequential Unformatted:
1628 In this case, we are merely copying bytes to and from main storage,
1629 yet we need to keep track of varying record lengths. We adopt
1630 the solution used by f2c. Each record contains a pair of length
1633 Length of record n in bytes
1635 Length of record n in bytes
1637 Length of record n+1 in bytes
1639 Length of record n+1 in bytes
1641 The length is stored at the end of a record to allow backspacing to the
1642 previous record. Between data transfer statements, the file pointer
1643 is left pointing to the first length of the current record.
1645 ENDFILE records are never explicitly stored.