PR libfortran/47439
[official-gcc.git] / libgfortran / io / unix.c
blobedccdd6397a3f002e26c6b06891dc0d0989a1874
1 /* Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
2 2011
3 Free Software Foundation, Inc.
4 Contributed by Andy Vaught
5 F2003 I/O support contributed by Jerry DeLisle
7 This file is part of the GNU Fortran runtime library (libgfortran).
9 Libgfortran is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3, or (at your option)
12 any later version.
14 Libgfortran is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 Under Section 7 of GPL version 3, you are granted additional
20 permissions described in the GCC Runtime Library Exception, version
21 3.1, as published by the Free Software Foundation.
23 You should have received a copy of the GNU General Public License and
24 a copy of the GCC Runtime Library Exception along with this program;
25 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
26 <http://www.gnu.org/licenses/>. */
28 /* Unix stream I/O module */
30 #include "io.h"
31 #include "unix.h"
32 #include <stdlib.h>
33 #include <limits.h>
35 #include <unistd.h>
36 #include <sys/stat.h>
37 #include <fcntl.h>
38 #include <assert.h>
40 #include <string.h>
41 #include <errno.h>
44 /* For mingw, we don't identify files by their inode number, but by a
45 64-bit identifier created from a BY_HANDLE_FILE_INFORMATION. */
46 #ifdef __MINGW32__
48 #define WIN32_LEAN_AND_MEAN
49 #include <windows.h>
51 #define lseek _lseeki64
52 #define fstat _fstati64
53 #define stat _stati64
54 typedef struct _stati64 gfstat_t;
56 #ifndef HAVE_WORKING_STAT
57 static uint64_t
58 id_from_handle (HANDLE hFile)
60 BY_HANDLE_FILE_INFORMATION FileInformation;
62 if (hFile == INVALID_HANDLE_VALUE)
63 return 0;
65 memset (&FileInformation, 0, sizeof(FileInformation));
66 if (!GetFileInformationByHandle (hFile, &FileInformation))
67 return 0;
69 return ((uint64_t) FileInformation.nFileIndexLow)
70 | (((uint64_t) FileInformation.nFileIndexHigh) << 32);
74 static uint64_t
75 id_from_path (const char *path)
77 HANDLE hFile;
78 uint64_t res;
80 if (!path || !*path || access (path, F_OK))
81 return (uint64_t) -1;
83 hFile = CreateFile (path, 0, 0, NULL, OPEN_EXISTING,
84 FILE_FLAG_BACKUP_SEMANTICS | FILE_ATTRIBUTE_READONLY,
85 NULL);
86 res = id_from_handle (hFile);
87 CloseHandle (hFile);
88 return res;
92 static uint64_t
93 id_from_fd (const int fd)
95 return id_from_handle ((HANDLE) _get_osfhandle (fd));
98 #endif
100 #else
101 typedef struct stat gfstat_t;
102 #endif
104 #ifndef PATH_MAX
105 #define PATH_MAX 1024
106 #endif
108 /* These flags aren't defined on all targets (mingw32), so provide them
109 here. */
110 #ifndef S_IRGRP
111 #define S_IRGRP 0
112 #endif
114 #ifndef S_IWGRP
115 #define S_IWGRP 0
116 #endif
118 #ifndef S_IROTH
119 #define S_IROTH 0
120 #endif
122 #ifndef S_IWOTH
123 #define S_IWOTH 0
124 #endif
127 #ifndef HAVE_ACCESS
129 #ifndef W_OK
130 #define W_OK 2
131 #endif
133 #ifndef R_OK
134 #define R_OK 4
135 #endif
137 #ifndef F_OK
138 #define F_OK 0
139 #endif
141 /* Fallback implementation of access() on systems that don't have it.
142 Only modes R_OK, W_OK and F_OK are used in this file. */
144 static int
145 fallback_access (const char *path, int mode)
147 int fd;
149 if ((mode & R_OK) && (fd = open (path, O_RDONLY)) < 0)
150 return -1;
151 close (fd);
153 if ((mode & W_OK) && (fd = open (path, O_WRONLY)) < 0)
154 return -1;
155 close (fd);
157 if (mode == F_OK)
159 gfstat_t st;
160 return stat (path, &st);
163 return 0;
166 #undef access
167 #define access fallback_access
168 #endif
171 /* Unix and internal stream I/O module */
173 static const int BUFFER_SIZE = 8192;
175 typedef struct
177 stream st;
179 gfc_offset buffer_offset; /* File offset of the start of the buffer */
180 gfc_offset physical_offset; /* Current physical file offset */
181 gfc_offset logical_offset; /* Current logical file offset */
182 gfc_offset file_length; /* Length of the file, -1 if not seekable. */
184 char *buffer; /* Pointer to the buffer. */
185 int fd; /* The POSIX file descriptor. */
187 int active; /* Length of valid bytes in the buffer */
189 int ndirty; /* Dirty bytes starting at buffer_offset */
191 int special_file; /* =1 if the fd refers to a special file */
193 /* Cached stat(2) values. */
194 dev_t st_dev;
195 ino_t st_ino;
197 unix_stream;
200 /* fix_fd()-- Given a file descriptor, make sure it is not one of the
201 * standard descriptors, returning a non-standard descriptor. If the
202 * user specifies that system errors should go to standard output,
203 * then closes standard output, we don't want the system errors to a
204 * file that has been given file descriptor 1 or 0. We want to send
205 * the error to the invalid descriptor. */
207 static int
208 fix_fd (int fd)
210 #ifdef HAVE_DUP
211 int input, output, error;
213 input = output = error = 0;
215 /* Unix allocates the lowest descriptors first, so a loop is not
216 required, but this order is. */
217 if (fd == STDIN_FILENO)
219 fd = dup (fd);
220 input = 1;
222 if (fd == STDOUT_FILENO)
224 fd = dup (fd);
225 output = 1;
227 if (fd == STDERR_FILENO)
229 fd = dup (fd);
230 error = 1;
233 if (input)
234 close (STDIN_FILENO);
235 if (output)
236 close (STDOUT_FILENO);
237 if (error)
238 close (STDERR_FILENO);
239 #endif
241 return fd;
245 /* If the stream corresponds to a preconnected unit, we flush the
246 corresponding C stream. This is bugware for mixed C-Fortran codes
247 where the C code doesn't flush I/O before returning. */
248 void
249 flush_if_preconnected (stream * s)
251 int fd;
253 fd = ((unix_stream *) s)->fd;
254 if (fd == STDIN_FILENO)
255 fflush (stdin);
256 else if (fd == STDOUT_FILENO)
257 fflush (stdout);
258 else if (fd == STDERR_FILENO)
259 fflush (stderr);
263 /********************************************************************
264 Raw I/O functions (read, write, seek, tell, truncate, close).
266 These functions wrap the basic POSIX I/O syscalls. Any deviation in
267 semantics is a bug, except the following: write restarts in case
268 of being interrupted by a signal, and as the first argument the
269 functions take the unix_stream struct rather than an integer file
270 descriptor. Also, for POSIX read() and write() a nbyte argument larger
271 than SSIZE_MAX is undefined; here the type of nbyte is ssize_t rather
272 than size_t as for POSIX read/write.
273 *********************************************************************/
275 static int
276 raw_flush (unix_stream * s __attribute__ ((unused)))
278 return 0;
281 static ssize_t
282 raw_read (unix_stream * s, void * buf, ssize_t nbyte)
284 /* For read we can't do I/O in a loop like raw_write does, because
285 that will break applications that wait for interactive I/O. */
286 return read (s->fd, buf, nbyte);
289 static ssize_t
290 raw_write (unix_stream * s, const void * buf, ssize_t nbyte)
292 ssize_t trans, bytes_left;
293 char *buf_st;
295 bytes_left = nbyte;
296 buf_st = (char *) buf;
298 /* We must write in a loop since some systems don't restart system
299 calls in case of a signal. */
300 while (bytes_left > 0)
302 trans = write (s->fd, buf_st, bytes_left);
303 if (trans < 0)
305 if (errno == EINTR)
306 continue;
307 else
308 return trans;
310 buf_st += trans;
311 bytes_left -= trans;
314 return nbyte - bytes_left;
317 static gfc_offset
318 raw_seek (unix_stream * s, gfc_offset offset, int whence)
320 return lseek (s->fd, offset, whence);
323 static gfc_offset
324 raw_tell (unix_stream * s)
326 return lseek (s->fd, 0, SEEK_CUR);
329 static int
330 raw_truncate (unix_stream * s, gfc_offset length)
332 #ifdef __MINGW32__
333 HANDLE h;
334 gfc_offset cur;
336 if (isatty (s->fd))
338 errno = EBADF;
339 return -1;
341 h = (HANDLE) _get_osfhandle (s->fd);
342 if (h == INVALID_HANDLE_VALUE)
344 errno = EBADF;
345 return -1;
347 cur = lseek (s->fd, 0, SEEK_CUR);
348 if (cur == -1)
349 return -1;
350 if (lseek (s->fd, length, SEEK_SET) == -1)
351 goto error;
352 if (!SetEndOfFile (h))
354 errno = EBADF;
355 goto error;
357 if (lseek (s->fd, cur, SEEK_SET) == -1)
358 return -1;
359 return 0;
360 error:
361 lseek (s->fd, cur, SEEK_SET);
362 return -1;
363 #elif defined HAVE_FTRUNCATE
364 return ftruncate (s->fd, length);
365 #elif defined HAVE_CHSIZE
366 return chsize (s->fd, length);
367 #else
368 runtime_error ("required ftruncate or chsize support not present");
369 return -1;
370 #endif
373 static int
374 raw_close (unix_stream * s)
376 int retval;
378 if (s->fd != STDOUT_FILENO
379 && s->fd != STDERR_FILENO
380 && s->fd != STDIN_FILENO)
381 retval = close (s->fd);
382 else
383 retval = 0;
384 free (s);
385 return retval;
388 static int
389 raw_init (unix_stream * s)
391 s->st.read = (void *) raw_read;
392 s->st.write = (void *) raw_write;
393 s->st.seek = (void *) raw_seek;
394 s->st.tell = (void *) raw_tell;
395 s->st.trunc = (void *) raw_truncate;
396 s->st.close = (void *) raw_close;
397 s->st.flush = (void *) raw_flush;
399 s->buffer = NULL;
400 return 0;
404 /*********************************************************************
405 Buffered I/O functions. These functions have the same semantics as the
406 raw I/O functions above, except that they are buffered in order to
407 improve performance. The buffer must be flushed when switching from
408 reading to writing and vice versa.
409 *********************************************************************/
411 static int
412 buf_flush (unix_stream * s)
414 int writelen;
416 /* Flushing in read mode means discarding read bytes. */
417 s->active = 0;
419 if (s->ndirty == 0)
420 return 0;
422 if (s->file_length != -1 && s->physical_offset != s->buffer_offset
423 && lseek (s->fd, s->buffer_offset, SEEK_SET) < 0)
424 return -1;
426 writelen = raw_write (s, s->buffer, s->ndirty);
428 s->physical_offset = s->buffer_offset + writelen;
430 /* Don't increment file_length if the file is non-seekable. */
431 if (s->file_length != -1 && s->physical_offset > s->file_length)
432 s->file_length = s->physical_offset;
434 s->ndirty -= writelen;
435 if (s->ndirty != 0)
436 return -1;
438 #ifdef _WIN32
439 _commit (s->fd);
440 #endif
442 return 0;
445 static ssize_t
446 buf_read (unix_stream * s, void * buf, ssize_t nbyte)
448 if (s->active == 0)
449 s->buffer_offset = s->logical_offset;
451 /* Is the data we want in the buffer? */
452 if (s->logical_offset + nbyte <= s->buffer_offset + s->active
453 && s->buffer_offset <= s->logical_offset)
454 memcpy (buf, s->buffer + (s->logical_offset - s->buffer_offset), nbyte);
455 else
457 /* First copy the active bytes if applicable, then read the rest
458 either directly or filling the buffer. */
459 char *p;
460 int nread = 0;
461 ssize_t to_read, did_read;
462 gfc_offset new_logical;
464 p = (char *) buf;
465 if (s->logical_offset >= s->buffer_offset
466 && s->buffer_offset + s->active >= s->logical_offset)
468 nread = s->active - (s->logical_offset - s->buffer_offset);
469 memcpy (buf, s->buffer + (s->logical_offset - s->buffer_offset),
470 nread);
471 p += nread;
473 /* At this point we consider all bytes in the buffer discarded. */
474 to_read = nbyte - nread;
475 new_logical = s->logical_offset + nread;
476 if (s->file_length != -1 && s->physical_offset != new_logical
477 && lseek (s->fd, new_logical, SEEK_SET) < 0)
478 return -1;
479 s->buffer_offset = s->physical_offset = new_logical;
480 if (to_read <= BUFFER_SIZE/2)
482 did_read = raw_read (s, s->buffer, BUFFER_SIZE);
483 s->physical_offset += did_read;
484 s->active = did_read;
485 did_read = (did_read > to_read) ? to_read : did_read;
486 memcpy (p, s->buffer, did_read);
488 else
490 did_read = raw_read (s, p, to_read);
491 s->physical_offset += did_read;
492 s->active = 0;
494 nbyte = did_read + nread;
496 s->logical_offset += nbyte;
497 return nbyte;
500 static ssize_t
501 buf_write (unix_stream * s, const void * buf, ssize_t nbyte)
503 if (s->ndirty == 0)
504 s->buffer_offset = s->logical_offset;
506 /* Does the data fit into the buffer? As a special case, if the
507 buffer is empty and the request is bigger than BUFFER_SIZE/2,
508 write directly. This avoids the case where the buffer would have
509 to be flushed at every write. */
510 if (!(s->ndirty == 0 && nbyte > BUFFER_SIZE/2)
511 && s->logical_offset + nbyte <= s->buffer_offset + BUFFER_SIZE
512 && s->buffer_offset <= s->logical_offset
513 && s->buffer_offset + s->ndirty >= s->logical_offset)
515 memcpy (s->buffer + (s->logical_offset - s->buffer_offset), buf, nbyte);
516 int nd = (s->logical_offset - s->buffer_offset) + nbyte;
517 if (nd > s->ndirty)
518 s->ndirty = nd;
520 else
522 /* Flush, and either fill the buffer with the new data, or if
523 the request is bigger than the buffer size, write directly
524 bypassing the buffer. */
525 buf_flush (s);
526 if (nbyte <= BUFFER_SIZE/2)
528 memcpy (s->buffer, buf, nbyte);
529 s->buffer_offset = s->logical_offset;
530 s->ndirty += nbyte;
532 else
534 if (s->file_length != -1 && s->physical_offset != s->logical_offset)
536 if (lseek (s->fd, s->logical_offset, SEEK_SET) < 0)
537 return -1;
538 s->physical_offset = s->logical_offset;
541 nbyte = raw_write (s, buf, nbyte);
542 s->physical_offset += nbyte;
545 s->logical_offset += nbyte;
546 /* Don't increment file_length if the file is non-seekable. */
547 if (s->file_length != -1 && s->logical_offset > s->file_length)
548 s->file_length = s->logical_offset;
549 return nbyte;
552 static gfc_offset
553 buf_seek (unix_stream * s, gfc_offset offset, int whence)
555 switch (whence)
557 case SEEK_SET:
558 break;
559 case SEEK_CUR:
560 offset += s->logical_offset;
561 break;
562 case SEEK_END:
563 offset += s->file_length;
564 break;
565 default:
566 return -1;
568 if (offset < 0)
570 errno = EINVAL;
571 return -1;
573 s->logical_offset = offset;
574 return offset;
577 static gfc_offset
578 buf_tell (unix_stream * s)
580 return s->logical_offset;
583 static int
584 buf_truncate (unix_stream * s, gfc_offset length)
586 int r;
588 if (buf_flush (s) != 0)
589 return -1;
590 r = raw_truncate (s, length);
591 if (r == 0)
592 s->file_length = length;
593 return r;
596 static int
597 buf_close (unix_stream * s)
599 if (buf_flush (s) != 0)
600 return -1;
601 free (s->buffer);
602 return raw_close (s);
605 static int
606 buf_init (unix_stream * s)
608 s->st.read = (void *) buf_read;
609 s->st.write = (void *) buf_write;
610 s->st.seek = (void *) buf_seek;
611 s->st.tell = (void *) buf_tell;
612 s->st.trunc = (void *) buf_truncate;
613 s->st.close = (void *) buf_close;
614 s->st.flush = (void *) buf_flush;
616 s->buffer = get_mem (BUFFER_SIZE);
617 return 0;
621 /*********************************************************************
622 memory stream functions - These are used for internal files
624 The idea here is that a single stream structure is created and all
625 requests must be satisfied from it. The location and size of the
626 buffer is the character variable supplied to the READ or WRITE
627 statement.
629 *********************************************************************/
631 char *
632 mem_alloc_r (stream * strm, int * len)
634 unix_stream * s = (unix_stream *) strm;
635 gfc_offset n;
636 gfc_offset where = s->logical_offset;
638 if (where < s->buffer_offset || where > s->buffer_offset + s->active)
639 return NULL;
641 n = s->buffer_offset + s->active - where;
642 if (*len > n)
643 *len = n;
645 s->logical_offset = where + *len;
647 return s->buffer + (where - s->buffer_offset);
651 char *
652 mem_alloc_r4 (stream * strm, int * len)
654 unix_stream * s = (unix_stream *) strm;
655 gfc_offset n;
656 gfc_offset where = s->logical_offset;
658 if (where < s->buffer_offset || where > s->buffer_offset + s->active)
659 return NULL;
661 n = s->buffer_offset + s->active - where;
662 if (*len > n)
663 *len = n;
665 s->logical_offset = where + *len;
667 return s->buffer + (where - s->buffer_offset) * 4;
671 char *
672 mem_alloc_w (stream * strm, int * len)
674 unix_stream * s = (unix_stream *) strm;
675 gfc_offset m;
676 gfc_offset where = s->logical_offset;
678 m = where + *len;
680 if (where < s->buffer_offset)
681 return NULL;
683 if (m > s->file_length)
684 return NULL;
686 s->logical_offset = m;
688 return s->buffer + (where - s->buffer_offset);
692 gfc_char4_t *
693 mem_alloc_w4 (stream * strm, int * len)
695 unix_stream * s = (unix_stream *) strm;
696 gfc_offset m;
697 gfc_offset where = s->logical_offset;
698 gfc_char4_t *result = (gfc_char4_t *) s->buffer;
700 m = where + *len;
702 if (where < s->buffer_offset)
703 return NULL;
705 if (m > s->file_length)
706 return NULL;
708 s->logical_offset = m;
709 return &result[where - s->buffer_offset];
713 /* Stream read function for character(kine=1) internal units. */
715 static ssize_t
716 mem_read (stream * s, void * buf, ssize_t nbytes)
718 void *p;
719 int nb = nbytes;
721 p = mem_alloc_r (s, &nb);
722 if (p)
724 memcpy (buf, p, nb);
725 return (ssize_t) nb;
727 else
728 return 0;
732 /* Stream read function for chracter(kind=4) internal units. */
734 static ssize_t
735 mem_read4 (stream * s, void * buf, ssize_t nbytes)
737 void *p;
738 int nb = nbytes;
740 p = mem_alloc_r (s, &nb);
741 if (p)
743 memcpy (buf, p, nb);
744 return (ssize_t) nb;
746 else
747 return 0;
751 /* Stream write function for character(kind=1) internal units. */
753 static ssize_t
754 mem_write (stream * s, const void * buf, ssize_t nbytes)
756 void *p;
757 int nb = nbytes;
759 p = mem_alloc_w (s, &nb);
760 if (p)
762 memcpy (p, buf, nb);
763 return (ssize_t) nb;
765 else
766 return 0;
770 /* Stream write function for character(kind=4) internal units. */
772 static ssize_t
773 mem_write4 (stream * s, const void * buf, ssize_t nwords)
775 gfc_char4_t *p;
776 int nw = nwords;
778 p = mem_alloc_w4 (s, &nw);
779 if (p)
781 while (nw--)
782 *p++ = (gfc_char4_t) *((char *) buf);
783 return nwords;
785 else
786 return 0;
790 static gfc_offset
791 mem_seek (stream * strm, gfc_offset offset, int whence)
793 unix_stream * s = (unix_stream *) strm;
794 switch (whence)
796 case SEEK_SET:
797 break;
798 case SEEK_CUR:
799 offset += s->logical_offset;
800 break;
801 case SEEK_END:
802 offset += s->file_length;
803 break;
804 default:
805 return -1;
808 /* Note that for internal array I/O it's actually possible to have a
809 negative offset, so don't check for that. */
810 if (offset > s->file_length)
812 errno = EINVAL;
813 return -1;
816 s->logical_offset = offset;
818 /* Returning < 0 is the error indicator for sseek(), so return 0 if
819 offset is negative. Thus if the return value is 0, the caller
820 has to use stell() to get the real value of logical_offset. */
821 if (offset >= 0)
822 return offset;
823 return 0;
827 static gfc_offset
828 mem_tell (stream * s)
830 return ((unix_stream *)s)->logical_offset;
834 static int
835 mem_truncate (unix_stream * s __attribute__ ((unused)),
836 gfc_offset length __attribute__ ((unused)))
838 return 0;
842 static int
843 mem_flush (unix_stream * s __attribute__ ((unused)))
845 return 0;
849 static int
850 mem_close (unix_stream * s)
852 if (s != NULL)
853 free (s);
855 return 0;
859 /*********************************************************************
860 Public functions -- A reimplementation of this module needs to
861 define functional equivalents of the following.
862 *********************************************************************/
864 /* open_internal()-- Returns a stream structure from a character(kind=1)
865 internal file */
867 stream *
868 open_internal (char *base, int length, gfc_offset offset)
870 unix_stream *s;
872 s = get_mem (sizeof (unix_stream));
873 memset (s, '\0', sizeof (unix_stream));
875 s->buffer = base;
876 s->buffer_offset = offset;
878 s->logical_offset = 0;
879 s->active = s->file_length = length;
881 s->st.close = (void *) mem_close;
882 s->st.seek = (void *) mem_seek;
883 s->st.tell = (void *) mem_tell;
884 s->st.trunc = (void *) mem_truncate;
885 s->st.read = (void *) mem_read;
886 s->st.write = (void *) mem_write;
887 s->st.flush = (void *) mem_flush;
889 return (stream *) s;
892 /* open_internal4()-- Returns a stream structure from a character(kind=4)
893 internal file */
895 stream *
896 open_internal4 (char *base, int length, gfc_offset offset)
898 unix_stream *s;
900 s = get_mem (sizeof (unix_stream));
901 memset (s, '\0', sizeof (unix_stream));
903 s->buffer = base;
904 s->buffer_offset = offset;
906 s->logical_offset = 0;
907 s->active = s->file_length = length;
909 s->st.close = (void *) mem_close;
910 s->st.seek = (void *) mem_seek;
911 s->st.tell = (void *) mem_tell;
912 s->st.trunc = (void *) mem_truncate;
913 s->st.read = (void *) mem_read4;
914 s->st.write = (void *) mem_write4;
915 s->st.flush = (void *) mem_flush;
917 return (stream *) s;
921 /* fd_to_stream()-- Given an open file descriptor, build a stream
922 * around it. */
924 static stream *
925 fd_to_stream (int fd)
927 gfstat_t statbuf;
928 unix_stream *s;
930 s = get_mem (sizeof (unix_stream));
931 memset (s, '\0', sizeof (unix_stream));
933 s->fd = fd;
934 s->buffer_offset = 0;
935 s->physical_offset = 0;
936 s->logical_offset = 0;
938 /* Get the current length of the file. */
940 fstat (fd, &statbuf);
942 s->st_dev = statbuf.st_dev;
943 s->st_ino = statbuf.st_ino;
944 s->special_file = !S_ISREG (statbuf.st_mode);
946 if (S_ISREG (statbuf.st_mode))
947 s->file_length = statbuf.st_size;
948 else if (S_ISBLK (statbuf.st_mode))
950 /* Hopefully more portable than ioctl(fd, BLKGETSIZE64, &size)? */
951 gfc_offset cur = lseek (fd, 0, SEEK_CUR);
952 s->file_length = lseek (fd, 0, SEEK_END);
953 lseek (fd, cur, SEEK_SET);
955 else
956 s->file_length = -1;
958 if (!(S_ISREG (statbuf.st_mode) || S_ISBLK (statbuf.st_mode))
959 || options.all_unbuffered
960 ||(options.unbuffered_preconnected &&
961 (s->fd == STDIN_FILENO
962 || s->fd == STDOUT_FILENO
963 || s->fd == STDERR_FILENO))
964 || isatty (s->fd))
965 raw_init (s);
966 else
967 buf_init (s);
969 return (stream *) s;
973 /* Given the Fortran unit number, convert it to a C file descriptor. */
976 unit_to_fd (int unit)
978 gfc_unit *us;
979 int fd;
981 us = find_unit (unit);
982 if (us == NULL)
983 return -1;
985 fd = ((unix_stream *) us->s)->fd;
986 unlock_unit (us);
987 return fd;
991 /* unpack_filename()-- Given a fortran string and a pointer to a
992 * buffer that is PATH_MAX characters, convert the fortran string to a
993 * C string in the buffer. Returns nonzero if this is not possible. */
996 unpack_filename (char *cstring, const char *fstring, int len)
998 if (fstring == NULL)
999 return 1;
1000 len = fstrlen (fstring, len);
1001 if (len >= PATH_MAX)
1002 return 1;
1004 memmove (cstring, fstring, len);
1005 cstring[len] = '\0';
1007 return 0;
1011 /* tempfile()-- Generate a temporary filename for a scratch file and
1012 * open it. mkstemp() opens the file for reading and writing, but the
1013 * library mode prevents anything that is not allowed. The descriptor
1014 * is returned, which is -1 on error. The template is pointed to by
1015 * opp->file, which is copied into the unit structure
1016 * and freed later. */
1018 static int
1019 tempfile (st_parameter_open *opp)
1021 const char *tempdir;
1022 char *template;
1023 const char *slash = "/";
1024 int fd;
1025 size_t tempdirlen;
1027 #ifndef HAVE_MKSTEMP
1028 int count;
1029 size_t slashlen;
1030 #endif
1032 tempdir = getenv ("GFORTRAN_TMPDIR");
1033 #ifdef __MINGW32__
1034 if (tempdir == NULL)
1036 char buffer[MAX_PATH + 1];
1037 DWORD ret;
1038 ret = GetTempPath (MAX_PATH, buffer);
1039 /* If we are not able to get a temp-directory, we use
1040 current directory. */
1041 if (ret > MAX_PATH || !ret)
1042 buffer[0] = 0;
1043 else
1044 buffer[ret] = 0;
1045 tempdir = strdup (buffer);
1047 #else
1048 if (tempdir == NULL)
1049 tempdir = getenv ("TMP");
1050 if (tempdir == NULL)
1051 tempdir = getenv ("TEMP");
1052 if (tempdir == NULL)
1053 tempdir = DEFAULT_TEMPDIR;
1054 #endif
1056 /* Check for special case that tempdir contains slash
1057 or backslash at end. */
1058 tempdirlen = strlen (tempdir);
1059 if (*tempdir == 0 || tempdir[tempdirlen - 1] == '/'
1060 #ifdef __MINGW32__
1061 || tempdir[tempdirlen - 1] == '\\'
1062 #endif
1064 slash = "";
1066 // Take care that the template is longer in the mktemp() branch.
1067 template = get_mem (tempdirlen + 23);
1069 #ifdef HAVE_MKSTEMP
1070 sprintf (template, "%s%sgfortrantmpXXXXXX", tempdir, slash);
1072 fd = mkstemp (template);
1074 #else /* HAVE_MKSTEMP */
1075 fd = -1;
1076 count = 0;
1077 slashlen = strlen (slash);
1080 sprintf (template, "%s%sgfortrantmpaaaXXXXXX", tempdir, slash);
1081 if (count > 0)
1083 int c = count;
1084 template[tempdirlen + slashlen + 13] = 'a' + (c% 26);
1085 c /= 26;
1086 template[tempdirlen + slashlen + 12] = 'a' + (c % 26);
1087 c /= 26;
1088 template[tempdirlen + slashlen + 11] = 'a' + (c % 26);
1089 if (c >= 26)
1090 break;
1093 if (!mktemp (template))
1095 errno = EEXIST;
1096 count++;
1097 continue;
1100 #if defined(HAVE_CRLF) && defined(O_BINARY)
1101 fd = open (template, O_RDWR | O_CREAT | O_EXCL | O_BINARY,
1102 S_IREAD | S_IWRITE);
1103 #else
1104 fd = open (template, O_RDWR | O_CREAT | O_EXCL, S_IREAD | S_IWRITE);
1105 #endif
1107 while (fd == -1 && errno == EEXIST);
1108 #endif /* HAVE_MKSTEMP */
1110 opp->file = template;
1111 opp->file_len = strlen (template); /* Don't include trailing nul */
1113 return fd;
1117 /* regular_file()-- Open a regular file.
1118 * Change flags->action if it is ACTION_UNSPECIFIED on entry,
1119 * unless an error occurs.
1120 * Returns the descriptor, which is less than zero on error. */
1122 static int
1123 regular_file (st_parameter_open *opp, unit_flags *flags)
1125 char path[PATH_MAX + 1];
1126 int mode;
1127 int rwflag;
1128 int crflag;
1129 int fd;
1131 if (unpack_filename (path, opp->file, opp->file_len))
1133 errno = ENOENT; /* Fake an OS error */
1134 return -1;
1137 #ifdef __CYGWIN__
1138 if (opp->file_len == 7)
1140 if (strncmp (path, "CONOUT$", 7) == 0
1141 || strncmp (path, "CONERR$", 7) == 0)
1143 fd = open ("/dev/conout", O_WRONLY);
1144 flags->action = ACTION_WRITE;
1145 return fd;
1149 if (opp->file_len == 6 && strncmp (path, "CONIN$", 6) == 0)
1151 fd = open ("/dev/conin", O_RDONLY);
1152 flags->action = ACTION_READ;
1153 return fd;
1155 #endif
1158 #ifdef __MINGW32__
1159 if (opp->file_len == 7)
1161 if (strncmp (path, "CONOUT$", 7) == 0
1162 || strncmp (path, "CONERR$", 7) == 0)
1164 fd = open ("CONOUT$", O_WRONLY);
1165 flags->action = ACTION_WRITE;
1166 return fd;
1170 if (opp->file_len == 6 && strncmp (path, "CONIN$", 6) == 0)
1172 fd = open ("CONIN$", O_RDONLY);
1173 flags->action = ACTION_READ;
1174 return fd;
1176 #endif
1178 rwflag = 0;
1180 switch (flags->action)
1182 case ACTION_READ:
1183 rwflag = O_RDONLY;
1184 break;
1186 case ACTION_WRITE:
1187 rwflag = O_WRONLY;
1188 break;
1190 case ACTION_READWRITE:
1191 case ACTION_UNSPECIFIED:
1192 rwflag = O_RDWR;
1193 break;
1195 default:
1196 internal_error (&opp->common, "regular_file(): Bad action");
1199 switch (flags->status)
1201 case STATUS_NEW:
1202 crflag = O_CREAT | O_EXCL;
1203 break;
1205 case STATUS_OLD: /* open will fail if the file does not exist*/
1206 crflag = 0;
1207 break;
1209 case STATUS_UNKNOWN:
1210 case STATUS_SCRATCH:
1211 crflag = O_CREAT;
1212 break;
1214 case STATUS_REPLACE:
1215 crflag = O_CREAT | O_TRUNC;
1216 break;
1218 default:
1219 internal_error (&opp->common, "regular_file(): Bad status");
1222 /* rwflag |= O_LARGEFILE; */
1224 #if defined(HAVE_CRLF) && defined(O_BINARY)
1225 crflag |= O_BINARY;
1226 #endif
1228 mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
1229 fd = open (path, rwflag | crflag, mode);
1230 if (flags->action != ACTION_UNSPECIFIED)
1231 return fd;
1233 if (fd >= 0)
1235 flags->action = ACTION_READWRITE;
1236 return fd;
1238 if (errno != EACCES && errno != EROFS)
1239 return fd;
1241 /* retry for read-only access */
1242 rwflag = O_RDONLY;
1243 fd = open (path, rwflag | crflag, mode);
1244 if (fd >=0)
1246 flags->action = ACTION_READ;
1247 return fd; /* success */
1250 if (errno != EACCES)
1251 return fd; /* failure */
1253 /* retry for write-only access */
1254 rwflag = O_WRONLY;
1255 fd = open (path, rwflag | crflag, mode);
1256 if (fd >=0)
1258 flags->action = ACTION_WRITE;
1259 return fd; /* success */
1261 return fd; /* failure */
1265 /* open_external()-- Open an external file, unix specific version.
1266 * Change flags->action if it is ACTION_UNSPECIFIED on entry.
1267 * Returns NULL on operating system error. */
1269 stream *
1270 open_external (st_parameter_open *opp, unit_flags *flags)
1272 int fd;
1274 if (flags->status == STATUS_SCRATCH)
1276 fd = tempfile (opp);
1277 if (flags->action == ACTION_UNSPECIFIED)
1278 flags->action = ACTION_READWRITE;
1280 #if HAVE_UNLINK_OPEN_FILE
1281 /* We can unlink scratch files now and it will go away when closed. */
1282 if (fd >= 0)
1283 unlink (opp->file);
1284 #endif
1286 else
1288 /* regular_file resets flags->action if it is ACTION_UNSPECIFIED and
1289 * if it succeeds */
1290 fd = regular_file (opp, flags);
1293 if (fd < 0)
1294 return NULL;
1295 fd = fix_fd (fd);
1297 return fd_to_stream (fd);
1301 /* input_stream()-- Return a stream pointer to the default input stream.
1302 * Called on initialization. */
1304 stream *
1305 input_stream (void)
1307 return fd_to_stream (STDIN_FILENO);
1311 /* output_stream()-- Return a stream pointer to the default output stream.
1312 * Called on initialization. */
1314 stream *
1315 output_stream (void)
1317 stream * s;
1319 #if defined(HAVE_CRLF) && defined(HAVE_SETMODE)
1320 setmode (STDOUT_FILENO, O_BINARY);
1321 #endif
1323 s = fd_to_stream (STDOUT_FILENO);
1324 return s;
1328 /* error_stream()-- Return a stream pointer to the default error stream.
1329 * Called on initialization. */
1331 stream *
1332 error_stream (void)
1334 stream * s;
1336 #if defined(HAVE_CRLF) && defined(HAVE_SETMODE)
1337 setmode (STDERR_FILENO, O_BINARY);
1338 #endif
1340 s = fd_to_stream (STDERR_FILENO);
1341 return s;
1345 /* st_vprintf()-- vprintf function for error output. To avoid buffer
1346 overruns, we limit the length of the buffer to ST_VPRINTF_SIZE. 2k
1347 is big enough to completely fill a 80x25 terminal, so it shuld be
1348 OK. We use a direct write() because it is simpler and least likely
1349 to be clobbered by memory corruption. Writing an error message
1350 longer than that is an error. */
1352 #define ST_VPRINTF_SIZE 2048
1355 st_vprintf (const char *format, va_list ap)
1357 static char buffer[ST_VPRINTF_SIZE];
1358 int written;
1359 int fd;
1361 fd = options.use_stderr ? STDERR_FILENO : STDOUT_FILENO;
1362 #ifdef HAVE_VSNPRINTF
1363 written = vsnprintf(buffer, ST_VPRINTF_SIZE, format, ap);
1364 #else
1365 written = vsprintf(buffer, format, ap);
1367 if (written >= ST_VPRINTF_SIZE-1)
1369 /* The error message was longer than our buffer. Ouch. Because
1370 we may have messed up things badly, report the error and
1371 quit. */
1372 #define ERROR_MESSAGE "Internal error: buffer overrun in st_vprintf()\n"
1373 write (fd, buffer, ST_VPRINTF_SIZE-1);
1374 write (fd, ERROR_MESSAGE, strlen(ERROR_MESSAGE));
1375 sys_exit(2);
1376 #undef ERROR_MESSAGE
1379 #endif
1381 written = write (fd, buffer, written);
1382 return written;
1385 /* st_printf()-- printf() function for error output. This just calls
1386 st_vprintf() to do the actual work. */
1389 st_printf (const char *format, ...)
1391 int written;
1392 va_list ap;
1393 va_start (ap, format);
1394 written = st_vprintf(format, ap);
1395 va_end (ap);
1396 return written;
1400 /* compare_file_filename()-- Given an open stream and a fortran string
1401 * that is a filename, figure out if the file is the same as the
1402 * filename. */
1405 compare_file_filename (gfc_unit *u, const char *name, int len)
1407 char path[PATH_MAX + 1];
1408 gfstat_t st;
1409 #ifdef HAVE_WORKING_STAT
1410 unix_stream *s;
1411 #else
1412 # ifdef __MINGW32__
1413 uint64_t id1, id2;
1414 # endif
1415 #endif
1417 if (unpack_filename (path, name, len))
1418 return 0; /* Can't be the same */
1420 /* If the filename doesn't exist, then there is no match with the
1421 * existing file. */
1423 if (stat (path, &st) < 0)
1424 return 0;
1426 #ifdef HAVE_WORKING_STAT
1427 s = (unix_stream *) (u->s);
1428 return (st.st_dev == s->st_dev) && (st.st_ino == s->st_ino);
1429 #else
1431 # ifdef __MINGW32__
1432 /* We try to match files by a unique ID. On some filesystems (network
1433 fs and FAT), we can't generate this unique ID, and will simply compare
1434 filenames. */
1435 id1 = id_from_path (path);
1436 id2 = id_from_fd (((unix_stream *) (u->s))->fd);
1437 if (id1 || id2)
1438 return (id1 == id2);
1439 # endif
1441 if (len != u->file_len)
1442 return 0;
1443 return (memcmp(path, u->file, len) == 0);
1444 #endif
1448 #ifdef HAVE_WORKING_STAT
1449 # define FIND_FILE0_DECL gfstat_t *st
1450 # define FIND_FILE0_ARGS st
1451 #else
1452 # define FIND_FILE0_DECL uint64_t id, const char *file, gfc_charlen_type file_len
1453 # define FIND_FILE0_ARGS id, file, file_len
1454 #endif
1456 /* find_file0()-- Recursive work function for find_file() */
1458 static gfc_unit *
1459 find_file0 (gfc_unit *u, FIND_FILE0_DECL)
1461 gfc_unit *v;
1462 #if defined(__MINGW32__) && !HAVE_WORKING_STAT
1463 uint64_t id1;
1464 #endif
1466 if (u == NULL)
1467 return NULL;
1469 #ifdef HAVE_WORKING_STAT
1470 if (u->s != NULL)
1472 unix_stream *s = (unix_stream *) (u->s);
1473 if (st[0].st_dev == s->st_dev && st[0].st_ino == s->st_ino)
1474 return u;
1476 #else
1477 # ifdef __MINGW32__
1478 if (u->s && ((id1 = id_from_fd (((unix_stream *) u->s)->fd)) || id1))
1480 if (id == id1)
1481 return u;
1483 else
1484 # endif
1485 if (compare_string (u->file_len, u->file, file_len, file) == 0)
1486 return u;
1487 #endif
1489 v = find_file0 (u->left, FIND_FILE0_ARGS);
1490 if (v != NULL)
1491 return v;
1493 v = find_file0 (u->right, FIND_FILE0_ARGS);
1494 if (v != NULL)
1495 return v;
1497 return NULL;
1501 /* find_file()-- Take the current filename and see if there is a unit
1502 * that has the file already open. Returns a pointer to the unit if so. */
1504 gfc_unit *
1505 find_file (const char *file, gfc_charlen_type file_len)
1507 char path[PATH_MAX + 1];
1508 gfstat_t st[1];
1509 gfc_unit *u;
1510 #if defined(__MINGW32__) && !HAVE_WORKING_STAT
1511 uint64_t id = 0ULL;
1512 #endif
1514 if (unpack_filename (path, file, file_len))
1515 return NULL;
1517 if (stat (path, &st[0]) < 0)
1518 return NULL;
1520 #if defined(__MINGW32__) && !HAVE_WORKING_STAT
1521 id = id_from_path (path);
1522 #endif
1524 __gthread_mutex_lock (&unit_lock);
1525 retry:
1526 u = find_file0 (unit_root, FIND_FILE0_ARGS);
1527 if (u != NULL)
1529 /* Fast path. */
1530 if (! __gthread_mutex_trylock (&u->lock))
1532 /* assert (u->closed == 0); */
1533 __gthread_mutex_unlock (&unit_lock);
1534 return u;
1537 inc_waiting_locked (u);
1539 __gthread_mutex_unlock (&unit_lock);
1540 if (u != NULL)
1542 __gthread_mutex_lock (&u->lock);
1543 if (u->closed)
1545 __gthread_mutex_lock (&unit_lock);
1546 __gthread_mutex_unlock (&u->lock);
1547 if (predec_waiting_locked (u) == 0)
1548 free (u);
1549 goto retry;
1552 dec_waiting_unlocked (u);
1554 return u;
1557 static gfc_unit *
1558 flush_all_units_1 (gfc_unit *u, int min_unit)
1560 while (u != NULL)
1562 if (u->unit_number > min_unit)
1564 gfc_unit *r = flush_all_units_1 (u->left, min_unit);
1565 if (r != NULL)
1566 return r;
1568 if (u->unit_number >= min_unit)
1570 if (__gthread_mutex_trylock (&u->lock))
1571 return u;
1572 if (u->s)
1573 sflush (u->s);
1574 __gthread_mutex_unlock (&u->lock);
1576 u = u->right;
1578 return NULL;
1581 void
1582 flush_all_units (void)
1584 gfc_unit *u;
1585 int min_unit = 0;
1587 __gthread_mutex_lock (&unit_lock);
1590 u = flush_all_units_1 (unit_root, min_unit);
1591 if (u != NULL)
1592 inc_waiting_locked (u);
1593 __gthread_mutex_unlock (&unit_lock);
1594 if (u == NULL)
1595 return;
1597 __gthread_mutex_lock (&u->lock);
1599 min_unit = u->unit_number + 1;
1601 if (u->closed == 0)
1603 sflush (u->s);
1604 __gthread_mutex_lock (&unit_lock);
1605 __gthread_mutex_unlock (&u->lock);
1606 (void) predec_waiting_locked (u);
1608 else
1610 __gthread_mutex_lock (&unit_lock);
1611 __gthread_mutex_unlock (&u->lock);
1612 if (predec_waiting_locked (u) == 0)
1613 free (u);
1616 while (1);
1620 /* delete_file()-- Given a unit structure, delete the file associated
1621 * with the unit. Returns nonzero if something went wrong. */
1624 delete_file (gfc_unit * u)
1626 char path[PATH_MAX + 1];
1628 if (unpack_filename (path, u->file, u->file_len))
1629 { /* Shouldn't be possible */
1630 errno = ENOENT;
1631 return 1;
1634 return unlink (path);
1638 /* file_exists()-- Returns nonzero if the current filename exists on
1639 * the system */
1642 file_exists (const char *file, gfc_charlen_type file_len)
1644 char path[PATH_MAX + 1];
1646 if (unpack_filename (path, file, file_len))
1647 return 0;
1649 return !(access (path, F_OK));
1653 /* file_size()-- Returns the size of the file. */
1655 GFC_IO_INT
1656 file_size (const char *file, gfc_charlen_type file_len)
1658 char path[PATH_MAX + 1];
1659 gfstat_t statbuf;
1661 if (unpack_filename (path, file, file_len))
1662 return -1;
1664 if (stat (path, &statbuf) < 0)
1665 return -1;
1667 return (GFC_IO_INT) statbuf.st_size;
1670 static const char yes[] = "YES", no[] = "NO", unknown[] = "UNKNOWN";
1672 /* inquire_sequential()-- Given a fortran string, determine if the
1673 * file is suitable for sequential access. Returns a C-style
1674 * string. */
1676 const char *
1677 inquire_sequential (const char *string, int len)
1679 char path[PATH_MAX + 1];
1680 gfstat_t statbuf;
1682 if (string == NULL ||
1683 unpack_filename (path, string, len) || stat (path, &statbuf) < 0)
1684 return unknown;
1686 if (S_ISREG (statbuf.st_mode) ||
1687 S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode))
1688 return unknown;
1690 if (S_ISDIR (statbuf.st_mode) || S_ISBLK (statbuf.st_mode))
1691 return no;
1693 return unknown;
1697 /* inquire_direct()-- Given a fortran string, determine if the file is
1698 * suitable for direct access. Returns a C-style string. */
1700 const char *
1701 inquire_direct (const char *string, int len)
1703 char path[PATH_MAX + 1];
1704 gfstat_t statbuf;
1706 if (string == NULL ||
1707 unpack_filename (path, string, len) || stat (path, &statbuf) < 0)
1708 return unknown;
1710 if (S_ISREG (statbuf.st_mode) || S_ISBLK (statbuf.st_mode))
1711 return unknown;
1713 if (S_ISDIR (statbuf.st_mode) ||
1714 S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode))
1715 return no;
1717 return unknown;
1721 /* inquire_formatted()-- Given a fortran string, determine if the file
1722 * is suitable for formatted form. Returns a C-style string. */
1724 const char *
1725 inquire_formatted (const char *string, int len)
1727 char path[PATH_MAX + 1];
1728 gfstat_t statbuf;
1730 if (string == NULL ||
1731 unpack_filename (path, string, len) || stat (path, &statbuf) < 0)
1732 return unknown;
1734 if (S_ISREG (statbuf.st_mode) ||
1735 S_ISBLK (statbuf.st_mode) ||
1736 S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode))
1737 return unknown;
1739 if (S_ISDIR (statbuf.st_mode))
1740 return no;
1742 return unknown;
1746 /* inquire_unformatted()-- Given a fortran string, determine if the file
1747 * is suitable for unformatted form. Returns a C-style string. */
1749 const char *
1750 inquire_unformatted (const char *string, int len)
1752 return inquire_formatted (string, len);
1756 /* inquire_access()-- Given a fortran string, determine if the file is
1757 * suitable for access. */
1759 static const char *
1760 inquire_access (const char *string, int len, int mode)
1762 char path[PATH_MAX + 1];
1764 if (string == NULL || unpack_filename (path, string, len) ||
1765 access (path, mode) < 0)
1766 return no;
1768 return yes;
1772 /* inquire_read()-- Given a fortran string, determine if the file is
1773 * suitable for READ access. */
1775 const char *
1776 inquire_read (const char *string, int len)
1778 return inquire_access (string, len, R_OK);
1782 /* inquire_write()-- Given a fortran string, determine if the file is
1783 * suitable for READ access. */
1785 const char *
1786 inquire_write (const char *string, int len)
1788 return inquire_access (string, len, W_OK);
1792 /* inquire_readwrite()-- Given a fortran string, determine if the file is
1793 * suitable for read and write access. */
1795 const char *
1796 inquire_readwrite (const char *string, int len)
1798 return inquire_access (string, len, R_OK | W_OK);
1802 /* file_length()-- Return the file length in bytes, -1 if unknown */
1804 gfc_offset
1805 file_length (stream * s)
1807 gfc_offset curr, end;
1808 if (!is_seekable (s))
1809 return -1;
1810 curr = stell (s);
1811 if (curr == -1)
1812 return curr;
1813 end = sseek (s, 0, SEEK_END);
1814 sseek (s, curr, SEEK_SET);
1815 return end;
1819 /* is_seekable()-- Return nonzero if the stream is seekable, zero if
1820 * it is not */
1823 is_seekable (stream *s)
1825 /* By convention, if file_length == -1, the file is not
1826 seekable. */
1827 return ((unix_stream *) s)->file_length!=-1;
1831 /* is_special()-- Return nonzero if the stream is not a regular file. */
1834 is_special (stream *s)
1836 return ((unix_stream *) s)->special_file;
1841 stream_isatty (stream *s)
1843 return isatty (((unix_stream *) s)->fd);
1847 stream_ttyname (stream *s __attribute__ ((unused)),
1848 char * buf __attribute__ ((unused)),
1849 size_t buflen __attribute__ ((unused)))
1851 #ifdef HAVE_TTYNAME_R
1852 return ttyname_r (((unix_stream *) s)->fd, buf, buflen);
1853 #elif defined HAVE_TTYNAME
1854 char *p;
1855 size_t plen;
1856 p = ttyname (((unix_stream *) s)->fd);
1857 if (!p)
1858 return errno;
1859 plen = strlen (p);
1860 if (buflen < plen)
1861 plen = buflen;
1862 memcpy (buf, p, plen);
1863 return 0;
1864 #else
1865 return ENOSYS;
1866 #endif
1872 /* How files are stored: This is an operating-system specific issue,
1873 and therefore belongs here. There are three cases to consider.
1875 Direct Access:
1876 Records are written as block of bytes corresponding to the record
1877 length of the file. This goes for both formatted and unformatted
1878 records. Positioning is done explicitly for each data transfer,
1879 so positioning is not much of an issue.
1881 Sequential Formatted:
1882 Records are separated by newline characters. The newline character
1883 is prohibited from appearing in a string. If it does, this will be
1884 messed up on the next read. End of file is also the end of a record.
1886 Sequential Unformatted:
1887 In this case, we are merely copying bytes to and from main storage,
1888 yet we need to keep track of varying record lengths. We adopt
1889 the solution used by f2c. Each record contains a pair of length
1890 markers:
1892 Length of record n in bytes
1893 Data of record n
1894 Length of record n in bytes
1896 Length of record n+1 in bytes
1897 Data of record n+1
1898 Length of record n+1 in bytes
1900 The length is stored at the end of a record to allow backspacing to the
1901 previous record. Between data transfer statements, the file pointer
1902 is left pointing to the first length of the current record.
1904 ENDFILE records are never explicitly stored.