1 /* Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
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 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 */
43 /* For mingw, we don't identify files by their inode number, but by a
44 64-bit identifier created from a BY_HANDLE_FILE_INFORMATION. */
47 #define WIN32_LEAN_AND_MEAN
50 #define lseek _lseeki64
51 #define fstat _fstati64
53 typedef struct _stati64 gfstat_t;
55 #ifndef HAVE_WORKING_STAT
57 id_from_handle (HANDLE hFile)
59 BY_HANDLE_FILE_INFORMATION FileInformation;
61 if (hFile == INVALID_HANDLE_VALUE)
64 memset (&FileInformation, 0, sizeof(FileInformation));
65 if (!GetFileInformationByHandle (hFile, &FileInformation))
68 return ((uint64_t) FileInformation.nFileIndexLow)
69 | (((uint64_t) FileInformation.nFileIndexHigh) << 32);
74 id_from_path (const char *path)
79 if (!path || !*path || access (path, F_OK))
82 hFile = CreateFile (path, 0, 0, NULL, OPEN_EXISTING,
83 FILE_FLAG_BACKUP_SEMANTICS | FILE_ATTRIBUTE_READONLY,
85 res = id_from_handle (hFile);
92 id_from_fd (const int fd)
94 return id_from_handle ((HANDLE) _get_osfhandle (fd));
100 typedef struct stat gfstat_t;
104 #define PATH_MAX 1024
115 /* These flags aren't defined on all targets (mingw32), so provide them
148 /* Fallback implementation of access() on systems that don't have it.
149 Only modes R_OK, W_OK and F_OK are used in this file. */
152 fallback_access (const char *path, int mode)
154 if ((mode & R_OK) && open (path, O_RDONLY) < 0)
157 if ((mode & W_OK) && open (path, O_WRONLY) < 0)
163 return stat (path, &st);
170 #define access fallback_access
174 /* Unix and internal stream I/O module */
176 static const int BUFFER_SIZE = 8192;
178 /* fix_fd()-- Given a file descriptor, make sure it is not one of the
179 * standard descriptors, returning a non-standard descriptor. If the
180 * user specifies that system errors should go to standard output,
181 * then closes standard output, we don't want the system errors to a
182 * file that has been given file descriptor 1 or 0. We want to send
183 * the error to the invalid descriptor. */
189 int input, output, error;
191 input = output = error = 0;
193 /* Unix allocates the lowest descriptors first, so a loop is not
194 required, but this order is. */
195 if (fd == STDIN_FILENO)
200 if (fd == STDOUT_FILENO)
205 if (fd == STDERR_FILENO)
212 close (STDIN_FILENO);
214 close (STDOUT_FILENO);
216 close (STDERR_FILENO);
223 /* If the stream corresponds to a preconnected unit, we flush the
224 corresponding C stream. This is bugware for mixed C-Fortran codes
225 where the C code doesn't flush I/O before returning. */
227 flush_if_preconnected (stream * s)
231 fd = ((unix_stream *) s)->fd;
232 if (fd == STDIN_FILENO)
234 else if (fd == STDOUT_FILENO)
236 else if (fd == STDERR_FILENO)
241 /* get_oserror()-- Get the most recent operating system error. For
242 * unix, this is errno. */
247 return strerror (errno);
251 /********************************************************************
252 Raw I/O functions (read, write, seek, tell, truncate, close).
254 These functions wrap the basic POSIX I/O syscalls. Any deviation in
255 semantics is a bug, except the following: write restarts in case
256 of being interrupted by a signal, and as the first argument the
257 functions take the unix_stream struct rather than an integer file
258 descriptor. Also, for POSIX read() and write() a nbyte argument larger
259 than SSIZE_MAX is undefined; here the type of nbyte is ssize_t rather
260 than size_t as for POSIX read/write.
261 *********************************************************************/
264 raw_flush (unix_stream * s __attribute__ ((unused)))
270 raw_read (unix_stream * s, void * buf, ssize_t nbyte)
272 /* For read we can't do I/O in a loop like raw_write does, because
273 that will break applications that wait for interactive I/O. */
274 return read (s->fd, buf, nbyte);
278 raw_write (unix_stream * s, const void * buf, ssize_t nbyte)
280 ssize_t trans, bytes_left;
284 buf_st = (char *) buf;
286 /* We must write in a loop since some systems don't restart system
287 calls in case of a signal. */
288 while (bytes_left > 0)
290 trans = write (s->fd, buf_st, bytes_left);
302 return nbyte - bytes_left;
306 raw_seek (unix_stream * s, gfc_offset offset, int whence)
308 return lseek (s->fd, offset, whence);
312 raw_tell (unix_stream * s)
314 return lseek (s->fd, 0, SEEK_CUR);
318 raw_truncate (unix_stream * s, gfc_offset length)
329 h = (HANDLE) _get_osfhandle (s->fd);
330 if (h == INVALID_HANDLE_VALUE)
335 cur = lseek (s->fd, 0, SEEK_CUR);
338 if (lseek (s->fd, length, SEEK_SET) == -1)
340 if (!SetEndOfFile (h))
345 if (lseek (s->fd, cur, SEEK_SET) == -1)
349 lseek (s->fd, cur, SEEK_SET);
351 #elif defined HAVE_FTRUNCATE
352 return ftruncate (s->fd, length);
353 #elif defined HAVE_CHSIZE
354 return chsize (s->fd, length);
356 runtime_error ("required ftruncate or chsize support not present");
362 raw_close (unix_stream * s)
366 if (s->fd != STDOUT_FILENO
367 && s->fd != STDERR_FILENO
368 && s->fd != STDIN_FILENO)
369 retval = close (s->fd);
377 raw_init (unix_stream * s)
379 s->st.read = (void *) raw_read;
380 s->st.write = (void *) raw_write;
381 s->st.seek = (void *) raw_seek;
382 s->st.tell = (void *) raw_tell;
383 s->st.trunc = (void *) raw_truncate;
384 s->st.close = (void *) raw_close;
385 s->st.flush = (void *) raw_flush;
392 /*********************************************************************
393 Buffered I/O functions. These functions have the same semantics as the
394 raw I/O functions above, except that they are buffered in order to
395 improve performance. The buffer must be flushed when switching from
396 reading to writing and vice versa.
397 *********************************************************************/
400 buf_flush (unix_stream * s)
404 /* Flushing in read mode means discarding read bytes. */
410 if (s->file_length != -1 && s->physical_offset != s->buffer_offset
411 && lseek (s->fd, s->buffer_offset, SEEK_SET) < 0)
414 writelen = raw_write (s, s->buffer, s->ndirty);
416 s->physical_offset = s->buffer_offset + writelen;
418 /* Don't increment file_length if the file is non-seekable. */
419 if (s->file_length != -1 && s->physical_offset > s->file_length)
420 s->file_length = s->physical_offset;
422 s->ndirty -= writelen;
434 buf_read (unix_stream * s, void * buf, ssize_t nbyte)
437 s->buffer_offset = s->logical_offset;
439 /* Is the data we want in the buffer? */
440 if (s->logical_offset + nbyte <= s->buffer_offset + s->active
441 && s->buffer_offset <= s->logical_offset)
442 memcpy (buf, s->buffer + (s->logical_offset - s->buffer_offset), nbyte);
445 /* First copy the active bytes if applicable, then read the rest
446 either directly or filling the buffer. */
449 ssize_t to_read, did_read;
450 gfc_offset new_logical;
453 if (s->logical_offset >= s->buffer_offset
454 && s->buffer_offset + s->active >= s->logical_offset)
456 nread = s->active - (s->logical_offset - s->buffer_offset);
457 memcpy (buf, s->buffer + (s->logical_offset - s->buffer_offset),
461 /* At this point we consider all bytes in the buffer discarded. */
462 to_read = nbyte - nread;
463 new_logical = s->logical_offset + nread;
464 if (s->file_length != -1 && s->physical_offset != new_logical
465 && lseek (s->fd, new_logical, SEEK_SET) < 0)
467 s->buffer_offset = s->physical_offset = new_logical;
468 if (to_read <= BUFFER_SIZE/2)
470 did_read = raw_read (s, s->buffer, BUFFER_SIZE);
471 s->physical_offset += did_read;
472 s->active = did_read;
473 did_read = (did_read > to_read) ? to_read : did_read;
474 memcpy (p, s->buffer, did_read);
478 did_read = raw_read (s, p, to_read);
479 s->physical_offset += did_read;
482 nbyte = did_read + nread;
484 s->logical_offset += nbyte;
489 buf_write (unix_stream * s, const void * buf, ssize_t nbyte)
492 s->buffer_offset = s->logical_offset;
494 /* Does the data fit into the buffer? As a special case, if the
495 buffer is empty and the request is bigger than BUFFER_SIZE/2,
496 write directly. This avoids the case where the buffer would have
497 to be flushed at every write. */
498 if (!(s->ndirty == 0 && nbyte > BUFFER_SIZE/2)
499 && s->logical_offset + nbyte <= s->buffer_offset + BUFFER_SIZE
500 && s->buffer_offset <= s->logical_offset
501 && s->buffer_offset + s->ndirty >= s->logical_offset)
503 memcpy (s->buffer + (s->logical_offset - s->buffer_offset), buf, nbyte);
504 int nd = (s->logical_offset - s->buffer_offset) + nbyte;
510 /* Flush, and either fill the buffer with the new data, or if
511 the request is bigger than the buffer size, write directly
512 bypassing the buffer. */
514 if (nbyte <= BUFFER_SIZE/2)
516 memcpy (s->buffer, buf, nbyte);
517 s->buffer_offset = s->logical_offset;
522 if (s->file_length != -1 && s->physical_offset != s->logical_offset)
524 if (lseek (s->fd, s->logical_offset, SEEK_SET) < 0)
526 s->physical_offset = s->logical_offset;
529 nbyte = raw_write (s, buf, nbyte);
530 s->physical_offset += nbyte;
533 s->logical_offset += nbyte;
534 /* Don't increment file_length if the file is non-seekable. */
535 if (s->file_length != -1 && s->logical_offset > s->file_length)
536 s->file_length = s->logical_offset;
541 buf_seek (unix_stream * s, gfc_offset offset, int whence)
548 offset += s->logical_offset;
551 offset += s->file_length;
561 s->logical_offset = offset;
566 buf_tell (unix_stream * s)
568 return s->logical_offset;
572 buf_truncate (unix_stream * s, gfc_offset length)
576 if (buf_flush (s) != 0)
578 r = raw_truncate (s, length);
580 s->file_length = length;
585 buf_close (unix_stream * s)
587 if (buf_flush (s) != 0)
590 return raw_close (s);
594 buf_init (unix_stream * s)
596 s->st.read = (void *) buf_read;
597 s->st.write = (void *) buf_write;
598 s->st.seek = (void *) buf_seek;
599 s->st.tell = (void *) buf_tell;
600 s->st.trunc = (void *) buf_truncate;
601 s->st.close = (void *) buf_close;
602 s->st.flush = (void *) buf_flush;
604 s->buffer = get_mem (BUFFER_SIZE);
609 /*********************************************************************
610 memory stream functions - These are used for internal files
612 The idea here is that a single stream structure is created and all
613 requests must be satisfied from it. The location and size of the
614 buffer is the character variable supplied to the READ or WRITE
617 *********************************************************************/
620 mem_alloc_r (stream * strm, int * len)
622 unix_stream * s = (unix_stream *) strm;
624 gfc_offset where = s->logical_offset;
626 if (where < s->buffer_offset || where > s->buffer_offset + s->active)
629 n = s->buffer_offset + s->active - where;
633 s->logical_offset = where + *len;
635 return s->buffer + (where - s->buffer_offset);
640 mem_alloc_r4 (stream * strm, int * len)
642 unix_stream * s = (unix_stream *) strm;
644 gfc_offset where = s->logical_offset;
646 if (where < s->buffer_offset || where > s->buffer_offset + s->active)
649 n = s->buffer_offset + s->active - where;
653 s->logical_offset = where + *len;
655 return s->buffer + (where - s->buffer_offset) * 4;
660 mem_alloc_w (stream * strm, int * len)
662 unix_stream * s = (unix_stream *) strm;
664 gfc_offset where = s->logical_offset;
668 if (where < s->buffer_offset)
671 if (m > s->file_length)
674 s->logical_offset = m;
676 return s->buffer + (where - s->buffer_offset);
681 mem_alloc_w4 (stream * strm, int * len)
683 unix_stream * s = (unix_stream *) strm;
685 gfc_offset where = s->logical_offset;
686 gfc_char4_t *result = (gfc_char4_t *) s->buffer;
690 if (where < s->buffer_offset)
693 if (m > s->file_length)
696 s->logical_offset = m;
697 return &result[where - s->buffer_offset];
701 /* Stream read function for character(kine=1) internal units. */
704 mem_read (stream * s, void * buf, ssize_t nbytes)
709 p = mem_alloc_r (s, &nb);
720 /* Stream read function for chracter(kind=4) internal units. */
723 mem_read4 (stream * s, void * buf, ssize_t nbytes)
728 p = mem_alloc_r (s, &nb);
739 /* Stream write function for character(kind=1) internal units. */
742 mem_write (stream * s, const void * buf, ssize_t nbytes)
747 p = mem_alloc_w (s, &nb);
758 /* Stream write function for character(kind=4) internal units. */
761 mem_write4 (stream * s, const void * buf, ssize_t nwords)
766 p = mem_alloc_w4 (s, &nw);
770 *p++ = (gfc_char4_t) *((char *) buf);
779 mem_seek (stream * strm, gfc_offset offset, int whence)
781 unix_stream * s = (unix_stream *) strm;
787 offset += s->logical_offset;
790 offset += s->file_length;
796 /* Note that for internal array I/O it's actually possible to have a
797 negative offset, so don't check for that. */
798 if (offset > s->file_length)
804 s->logical_offset = offset;
806 /* Returning < 0 is the error indicator for sseek(), so return 0 if
807 offset is negative. Thus if the return value is 0, the caller
808 has to use stell() to get the real value of logical_offset. */
816 mem_tell (stream * s)
818 return ((unix_stream *)s)->logical_offset;
823 mem_truncate (unix_stream * s __attribute__ ((unused)),
824 gfc_offset length __attribute__ ((unused)))
831 mem_flush (unix_stream * s __attribute__ ((unused)))
838 mem_close (unix_stream * s)
847 /*********************************************************************
848 Public functions -- A reimplementation of this module needs to
849 define functional equivalents of the following.
850 *********************************************************************/
852 /* open_internal()-- Returns a stream structure from a character(kind=1)
856 open_internal (char *base, int length, gfc_offset offset)
860 s = get_mem (sizeof (unix_stream));
861 memset (s, '\0', sizeof (unix_stream));
864 s->buffer_offset = offset;
866 s->logical_offset = 0;
867 s->active = s->file_length = length;
869 s->st.close = (void *) mem_close;
870 s->st.seek = (void *) mem_seek;
871 s->st.tell = (void *) mem_tell;
872 s->st.trunc = (void *) mem_truncate;
873 s->st.read = (void *) mem_read;
874 s->st.write = (void *) mem_write;
875 s->st.flush = (void *) mem_flush;
880 /* open_internal4()-- Returns a stream structure from a character(kind=4)
884 open_internal4 (char *base, int length, gfc_offset offset)
888 s = get_mem (sizeof (unix_stream));
889 memset (s, '\0', sizeof (unix_stream));
892 s->buffer_offset = offset;
894 s->logical_offset = 0;
895 s->active = s->file_length = length;
897 s->st.close = (void *) mem_close;
898 s->st.seek = (void *) mem_seek;
899 s->st.tell = (void *) mem_tell;
900 s->st.trunc = (void *) mem_truncate;
901 s->st.read = (void *) mem_read4;
902 s->st.write = (void *) mem_write4;
903 s->st.flush = (void *) mem_flush;
909 /* fd_to_stream()-- Given an open file descriptor, build a stream
913 fd_to_stream (int fd, int prot)
918 s = get_mem (sizeof (unix_stream));
919 memset (s, '\0', sizeof (unix_stream));
922 s->buffer_offset = 0;
923 s->physical_offset = 0;
924 s->logical_offset = 0;
927 /* Get the current length of the file. */
929 fstat (fd, &statbuf);
931 if (lseek (fd, 0, SEEK_CUR) == (gfc_offset) -1)
934 s->file_length = S_ISREG (statbuf.st_mode) ? statbuf.st_size : -1;
936 s->special_file = !S_ISREG (statbuf.st_mode);
938 if (isatty (s->fd) || options.all_unbuffered
939 ||(options.unbuffered_preconnected &&
940 (s->fd == STDIN_FILENO
941 || s->fd == STDOUT_FILENO
942 || s->fd == STDERR_FILENO)))
951 /* Given the Fortran unit number, convert it to a C file descriptor. */
954 unit_to_fd (int unit)
959 us = find_unit (unit);
963 fd = ((unix_stream *) us->s)->fd;
969 /* unpack_filename()-- Given a fortran string and a pointer to a
970 * buffer that is PATH_MAX characters, convert the fortran string to a
971 * C string in the buffer. Returns nonzero if this is not possible. */
974 unpack_filename (char *cstring, const char *fstring, int len)
976 len = fstrlen (fstring, len);
980 memmove (cstring, fstring, len);
987 /* tempfile()-- Generate a temporary filename for a scratch file and
988 * open it. mkstemp() opens the file for reading and writing, but the
989 * library mode prevents anything that is not allowed. The descriptor
990 * is returned, which is -1 on error. The template is pointed to by
991 * opp->file, which is copied into the unit structure
992 * and freed later. */
995 tempfile (st_parameter_open *opp)
999 const char *slash = "/";
1002 tempdir = getenv ("GFORTRAN_TMPDIR");
1004 if (tempdir == NULL)
1006 char buffer[MAX_PATH + 1];
1008 ret = GetTempPath (MAX_PATH, buffer);
1009 /* If we are not able to get a temp-directory, we use
1010 current directory. */
1011 if (ret > MAX_PATH || !ret)
1015 tempdir = strdup (buffer);
1018 if (tempdir == NULL)
1019 tempdir = getenv ("TMP");
1020 if (tempdir == NULL)
1021 tempdir = getenv ("TEMP");
1022 if (tempdir == NULL)
1023 tempdir = DEFAULT_TEMPDIR;
1025 /* Check for special case that tempdir contains slash
1026 or backslash at end. */
1027 if (*tempdir == 0 || tempdir[strlen (tempdir) - 1] == '/'
1029 || tempdir[strlen (tempdir) - 1] == '\\'
1034 template = get_mem (strlen (tempdir) + 20);
1037 sprintf (template, "%s%sgfortrantmpXXXXXX", tempdir, slash);
1039 fd = mkstemp (template);
1041 #else /* HAVE_MKSTEMP */
1045 sprintf (template, "%s%sgfortrantmpXXXXXX", tempdir, slash);
1046 if (!mktemp (template))
1048 #if defined(HAVE_CRLF) && defined(O_BINARY)
1049 fd = open (template, O_RDWR | O_CREAT | O_EXCL | O_BINARY,
1050 S_IREAD | S_IWRITE);
1052 fd = open (template, O_RDWR | O_CREAT | O_EXCL, S_IREAD | S_IWRITE);
1055 while (fd == -1 && errno == EEXIST);
1056 #endif /* HAVE_MKSTEMP */
1062 opp->file = template;
1063 opp->file_len = strlen (template); /* Don't include trailing nul */
1070 /* regular_file()-- Open a regular file.
1071 * Change flags->action if it is ACTION_UNSPECIFIED on entry,
1072 * unless an error occurs.
1073 * Returns the descriptor, which is less than zero on error. */
1076 regular_file (st_parameter_open *opp, unit_flags *flags)
1078 char path[PATH_MAX + 1];
1084 if (unpack_filename (path, opp->file, opp->file_len))
1086 errno = ENOENT; /* Fake an OS error */
1091 if (opp->file_len == 7)
1093 if (strncmp (path, "CONOUT$", 7) == 0
1094 || strncmp (path, "CONERR$", 7) == 0)
1096 fd = open ("/dev/conout", O_WRONLY);
1097 flags->action = ACTION_WRITE;
1102 if (opp->file_len == 6 && strncmp (path, "CONIN$", 6) == 0)
1104 fd = open ("/dev/conin", O_RDONLY);
1105 flags->action = ACTION_READ;
1112 if (opp->file_len == 7)
1114 if (strncmp (path, "CONOUT$", 7) == 0
1115 || strncmp (path, "CONERR$", 7) == 0)
1117 fd = open ("CONOUT$", O_WRONLY);
1118 flags->action = ACTION_WRITE;
1123 if (opp->file_len == 6 && strncmp (path, "CONIN$", 6) == 0)
1125 fd = open ("CONIN$", O_RDONLY);
1126 flags->action = ACTION_READ;
1133 switch (flags->action)
1143 case ACTION_READWRITE:
1144 case ACTION_UNSPECIFIED:
1149 internal_error (&opp->common, "regular_file(): Bad action");
1152 switch (flags->status)
1155 crflag = O_CREAT | O_EXCL;
1158 case STATUS_OLD: /* open will fail if the file does not exist*/
1162 case STATUS_UNKNOWN:
1163 case STATUS_SCRATCH:
1167 case STATUS_REPLACE:
1168 crflag = O_CREAT | O_TRUNC;
1172 internal_error (&opp->common, "regular_file(): Bad status");
1175 /* rwflag |= O_LARGEFILE; */
1177 #if defined(HAVE_CRLF) && defined(O_BINARY)
1181 mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
1182 fd = open (path, rwflag | crflag, mode);
1183 if (flags->action != ACTION_UNSPECIFIED)
1188 flags->action = ACTION_READWRITE;
1191 if (errno != EACCES && errno != EROFS)
1194 /* retry for read-only access */
1196 fd = open (path, rwflag | crflag, mode);
1199 flags->action = ACTION_READ;
1200 return fd; /* success */
1203 if (errno != EACCES)
1204 return fd; /* failure */
1206 /* retry for write-only access */
1208 fd = open (path, rwflag | crflag, mode);
1211 flags->action = ACTION_WRITE;
1212 return fd; /* success */
1214 return fd; /* failure */
1218 /* open_external()-- Open an external file, unix specific version.
1219 * Change flags->action if it is ACTION_UNSPECIFIED on entry.
1220 * Returns NULL on operating system error. */
1223 open_external (st_parameter_open *opp, unit_flags *flags)
1227 if (flags->status == STATUS_SCRATCH)
1229 fd = tempfile (opp);
1230 if (flags->action == ACTION_UNSPECIFIED)
1231 flags->action = ACTION_READWRITE;
1233 #if HAVE_UNLINK_OPEN_FILE
1234 /* We can unlink scratch files now and it will go away when closed. */
1241 /* regular_file resets flags->action if it is ACTION_UNSPECIFIED and
1243 fd = regular_file (opp, flags);
1250 switch (flags->action)
1260 case ACTION_READWRITE:
1261 prot = PROT_READ | PROT_WRITE;
1265 internal_error (&opp->common, "open_external(): Bad action");
1268 return fd_to_stream (fd, prot);
1272 /* input_stream()-- Return a stream pointer to the default input stream.
1273 * Called on initialization. */
1278 return fd_to_stream (STDIN_FILENO, PROT_READ);
1282 /* output_stream()-- Return a stream pointer to the default output stream.
1283 * Called on initialization. */
1286 output_stream (void)
1290 #if defined(HAVE_CRLF) && defined(HAVE_SETMODE)
1291 setmode (STDOUT_FILENO, O_BINARY);
1294 s = fd_to_stream (STDOUT_FILENO, PROT_WRITE);
1299 /* error_stream()-- Return a stream pointer to the default error stream.
1300 * Called on initialization. */
1307 #if defined(HAVE_CRLF) && defined(HAVE_SETMODE)
1308 setmode (STDERR_FILENO, O_BINARY);
1311 s = fd_to_stream (STDERR_FILENO, PROT_WRITE);
1316 /* st_vprintf()-- vprintf function for error output. To avoid buffer
1317 overruns, we limit the length of the buffer to ST_VPRINTF_SIZE. 2k
1318 is big enough to completely fill a 80x25 terminal, so it shuld be
1319 OK. We use a direct write() because it is simpler and least likely
1320 to be clobbered by memory corruption. Writing an error message
1321 longer than that is an error. */
1323 #define ST_VPRINTF_SIZE 2048
1326 st_vprintf (const char *format, va_list ap)
1328 static char buffer[ST_VPRINTF_SIZE];
1332 fd = options.use_stderr ? STDERR_FILENO : STDOUT_FILENO;
1333 #ifdef HAVE_VSNPRINTF
1334 written = vsnprintf(buffer, ST_VPRINTF_SIZE, format, ap);
1336 written = vsprintf(buffer, format, ap);
1338 if (written >= ST_VPRINTF_SIZE-1)
1340 /* The error message was longer than our buffer. Ouch. Because
1341 we may have messed up things badly, report the error and
1343 #define ERROR_MESSAGE "Internal error: buffer overrun in st_vprintf()\n"
1344 write (fd, buffer, ST_VPRINTF_SIZE-1);
1345 write (fd, ERROR_MESSAGE, strlen(ERROR_MESSAGE));
1347 #undef ERROR_MESSAGE
1352 written = write (fd, buffer, written);
1356 /* st_printf()-- printf() function for error output. This just calls
1357 st_vprintf() to do the actual work. */
1360 st_printf (const char *format, ...)
1364 va_start (ap, format);
1365 written = st_vprintf(format, ap);
1371 /* compare_file_filename()-- Given an open stream and a fortran string
1372 * that is a filename, figure out if the file is the same as the
1376 compare_file_filename (gfc_unit *u, const char *name, int len)
1378 char path[PATH_MAX + 1];
1380 #ifdef HAVE_WORKING_STAT
1388 if (unpack_filename (path, name, len))
1389 return 0; /* Can't be the same */
1391 /* If the filename doesn't exist, then there is no match with the
1394 if (stat (path, &st1) < 0)
1397 #ifdef HAVE_WORKING_STAT
1398 fstat (((unix_stream *) (u->s))->fd, &st2);
1399 return (st1.st_dev == st2.st_dev) && (st1.st_ino == st2.st_ino);
1403 /* We try to match files by a unique ID. On some filesystems (network
1404 fs and FAT), we can't generate this unique ID, and will simply compare
1406 id1 = id_from_path (path);
1407 id2 = id_from_fd (((unix_stream *) (u->s))->fd);
1409 return (id1 == id2);
1412 if (len != u->file_len)
1414 return (memcmp(path, u->file, len) == 0);
1419 #ifdef HAVE_WORKING_STAT
1420 # define FIND_FILE0_DECL gfstat_t *st
1421 # define FIND_FILE0_ARGS st
1423 # define FIND_FILE0_DECL uint64_t id, const char *file, gfc_charlen_type file_len
1424 # define FIND_FILE0_ARGS id, file, file_len
1427 /* find_file0()-- Recursive work function for find_file() */
1430 find_file0 (gfc_unit *u, FIND_FILE0_DECL)
1433 #if defined(__MINGW32__) && !HAVE_WORKING_STAT
1440 #ifdef HAVE_WORKING_STAT
1442 && fstat (((unix_stream *) u->s)->fd, &st[1]) >= 0 &&
1443 st[0].st_dev == st[1].st_dev && st[0].st_ino == st[1].st_ino)
1447 if (u->s && ((id1 = id_from_fd (((unix_stream *) u->s)->fd)) || id1))
1454 if (compare_string (u->file_len, u->file, file_len, file) == 0)
1458 v = find_file0 (u->left, FIND_FILE0_ARGS);
1462 v = find_file0 (u->right, FIND_FILE0_ARGS);
1470 /* find_file()-- Take the current filename and see if there is a unit
1471 * that has the file already open. Returns a pointer to the unit if so. */
1474 find_file (const char *file, gfc_charlen_type file_len)
1476 char path[PATH_MAX + 1];
1479 #if defined(__MINGW32__) && !HAVE_WORKING_STAT
1483 if (unpack_filename (path, file, file_len))
1486 if (stat (path, &st[0]) < 0)
1489 #if defined(__MINGW32__) && !HAVE_WORKING_STAT
1490 id = id_from_path (path);
1493 __gthread_mutex_lock (&unit_lock);
1495 u = find_file0 (unit_root, FIND_FILE0_ARGS);
1499 if (! __gthread_mutex_trylock (&u->lock))
1501 /* assert (u->closed == 0); */
1502 __gthread_mutex_unlock (&unit_lock);
1506 inc_waiting_locked (u);
1508 __gthread_mutex_unlock (&unit_lock);
1511 __gthread_mutex_lock (&u->lock);
1514 __gthread_mutex_lock (&unit_lock);
1515 __gthread_mutex_unlock (&u->lock);
1516 if (predec_waiting_locked (u) == 0)
1521 dec_waiting_unlocked (u);
1527 flush_all_units_1 (gfc_unit *u, int min_unit)
1531 if (u->unit_number > min_unit)
1533 gfc_unit *r = flush_all_units_1 (u->left, min_unit);
1537 if (u->unit_number >= min_unit)
1539 if (__gthread_mutex_trylock (&u->lock))
1543 __gthread_mutex_unlock (&u->lock);
1551 flush_all_units (void)
1556 __gthread_mutex_lock (&unit_lock);
1559 u = flush_all_units_1 (unit_root, min_unit);
1561 inc_waiting_locked (u);
1562 __gthread_mutex_unlock (&unit_lock);
1566 __gthread_mutex_lock (&u->lock);
1568 min_unit = u->unit_number + 1;
1573 __gthread_mutex_lock (&unit_lock);
1574 __gthread_mutex_unlock (&u->lock);
1575 (void) predec_waiting_locked (u);
1579 __gthread_mutex_lock (&unit_lock);
1580 __gthread_mutex_unlock (&u->lock);
1581 if (predec_waiting_locked (u) == 0)
1589 /* delete_file()-- Given a unit structure, delete the file associated
1590 * with the unit. Returns nonzero if something went wrong. */
1593 delete_file (gfc_unit * u)
1595 char path[PATH_MAX + 1];
1597 if (unpack_filename (path, u->file, u->file_len))
1598 { /* Shouldn't be possible */
1603 return unlink (path);
1607 /* file_exists()-- Returns nonzero if the current filename exists on
1611 file_exists (const char *file, gfc_charlen_type file_len)
1613 char path[PATH_MAX + 1];
1615 if (unpack_filename (path, file, file_len))
1618 return !(access (path, F_OK));
1622 /* file_size()-- Returns the size of the file. */
1625 file_size (const char *file, gfc_charlen_type file_len)
1627 char path[PATH_MAX + 1];
1630 if (unpack_filename (path, file, file_len))
1633 if (stat (path, &statbuf) < 0)
1636 return (GFC_IO_INT) statbuf.st_size;
1639 static const char yes[] = "YES", no[] = "NO", unknown[] = "UNKNOWN";
1641 /* inquire_sequential()-- Given a fortran string, determine if the
1642 * file is suitable for sequential access. Returns a C-style
1646 inquire_sequential (const char *string, int len)
1648 char path[PATH_MAX + 1];
1651 if (string == NULL ||
1652 unpack_filename (path, string, len) || stat (path, &statbuf) < 0)
1655 if (S_ISREG (statbuf.st_mode) ||
1656 S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode))
1659 if (S_ISDIR (statbuf.st_mode) || S_ISBLK (statbuf.st_mode))
1666 /* inquire_direct()-- Given a fortran string, determine if the file is
1667 * suitable for direct access. Returns a C-style string. */
1670 inquire_direct (const char *string, int len)
1672 char path[PATH_MAX + 1];
1675 if (string == NULL ||
1676 unpack_filename (path, string, len) || stat (path, &statbuf) < 0)
1679 if (S_ISREG (statbuf.st_mode) || S_ISBLK (statbuf.st_mode))
1682 if (S_ISDIR (statbuf.st_mode) ||
1683 S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode))
1690 /* inquire_formatted()-- Given a fortran string, determine if the file
1691 * is suitable for formatted form. Returns a C-style string. */
1694 inquire_formatted (const char *string, int len)
1696 char path[PATH_MAX + 1];
1699 if (string == NULL ||
1700 unpack_filename (path, string, len) || stat (path, &statbuf) < 0)
1703 if (S_ISREG (statbuf.st_mode) ||
1704 S_ISBLK (statbuf.st_mode) ||
1705 S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode))
1708 if (S_ISDIR (statbuf.st_mode))
1715 /* inquire_unformatted()-- Given a fortran string, determine if the file
1716 * is suitable for unformatted form. Returns a C-style string. */
1719 inquire_unformatted (const char *string, int len)
1721 return inquire_formatted (string, len);
1725 /* inquire_access()-- Given a fortran string, determine if the file is
1726 * suitable for access. */
1729 inquire_access (const char *string, int len, int mode)
1731 char path[PATH_MAX + 1];
1733 if (string == NULL || unpack_filename (path, string, len) ||
1734 access (path, mode) < 0)
1741 /* inquire_read()-- Given a fortran string, determine if the file is
1742 * suitable for READ access. */
1745 inquire_read (const char *string, int len)
1747 return inquire_access (string, len, R_OK);
1751 /* inquire_write()-- Given a fortran string, determine if the file is
1752 * suitable for READ access. */
1755 inquire_write (const char *string, int len)
1757 return inquire_access (string, len, W_OK);
1761 /* inquire_readwrite()-- Given a fortran string, determine if the file is
1762 * suitable for read and write access. */
1765 inquire_readwrite (const char *string, int len)
1767 return inquire_access (string, len, R_OK | W_OK);
1771 /* file_length()-- Return the file length in bytes, -1 if unknown */
1774 file_length (stream * s)
1776 gfc_offset curr, end;
1777 if (!is_seekable (s))
1782 end = sseek (s, 0, SEEK_END);
1783 sseek (s, curr, SEEK_SET);
1788 /* is_seekable()-- Return nonzero if the stream is seekable, zero if
1792 is_seekable (stream *s)
1794 /* By convention, if file_length == -1, the file is not
1796 return ((unix_stream *) s)->file_length!=-1;
1800 /* is_special()-- Return nonzero if the stream is not a regular file. */
1803 is_special (stream *s)
1805 return ((unix_stream *) s)->special_file;
1810 stream_isatty (stream *s)
1812 return isatty (((unix_stream *) s)->fd);
1816 stream_ttyname (stream *s __attribute__ ((unused)))
1819 return ttyname (((unix_stream *) s)->fd);
1826 /* How files are stored: This is an operating-system specific issue,
1827 and therefore belongs here. There are three cases to consider.
1830 Records are written as block of bytes corresponding to the record
1831 length of the file. This goes for both formatted and unformatted
1832 records. Positioning is done explicitly for each data transfer,
1833 so positioning is not much of an issue.
1835 Sequential Formatted:
1836 Records are separated by newline characters. The newline character
1837 is prohibited from appearing in a string. If it does, this will be
1838 messed up on the next read. End of file is also the end of a record.
1840 Sequential Unformatted:
1841 In this case, we are merely copying bytes to and from main storage,
1842 yet we need to keep track of varying record lengths. We adopt
1843 the solution used by f2c. Each record contains a pair of length
1846 Length of record n in bytes
1848 Length of record n in bytes
1850 Length of record n+1 in bytes
1852 Length of record n+1 in bytes
1854 The length is stored at the end of a record to allow backspacing to the
1855 previous record. Between data transfer statements, the file pointer
1856 is left pointing to the first length of the current record.
1858 ENDFILE records are never explicitly stored.