2005-07-12 Thomas Koenig <Thomas.Koenig@online.de>
[official-gcc.git] / libgfortran / io / unix.c
blobb35182d61696d89c9fde77a466762e9d9f4669a9
1 /* Copyright (C) 2002, 2003, 2004, 2005
2 Free Software Foundation, Inc.
3 Contributed by Andy Vaught
5 This file is part of the GNU Fortran 95 runtime library (libgfortran).
7 Libgfortran is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
12 In addition to the permissions in the GNU General Public License, the
13 Free Software Foundation gives you unlimited permission to link the
14 compiled version of this file into combinations with other programs,
15 and to distribute those combinations without any restriction coming
16 from the use of this file. (The General Public License restrictions
17 do apply in other respects; for example, they cover modification of
18 the file, and distribution when not linked into a combine
19 executable.)
21 Libgfortran is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 GNU General Public License for more details.
26 You should have received a copy of the GNU General Public License
27 along with Libgfortran; see the file COPYING. If not, write to
28 the Free Software Foundation, 59 Temple Place - Suite 330,
29 Boston, MA 02111-1307, USA. */
31 /* Unix stream I/O module */
33 #include "config.h"
34 #include <stdlib.h>
35 #include <limits.h>
37 #include <unistd.h>
38 #include <stdio.h>
39 #include <sys/stat.h>
40 #include <fcntl.h>
42 #ifdef HAVE_SYS_MMAN_H
43 #include <sys/mman.h>
44 #endif
45 #include <string.h>
46 #include <errno.h>
48 #include "libgfortran.h"
49 #include "io.h"
51 #ifndef PATH_MAX
52 #define PATH_MAX 1024
53 #endif
55 #ifndef MAP_FAILED
56 #define MAP_FAILED ((void *) -1)
57 #endif
59 #ifndef PROT_READ
60 #define PROT_READ 1
61 #endif
63 #ifndef PROT_WRITE
64 #define PROT_WRITE 2
65 #endif
67 /* These flags aren't defined on all targets (mingw32), so provide them
68 here. */
69 #ifndef S_IRGRP
70 #define S_IRGRP 0
71 #endif
73 #ifndef S_IWGRP
74 #define S_IWGRP 0
75 #endif
77 #ifndef S_IROTH
78 #define S_IROTH 0
79 #endif
81 #ifndef S_IWOTH
82 #define S_IWOTH 0
83 #endif
85 /* This implementation of stream I/O is based on the paper:
87 * "Exploiting the advantages of mapped files for stream I/O",
88 * O. Krieger, M. Stumm and R. Umrau, "Proceedings of the 1992 Winter
89 * USENIX conference", p. 27-42.
91 * It differs in a number of ways from the version described in the
92 * paper. First of all, threads are not an issue during I/O and we
93 * also don't have to worry about having multiple regions, since
94 * fortran's I/O model only allows you to be one place at a time.
96 * On the other hand, we have to be able to writing at the end of a
97 * stream, read from the start of a stream or read and write blocks of
98 * bytes from an arbitrary position. After opening a file, a pointer
99 * to a stream structure is returned, which is used to handle file
100 * accesses until the file is closed.
102 * salloc_at_r(stream, len, where)-- Given a stream pointer, return a
103 * pointer to a block of memory that mirror the file at position
104 * 'where' that is 'len' bytes long. The len integer is updated to
105 * reflect how many bytes were actually read. The only reason for a
106 * short read is end of file. The file pointer is updated. The
107 * pointer is valid until the next call to salloc_*.
109 * salloc_at_w(stream, len, where)-- Given the stream pointer, returns
110 * a pointer to a block of memory that is updated to reflect the state
111 * of the file. The length of the buffer is always equal to that
112 * requested. The buffer must be completely set by the caller. When
113 * data has been written, the sfree() function must be called to
114 * indicate that the caller is done writing data to the buffer. This
115 * may or may not cause a physical write.
117 * Short forms of these are salloc_r() and salloc_w() which drop the
118 * 'where' parameter and use the current file pointer. */
121 #define BUFFER_SIZE 8192
123 typedef struct
125 stream st;
127 int fd;
128 gfc_offset buffer_offset; /* File offset of the start of the buffer */
129 gfc_offset physical_offset; /* Current physical file offset */
130 gfc_offset logical_offset; /* Current logical file offset */
131 gfc_offset dirty_offset; /* Start of modified bytes in buffer */
132 gfc_offset file_length; /* Length of the file, -1 if not seekable. */
134 char *buffer;
135 int len; /* Physical length of the current buffer */
136 int active; /* Length of valid bytes in the buffer */
138 int prot;
139 int ndirty; /* Dirty bytes starting at dirty_offset */
141 int special_file; /* =1 if the fd refers to a special file */
143 unsigned unbuffered:1, mmaped:1;
145 char small_buffer[BUFFER_SIZE];
148 unix_stream;
150 /*move_pos_offset()-- Move the record pointer right or left
151 *relative to current position */
154 move_pos_offset (stream* st, int pos_off)
156 unix_stream * str = (unix_stream*)st;
157 if (pos_off < 0)
159 str->logical_offset += pos_off;
161 if (str->dirty_offset + str->ndirty > str->logical_offset)
163 if (str->ndirty + pos_off > 0)
164 str->ndirty += pos_off;
165 else
167 str->dirty_offset += pos_off + pos_off;
168 str->ndirty = 0;
172 return pos_off;
174 return 0;
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. */
185 static int
186 fix_fd (int fd)
188 int input, output, error;
190 input = output = error = 0;
192 /* Unix allocates the lowest descriptors first, so a loop is not
193 required, but this order is. */
195 if (fd == STDIN_FILENO)
197 fd = dup (fd);
198 input = 1;
200 if (fd == STDOUT_FILENO)
202 fd = dup (fd);
203 output = 1;
205 if (fd == STDERR_FILENO)
207 fd = dup (fd);
208 error = 1;
211 if (input)
212 close (STDIN_FILENO);
213 if (output)
214 close (STDOUT_FILENO);
215 if (error)
216 close (STDERR_FILENO);
218 return fd;
222 /* write()-- Write a buffer to a descriptor, allowing for short writes */
224 static int
225 writen (int fd, char *buffer, int len)
227 int n, n0;
229 n0 = len;
231 while (len > 0)
233 n = write (fd, buffer, len);
234 if (n < 0)
235 return n;
237 buffer += n;
238 len -= n;
241 return n0;
245 #if 0
246 /* readn()-- Read bytes into a buffer, allowing for short reads. If
247 * fewer than len bytes are returned, it is because we've hit the end
248 * of file. */
250 static int
251 readn (int fd, char *buffer, int len)
253 int nread, n;
255 nread = 0;
257 while (len > 0)
259 n = read (fd, buffer, len);
260 if (n < 0)
261 return n;
263 if (n == 0)
264 return nread;
266 buffer += n;
267 nread += n;
268 len -= n;
271 return nread;
273 #endif
276 /* get_oserror()-- Get the most recent operating system error. For
277 * unix, this is errno. */
279 const char *
280 get_oserror (void)
282 return strerror (errno);
286 /* sys_exit()-- Terminate the program with an exit code */
288 void
289 sys_exit (int code)
291 exit (code);
295 /*********************************************************************
296 File descriptor stream functions
297 *********************************************************************/
299 /* fd_flush()-- Write bytes that need to be written */
301 static try
302 fd_flush (unix_stream * s)
304 if (s->ndirty == 0)
305 return SUCCESS;;
307 if (s->physical_offset != s->dirty_offset &&
308 lseek (s->fd, s->dirty_offset, SEEK_SET) < 0)
309 return FAILURE;
311 if (writen (s->fd, s->buffer + (s->dirty_offset - s->buffer_offset),
312 s->ndirty) < 0)
313 return FAILURE;
315 s->physical_offset = s->dirty_offset + s->ndirty;
317 /* don't increment file_length if the file is non-seekable */
318 if (s->file_length != -1 && s->physical_offset > s->file_length)
319 s->file_length = s->physical_offset;
320 s->ndirty = 0;
322 return SUCCESS;
326 /* fd_alloc()-- Arrange a buffer such that the salloc() request can be
327 * satisfied. This subroutine gets the buffer ready for whatever is
328 * to come next. */
330 static void
331 fd_alloc (unix_stream * s, gfc_offset where,
332 int *len __attribute__ ((unused)))
334 char *new_buffer;
335 int n, read_len;
337 if (*len <= BUFFER_SIZE)
339 new_buffer = s->small_buffer;
340 read_len = BUFFER_SIZE;
342 else
344 new_buffer = get_mem (*len);
345 read_len = *len;
348 /* Salvage bytes currently within the buffer. This is important for
349 * devices that cannot seek. */
351 if (s->buffer != NULL && s->buffer_offset <= where &&
352 where <= s->buffer_offset + s->active)
355 n = s->active - (where - s->buffer_offset);
356 memmove (new_buffer, s->buffer + (where - s->buffer_offset), n);
358 s->active = n;
360 else
361 { /* new buffer starts off empty */
362 s->active = 0;
365 s->buffer_offset = where;
367 /* free the old buffer if necessary */
369 if (s->buffer != NULL && s->buffer != s->small_buffer)
370 free_mem (s->buffer);
372 s->buffer = new_buffer;
373 s->len = read_len;
374 s->mmaped = 0;
378 /* fd_alloc_r_at()-- Allocate a stream buffer for reading. Either
379 * we've already buffered the data or we need to load it. Returns
380 * NULL on I/O error. */
382 static char *
383 fd_alloc_r_at (unix_stream * s, int *len, gfc_offset where)
385 gfc_offset m;
386 int n;
388 if (where == -1)
389 where = s->logical_offset;
391 if (s->buffer != NULL && s->buffer_offset <= where &&
392 where + *len <= s->buffer_offset + s->active)
395 /* Return a position within the current buffer */
397 s->logical_offset = where + *len;
398 return s->buffer + where - s->buffer_offset;
401 fd_alloc (s, where, len);
403 m = where + s->active;
405 if (s->physical_offset != m && lseek (s->fd, m, SEEK_SET) < 0)
406 return NULL;
408 n = read (s->fd, s->buffer + s->active, s->len - s->active);
409 if (n < 0)
410 return NULL;
412 s->physical_offset = where + n;
414 s->active += n;
415 if (s->active < *len)
416 *len = s->active; /* Bytes actually available */
418 s->logical_offset = where + *len;
420 return s->buffer;
424 /* fd_alloc_w_at()-- Allocate a stream buffer for writing. Either
425 * we've already buffered the data or we need to load it. */
427 static char *
428 fd_alloc_w_at (unix_stream * s, int *len, gfc_offset where)
430 gfc_offset n;
432 if (where == -1)
433 where = s->logical_offset;
435 if (s->buffer == NULL || s->buffer_offset > where ||
436 where + *len > s->buffer_offset + s->len)
439 if (fd_flush (s) == FAILURE)
440 return NULL;
441 fd_alloc (s, where, len);
444 /* Return a position within the current buffer */
445 if (s->ndirty == 0
446 || where > s->dirty_offset + s->ndirty
447 || s->dirty_offset > where + *len)
448 { /* Discontiguous blocks, start with a clean buffer. */
449 /* Flush the buffer. */
450 if (s->ndirty != 0)
451 fd_flush (s);
452 s->dirty_offset = where;
453 s->ndirty = *len;
455 else
457 gfc_offset start; /* Merge with the existing data. */
458 if (where < s->dirty_offset)
459 start = where;
460 else
461 start = s->dirty_offset;
462 if (where + *len > s->dirty_offset + s->ndirty)
463 s->ndirty = where + *len - start;
464 else
465 s->ndirty = s->dirty_offset + s->ndirty - start;
466 s->dirty_offset = start;
469 s->logical_offset = where + *len;
471 if (where + *len > s->file_length)
472 s->file_length = where + *len;
474 n = s->logical_offset - s->buffer_offset;
475 if (n > s->active)
476 s->active = n;
478 return s->buffer + where - s->buffer_offset;
482 static try
483 fd_sfree (unix_stream * s)
485 if (s->ndirty != 0 &&
486 (s->buffer != s->small_buffer || options.all_unbuffered ||
487 s->unbuffered))
488 return fd_flush (s);
490 return SUCCESS;
494 static int
495 fd_seek (unix_stream * s, gfc_offset offset)
497 s->physical_offset = s->logical_offset = offset;
499 return (lseek (s->fd, offset, SEEK_SET) < 0) ? FAILURE : SUCCESS;
503 /* truncate_file()-- Given a unit, truncate the file at the current
504 * position. Sets the physical location to the new end of the file.
505 * Returns nonzero on error. */
507 static try
508 fd_truncate (unix_stream * s)
510 if (lseek (s->fd, s->logical_offset, SEEK_SET) == -1)
511 return FAILURE;
513 /* non-seekable files, like terminals and fifo's fail the lseek.
514 Using ftruncate on a seekable special file (like /dev/null)
515 is undefined, so we treat it as if the ftruncate failed.
517 #ifdef HAVE_FTRUNCATE
518 if (s->special_file || ftruncate (s->fd, s->logical_offset))
519 #else
520 #ifdef HAVE_CHSIZE
521 if (s->special_file || chsize (s->fd, s->logical_offset))
522 #endif
523 #endif
525 s->physical_offset = s->file_length = 0;
526 return FAILURE;
529 s->physical_offset = s->file_length = s->logical_offset;
531 return SUCCESS;
535 static try
536 fd_close (unix_stream * s)
538 if (fd_flush (s) == FAILURE)
539 return FAILURE;
541 if (s->buffer != NULL && s->buffer != s->small_buffer)
542 free_mem (s->buffer);
544 if (s->fd != STDOUT_FILENO && s->fd != STDERR_FILENO)
546 if (close (s->fd) < 0)
547 return FAILURE;
550 free_mem (s);
552 return SUCCESS;
556 static void
557 fd_open (unix_stream * s)
559 if (isatty (s->fd))
560 s->unbuffered = 1;
562 s->st.alloc_r_at = (void *) fd_alloc_r_at;
563 s->st.alloc_w_at = (void *) fd_alloc_w_at;
564 s->st.sfree = (void *) fd_sfree;
565 s->st.close = (void *) fd_close;
566 s->st.seek = (void *) fd_seek;
567 s->st.truncate = (void *) fd_truncate;
569 s->buffer = NULL;
573 /*********************************************************************
574 mmap stream functions
576 Because mmap() is not capable of extending a file, we have to keep
577 track of how long the file is. We also have to be able to detect end
578 of file conditions. If there are multiple writers to the file (which
579 can only happen outside the current program), things will get
580 confused. Then again, things will get confused anyway.
582 *********************************************************************/
584 #if HAVE_MMAP
586 static int page_size, page_mask;
588 /* mmap_flush()-- Deletes a memory mapping if something is mapped. */
590 static try
591 mmap_flush (unix_stream * s)
593 if (!s->mmaped)
594 return fd_flush (s);
596 if (s->buffer == NULL)
597 return SUCCESS;
599 if (munmap (s->buffer, s->active))
600 return FAILURE;
602 s->buffer = NULL;
603 s->active = 0;
605 return SUCCESS;
609 /* mmap_alloc()-- mmap() a section of the file. The whole section is
610 * guaranteed to be mappable. */
612 static try
613 mmap_alloc (unix_stream * s, gfc_offset where,
614 int *len __attribute__ ((unused)))
616 gfc_offset offset;
617 int length;
618 char *p;
620 if (mmap_flush (s) == FAILURE)
621 return FAILURE;
623 offset = where & page_mask; /* Round down to the next page */
625 length = ((where - offset) & page_mask) + 2 * page_size;
627 p = mmap (NULL, length, s->prot, MAP_SHARED, s->fd, offset);
628 if (p == (char *) MAP_FAILED)
629 return FAILURE;
631 s->mmaped = 1;
632 s->buffer = p;
633 s->buffer_offset = offset;
634 s->active = length;
636 return SUCCESS;
640 static char *
641 mmap_alloc_r_at (unix_stream * s, int *len, gfc_offset where)
643 gfc_offset m;
645 if (where == -1)
646 where = s->logical_offset;
648 m = where + *len;
650 if ((s->buffer == NULL || s->buffer_offset > where ||
651 m > s->buffer_offset + s->active) &&
652 mmap_alloc (s, where, len) == FAILURE)
653 return NULL;
655 if (m > s->file_length)
657 *len = s->file_length - s->logical_offset;
658 s->logical_offset = s->file_length;
660 else
661 s->logical_offset = m;
663 return s->buffer + (where - s->buffer_offset);
667 static char *
668 mmap_alloc_w_at (unix_stream * s, int *len, gfc_offset where)
670 if (where == -1)
671 where = s->logical_offset;
673 /* If we're extending the file, we have to use file descriptor
674 * methods. */
676 if (where + *len > s->file_length)
678 if (s->mmaped)
679 mmap_flush (s);
680 return fd_alloc_w_at (s, len, where);
683 if ((s->buffer == NULL || s->buffer_offset > where ||
684 where + *len > s->buffer_offset + s->active ||
685 where < s->buffer_offset + s->active) &&
686 mmap_alloc (s, where, len) == FAILURE)
687 return NULL;
689 s->logical_offset = where + *len;
691 return s->buffer + where - s->buffer_offset;
695 static int
696 mmap_seek (unix_stream * s, gfc_offset offset)
698 s->logical_offset = offset;
699 return SUCCESS;
703 static try
704 mmap_close (unix_stream * s)
706 try t;
708 t = mmap_flush (s);
710 if (close (s->fd) < 0)
711 t = FAILURE;
712 free_mem (s);
714 return t;
718 static try
719 mmap_sfree (unix_stream * s __attribute__ ((unused)))
721 return SUCCESS;
725 /* mmap_open()-- mmap_specific open. If the particular file cannot be
726 * mmap()-ed, we fall back to the file descriptor functions. */
728 static try
729 mmap_open (unix_stream * s __attribute__ ((unused)))
731 char *p;
732 int i;
734 page_size = getpagesize ();
735 page_mask = ~0;
737 p = mmap (0, page_size, s->prot, MAP_SHARED, s->fd, 0);
738 if (p == (char *) MAP_FAILED)
740 fd_open (s);
741 return SUCCESS;
744 munmap (p, page_size);
746 i = page_size >> 1;
747 while (i != 0)
749 page_mask <<= 1;
750 i >>= 1;
753 s->st.alloc_r_at = (void *) mmap_alloc_r_at;
754 s->st.alloc_w_at = (void *) mmap_alloc_w_at;
755 s->st.sfree = (void *) mmap_sfree;
756 s->st.close = (void *) mmap_close;
757 s->st.seek = (void *) mmap_seek;
758 s->st.truncate = (void *) fd_truncate;
760 if (lseek (s->fd, s->file_length, SEEK_SET) < 0)
761 return FAILURE;
763 return SUCCESS;
766 #endif
769 /*********************************************************************
770 memory stream functions - These are used for internal files
772 The idea here is that a single stream structure is created and all
773 requests must be satisfied from it. The location and size of the
774 buffer is the character variable supplied to the READ or WRITE
775 statement.
777 *********************************************************************/
780 static char *
781 mem_alloc_r_at (unix_stream * s, int *len, gfc_offset where)
783 gfc_offset n;
785 if (where == -1)
786 where = s->logical_offset;
788 if (where < s->buffer_offset || where > s->buffer_offset + s->active)
789 return NULL;
791 s->logical_offset = where + *len;
793 n = s->buffer_offset + s->active - where;
794 if (*len > n)
795 *len = n;
797 return s->buffer + (where - s->buffer_offset);
801 static char *
802 mem_alloc_w_at (unix_stream * s, int *len, gfc_offset where)
804 gfc_offset m;
806 if (where == -1)
807 where = s->logical_offset;
809 m = where + *len;
811 if (where < s->buffer_offset || m > s->buffer_offset + s->active)
812 return NULL;
814 s->logical_offset = m;
816 return s->buffer + (where - s->buffer_offset);
820 static int
821 mem_seek (unix_stream * s, gfc_offset offset)
823 if (offset > s->file_length)
825 errno = ESPIPE;
826 return FAILURE;
829 s->logical_offset = offset;
830 return SUCCESS;
834 static int
835 mem_truncate (unix_stream * s __attribute__ ((unused)))
837 return SUCCESS;
841 static try
842 mem_close (unix_stream * s)
844 free_mem (s);
846 return SUCCESS;
850 static try
851 mem_sfree (unix_stream * s __attribute__ ((unused)))
853 return SUCCESS;
858 /*********************************************************************
859 Public functions -- A reimplementation of this module needs to
860 define functional equivalents of the following.
861 *********************************************************************/
863 /* empty_internal_buffer()-- Zero the buffer of Internal file */
865 void
866 empty_internal_buffer(stream *strm)
868 unix_stream * s = (unix_stream *) strm;
869 memset(s->buffer, ' ', s->file_length);
872 /* open_internal()-- Returns a stream structure from an internal file */
874 stream *
875 open_internal (char *base, int length)
877 unix_stream *s;
879 s = get_mem (sizeof (unix_stream));
880 memset (s, '\0', sizeof (unix_stream));
882 s->buffer = base;
883 s->buffer_offset = 0;
885 s->logical_offset = 0;
886 s->active = s->file_length = length;
888 s->st.alloc_r_at = (void *) mem_alloc_r_at;
889 s->st.alloc_w_at = (void *) mem_alloc_w_at;
890 s->st.sfree = (void *) mem_sfree;
891 s->st.close = (void *) mem_close;
892 s->st.seek = (void *) mem_seek;
893 s->st.truncate = (void *) mem_truncate;
895 return (stream *) s;
899 /* fd_to_stream()-- Given an open file descriptor, build a stream
900 * around it. */
902 static stream *
903 fd_to_stream (int fd, int prot, int avoid_mmap)
905 struct stat statbuf;
906 unix_stream *s;
908 s = get_mem (sizeof (unix_stream));
909 memset (s, '\0', sizeof (unix_stream));
911 s->fd = fd;
912 s->buffer_offset = 0;
913 s->physical_offset = 0;
914 s->logical_offset = 0;
915 s->prot = prot;
917 /* Get the current length of the file. */
919 fstat (fd, &statbuf);
920 s->file_length = S_ISREG (statbuf.st_mode) ? statbuf.st_size : -1;
921 s->special_file = !S_ISREG (statbuf.st_mode);
923 #if HAVE_MMAP
924 if (avoid_mmap)
925 fd_open (s);
926 else
927 mmap_open (s);
928 #else
929 fd_open (s);
930 #endif
932 return (stream *) s;
936 /* Given the Fortran unit number, convert it to a C file descriptor. */
939 unit_to_fd(int unit)
941 gfc_unit *us;
943 us = find_unit(unit);
944 if (us == NULL)
945 return -1;
947 return ((unix_stream *) us->s)->fd;
951 /* unpack_filename()-- Given a fortran string and a pointer to a
952 * buffer that is PATH_MAX characters, convert the fortran string to a
953 * C string in the buffer. Returns nonzero if this is not possible. */
955 static int
956 unpack_filename (char *cstring, const char *fstring, int len)
958 len = fstrlen (fstring, len);
959 if (len >= PATH_MAX)
960 return 1;
962 memmove (cstring, fstring, len);
963 cstring[len] = '\0';
965 return 0;
969 /* tempfile()-- Generate a temporary filename for a scratch file and
970 * open it. mkstemp() opens the file for reading and writing, but the
971 * library mode prevents anything that is not allowed. The descriptor
972 * is returned, which is -1 on error. The template is pointed to by
973 * ioparm.file, which is copied into the unit structure
974 * and freed later. */
976 static int
977 tempfile (void)
979 const char *tempdir;
980 char *template;
981 int fd;
983 tempdir = getenv ("GFORTRAN_TMPDIR");
984 if (tempdir == NULL)
985 tempdir = getenv ("TMP");
986 if (tempdir == NULL)
987 tempdir = DEFAULT_TEMPDIR;
989 template = get_mem (strlen (tempdir) + 20);
991 st_sprintf (template, "%s/gfortrantmpXXXXXX", tempdir);
993 #ifdef HAVE_MKSTEMP
995 fd = mkstemp (template);
997 #else /* HAVE_MKSTEMP */
999 if (mktemp (template))
1001 fd = open (template, O_CREAT | O_EXCL, S_IREAD | S_IWRITE);
1002 while (!(fd == -1 && errno == EEXIST) && mktemp (template));
1003 else
1004 fd = -1;
1006 #endif /* HAVE_MKSTEMP */
1008 if (fd < 0)
1009 free_mem (template);
1010 else
1012 ioparm.file = template;
1013 ioparm.file_len = strlen (template); /* Don't include trailing nul */
1016 return fd;
1020 /* regular_file()-- Open a regular file.
1021 * Change flags->action if it is ACTION_UNSPECIFIED on entry,
1022 * unless an error occurs.
1023 * Returns the descriptor, which is less than zero on error. */
1025 static int
1026 regular_file (unit_flags *flags)
1028 char path[PATH_MAX + 1];
1029 int mode;
1030 int rwflag;
1031 int crflag;
1032 int fd;
1034 if (unpack_filename (path, ioparm.file, ioparm.file_len))
1036 errno = ENOENT; /* Fake an OS error */
1037 return -1;
1040 rwflag = 0;
1042 switch (flags->action)
1044 case ACTION_READ:
1045 rwflag = O_RDONLY;
1046 break;
1048 case ACTION_WRITE:
1049 rwflag = O_WRONLY;
1050 break;
1052 case ACTION_READWRITE:
1053 case ACTION_UNSPECIFIED:
1054 rwflag = O_RDWR;
1055 break;
1057 default:
1058 internal_error ("regular_file(): Bad action");
1061 switch (flags->status)
1063 case STATUS_NEW:
1064 crflag = O_CREAT | O_EXCL;
1065 break;
1067 case STATUS_OLD: /* open will fail if the file does not exist*/
1068 crflag = 0;
1069 break;
1071 case STATUS_UNKNOWN:
1072 case STATUS_SCRATCH:
1073 crflag = O_CREAT;
1074 break;
1076 case STATUS_REPLACE:
1077 crflag = O_CREAT | O_TRUNC;
1078 break;
1080 default:
1081 internal_error ("regular_file(): Bad status");
1084 /* rwflag |= O_LARGEFILE; */
1086 mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
1087 fd = open (path, rwflag | crflag, mode);
1088 if (flags->action != ACTION_UNSPECIFIED)
1089 return fd;
1091 if (fd >= 0)
1093 flags->action = ACTION_READWRITE;
1094 return fd;
1096 if (errno != EACCES)
1097 return fd;
1099 /* retry for read-only access */
1100 rwflag = O_RDONLY;
1101 fd = open (path, rwflag | crflag, mode);
1102 if (fd >=0)
1104 flags->action = ACTION_READ;
1105 return fd; /* success */
1108 if (errno != EACCES)
1109 return fd; /* failure */
1111 /* retry for write-only access */
1112 rwflag = O_WRONLY;
1113 fd = open (path, rwflag | crflag, mode);
1114 if (fd >=0)
1116 flags->action = ACTION_WRITE;
1117 return fd; /* success */
1119 return fd; /* failure */
1123 /* open_external()-- Open an external file, unix specific version.
1124 * Change flags->action if it is ACTION_UNSPECIFIED on entry.
1125 * Returns NULL on operating system error. */
1127 stream *
1128 open_external (unit_flags *flags)
1130 int fd, prot;
1132 if (flags->status == STATUS_SCRATCH)
1134 fd = tempfile ();
1135 if (flags->action == ACTION_UNSPECIFIED)
1136 flags->action = ACTION_READWRITE;
1137 /* We can unlink scratch files now and it will go away when closed. */
1138 unlink (ioparm.file);
1140 else
1142 /* regular_file resets flags->action if it is ACTION_UNSPECIFIED and
1143 * if it succeeds */
1144 fd = regular_file (flags);
1147 if (fd < 0)
1148 return NULL;
1149 fd = fix_fd (fd);
1151 switch (flags->action)
1153 case ACTION_READ:
1154 prot = PROT_READ;
1155 break;
1157 case ACTION_WRITE:
1158 prot = PROT_WRITE;
1159 break;
1161 case ACTION_READWRITE:
1162 prot = PROT_READ | PROT_WRITE;
1163 break;
1165 default:
1166 internal_error ("open_external(): Bad action");
1169 return fd_to_stream (fd, prot, 0);
1173 /* input_stream()-- Return a stream pointer to the default input stream.
1174 * Called on initialization. */
1176 stream *
1177 input_stream (void)
1179 return fd_to_stream (STDIN_FILENO, PROT_READ, 1);
1183 /* output_stream()-- Return a stream pointer to the default output stream.
1184 * Called on initialization. */
1186 stream *
1187 output_stream (void)
1189 return fd_to_stream (STDOUT_FILENO, PROT_WRITE, 1);
1193 /* error_stream()-- Return a stream pointer to the default error stream.
1194 * Called on initialization. */
1196 stream *
1197 error_stream (void)
1199 return fd_to_stream (STDERR_FILENO, PROT_WRITE, 1);
1202 /* init_error_stream()-- Return a pointer to the error stream. This
1203 * subroutine is called when the stream is needed, rather than at
1204 * initialization. We want to work even if memory has been seriously
1205 * corrupted. */
1207 stream *
1208 init_error_stream (void)
1210 static unix_stream error;
1212 memset (&error, '\0', sizeof (error));
1214 error.fd = options.use_stderr ? STDERR_FILENO : STDOUT_FILENO;
1216 error.st.alloc_w_at = (void *) fd_alloc_w_at;
1217 error.st.sfree = (void *) fd_sfree;
1219 error.unbuffered = 1;
1220 error.buffer = error.small_buffer;
1222 return (stream *) & error;
1226 /* compare_file_filename()-- Given an open stream and a fortran string
1227 * that is a filename, figure out if the file is the same as the
1228 * filename. */
1231 compare_file_filename (stream * s, const char *name, int len)
1233 char path[PATH_MAX + 1];
1234 struct stat st1, st2;
1236 if (unpack_filename (path, name, len))
1237 return 0; /* Can't be the same */
1239 /* If the filename doesn't exist, then there is no match with the
1240 * existing file. */
1242 if (stat (path, &st1) < 0)
1243 return 0;
1245 fstat (((unix_stream *) s)->fd, &st2);
1247 return (st1.st_dev == st2.st_dev) && (st1.st_ino == st2.st_ino);
1251 /* find_file0()-- Recursive work function for find_file() */
1253 static gfc_unit *
1254 find_file0 (gfc_unit * u, struct stat *st1)
1256 struct stat st2;
1257 gfc_unit *v;
1259 if (u == NULL)
1260 return NULL;
1262 if (fstat (((unix_stream *) u->s)->fd, &st2) >= 0 &&
1263 st1->st_dev == st2.st_dev && st1->st_ino == st2.st_ino)
1264 return u;
1266 v = find_file0 (u->left, st1);
1267 if (v != NULL)
1268 return v;
1270 v = find_file0 (u->right, st1);
1271 if (v != NULL)
1272 return v;
1274 return NULL;
1278 /* find_file()-- Take the current filename and see if there is a unit
1279 * that has the file already open. Returns a pointer to the unit if so. */
1281 gfc_unit *
1282 find_file (void)
1284 char path[PATH_MAX + 1];
1285 struct stat statbuf;
1287 if (unpack_filename (path, ioparm.file, ioparm.file_len))
1288 return NULL;
1290 if (stat (path, &statbuf) < 0)
1291 return NULL;
1293 return find_file0 (g.unit_root, &statbuf);
1297 /* stream_at_bof()-- Returns nonzero if the stream is at the beginning
1298 * of the file. */
1301 stream_at_bof (stream * s)
1303 unix_stream *us;
1305 if (!is_seekable (s))
1306 return 0;
1308 us = (unix_stream *) s;
1310 return us->logical_offset == 0;
1314 /* stream_at_eof()-- Returns nonzero if the stream is at the beginning
1315 * of the file. */
1318 stream_at_eof (stream * s)
1320 unix_stream *us;
1322 if (!is_seekable (s))
1323 return 0;
1325 us = (unix_stream *) s;
1327 return us->logical_offset == us->dirty_offset;
1331 /* delete_file()-- Given a unit structure, delete the file associated
1332 * with the unit. Returns nonzero if something went wrong. */
1335 delete_file (gfc_unit * u)
1337 char path[PATH_MAX + 1];
1339 if (unpack_filename (path, u->file, u->file_len))
1340 { /* Shouldn't be possible */
1341 errno = ENOENT;
1342 return 1;
1345 return unlink (path);
1349 /* file_exists()-- Returns nonzero if the current filename exists on
1350 * the system */
1353 file_exists (void)
1355 char path[PATH_MAX + 1];
1356 struct stat statbuf;
1358 if (unpack_filename (path, ioparm.file, ioparm.file_len))
1359 return 0;
1361 if (stat (path, &statbuf) < 0)
1362 return 0;
1364 return 1;
1369 static const char *yes = "YES", *no = "NO", *unknown = "UNKNOWN";
1371 /* inquire_sequential()-- Given a fortran string, determine if the
1372 * file is suitable for sequential access. Returns a C-style
1373 * string. */
1375 const char *
1376 inquire_sequential (const char *string, int len)
1378 char path[PATH_MAX + 1];
1379 struct stat statbuf;
1381 if (string == NULL ||
1382 unpack_filename (path, string, len) || stat (path, &statbuf) < 0)
1383 return unknown;
1385 if (S_ISREG (statbuf.st_mode) ||
1386 S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode))
1387 return yes;
1389 if (S_ISDIR (statbuf.st_mode) || S_ISBLK (statbuf.st_mode))
1390 return no;
1392 return unknown;
1396 /* inquire_direct()-- Given a fortran string, determine if the file is
1397 * suitable for direct access. Returns a C-style string. */
1399 const char *
1400 inquire_direct (const char *string, int len)
1402 char path[PATH_MAX + 1];
1403 struct stat statbuf;
1405 if (string == NULL ||
1406 unpack_filename (path, string, len) || stat (path, &statbuf) < 0)
1407 return unknown;
1409 if (S_ISREG (statbuf.st_mode) || S_ISBLK (statbuf.st_mode))
1410 return yes;
1412 if (S_ISDIR (statbuf.st_mode) ||
1413 S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode))
1414 return no;
1416 return unknown;
1420 /* inquire_formatted()-- Given a fortran string, determine if the file
1421 * is suitable for formatted form. Returns a C-style string. */
1423 const char *
1424 inquire_formatted (const char *string, int len)
1426 char path[PATH_MAX + 1];
1427 struct stat statbuf;
1429 if (string == NULL ||
1430 unpack_filename (path, string, len) || stat (path, &statbuf) < 0)
1431 return unknown;
1433 if (S_ISREG (statbuf.st_mode) ||
1434 S_ISBLK (statbuf.st_mode) ||
1435 S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode))
1436 return yes;
1438 if (S_ISDIR (statbuf.st_mode))
1439 return no;
1441 return unknown;
1445 /* inquire_unformatted()-- Given a fortran string, determine if the file
1446 * is suitable for unformatted form. Returns a C-style string. */
1448 const char *
1449 inquire_unformatted (const char *string, int len)
1451 return inquire_formatted (string, len);
1455 /* inquire_access()-- Given a fortran string, determine if the file is
1456 * suitable for access. */
1458 static const char *
1459 inquire_access (const char *string, int len, int mode)
1461 char path[PATH_MAX + 1];
1463 if (string == NULL || unpack_filename (path, string, len) ||
1464 access (path, mode) < 0)
1465 return no;
1467 return yes;
1471 /* inquire_read()-- Given a fortran string, determine if the file is
1472 * suitable for READ access. */
1474 const char *
1475 inquire_read (const char *string, int len)
1477 return inquire_access (string, len, R_OK);
1481 /* inquire_write()-- Given a fortran string, determine if the file is
1482 * suitable for READ access. */
1484 const char *
1485 inquire_write (const char *string, int len)
1487 return inquire_access (string, len, W_OK);
1491 /* inquire_readwrite()-- Given a fortran string, determine if the file is
1492 * suitable for read and write access. */
1494 const char *
1495 inquire_readwrite (const char *string, int len)
1497 return inquire_access (string, len, R_OK | W_OK);
1501 /* file_length()-- Return the file length in bytes, -1 if unknown */
1503 gfc_offset
1504 file_length (stream * s)
1506 return ((unix_stream *) s)->file_length;
1510 /* file_position()-- Return the current position of the file */
1512 gfc_offset
1513 file_position (stream * s)
1515 return ((unix_stream *) s)->logical_offset;
1519 /* is_seekable()-- Return nonzero if the stream is seekable, zero if
1520 * it is not */
1523 is_seekable (stream * s)
1525 /* by convention, if file_length == -1, the file is not seekable
1526 note that a mmapped file is always seekable, an fd_ file may
1527 or may not be. */
1528 return ((unix_stream *) s)->file_length!=-1;
1532 flush (stream *s)
1534 return fd_flush( (unix_stream *) s);
1538 /* How files are stored: This is an operating-system specific issue,
1539 and therefore belongs here. There are three cases to consider.
1541 Direct Access:
1542 Records are written as block of bytes corresponding to the record
1543 length of the file. This goes for both formatted and unformatted
1544 records. Positioning is done explicitly for each data transfer,
1545 so positioning is not much of an issue.
1547 Sequential Formatted:
1548 Records are separated by newline characters. The newline character
1549 is prohibited from appearing in a string. If it does, this will be
1550 messed up on the next read. End of file is also the end of a record.
1552 Sequential Unformatted:
1553 In this case, we are merely copying bytes to and from main storage,
1554 yet we need to keep track of varying record lengths. We adopt
1555 the solution used by f2c. Each record contains a pair of length
1556 markers:
1558 Length of record n in bytes
1559 Data of record n
1560 Length of record n in bytes
1562 Length of record n+1 in bytes
1563 Data of record n+1
1564 Length of record n+1 in bytes
1566 The length is stored at the end of a record to allow backspacing to the
1567 previous record. Between data transfer statements, the file pointer
1568 is left pointing to the first length of the current record.
1570 ENDFILE records are never explicitly stored.