PR 47432 Use ttyname_r() if available
[official-gcc.git] / libgfortran / io / unix.c
blob004e8606c0a064163d16518d196e4f7d49e9f053
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 if ((mode & R_OK) && open (path, O_RDONLY) < 0)
148 return -1;
150 if ((mode & W_OK) && open (path, O_WRONLY) < 0)
151 return -1;
153 if (mode == F_OK)
155 gfstat_t st;
156 return stat (path, &st);
159 return 0;
162 #undef access
163 #define access fallback_access
164 #endif
167 /* Unix and internal stream I/O module */
169 static const int BUFFER_SIZE = 8192;
171 typedef struct
173 stream st;
175 gfc_offset buffer_offset; /* File offset of the start of the buffer */
176 gfc_offset physical_offset; /* Current physical file offset */
177 gfc_offset logical_offset; /* Current logical file offset */
178 gfc_offset file_length; /* Length of the file, -1 if not seekable. */
180 char *buffer; /* Pointer to the buffer. */
181 int fd; /* The POSIX file descriptor. */
183 int active; /* Length of valid bytes in the buffer */
185 int ndirty; /* Dirty bytes starting at buffer_offset */
187 int special_file; /* =1 if the fd refers to a special file */
189 /* Cached stat(2) values. */
190 dev_t st_dev;
191 ino_t st_ino;
193 unix_stream;
196 /* fix_fd()-- Given a file descriptor, make sure it is not one of the
197 * standard descriptors, returning a non-standard descriptor. If the
198 * user specifies that system errors should go to standard output,
199 * then closes standard output, we don't want the system errors to a
200 * file that has been given file descriptor 1 or 0. We want to send
201 * the error to the invalid descriptor. */
203 static int
204 fix_fd (int fd)
206 #ifdef HAVE_DUP
207 int input, output, error;
209 input = output = error = 0;
211 /* Unix allocates the lowest descriptors first, so a loop is not
212 required, but this order is. */
213 if (fd == STDIN_FILENO)
215 fd = dup (fd);
216 input = 1;
218 if (fd == STDOUT_FILENO)
220 fd = dup (fd);
221 output = 1;
223 if (fd == STDERR_FILENO)
225 fd = dup (fd);
226 error = 1;
229 if (input)
230 close (STDIN_FILENO);
231 if (output)
232 close (STDOUT_FILENO);
233 if (error)
234 close (STDERR_FILENO);
235 #endif
237 return fd;
241 /* If the stream corresponds to a preconnected unit, we flush the
242 corresponding C stream. This is bugware for mixed C-Fortran codes
243 where the C code doesn't flush I/O before returning. */
244 void
245 flush_if_preconnected (stream * s)
247 int fd;
249 fd = ((unix_stream *) s)->fd;
250 if (fd == STDIN_FILENO)
251 fflush (stdin);
252 else if (fd == STDOUT_FILENO)
253 fflush (stdout);
254 else if (fd == STDERR_FILENO)
255 fflush (stderr);
259 /********************************************************************
260 Raw I/O functions (read, write, seek, tell, truncate, close).
262 These functions wrap the basic POSIX I/O syscalls. Any deviation in
263 semantics is a bug, except the following: write restarts in case
264 of being interrupted by a signal, and as the first argument the
265 functions take the unix_stream struct rather than an integer file
266 descriptor. Also, for POSIX read() and write() a nbyte argument larger
267 than SSIZE_MAX is undefined; here the type of nbyte is ssize_t rather
268 than size_t as for POSIX read/write.
269 *********************************************************************/
271 static int
272 raw_flush (unix_stream * s __attribute__ ((unused)))
274 return 0;
277 static ssize_t
278 raw_read (unix_stream * s, void * buf, ssize_t nbyte)
280 /* For read we can't do I/O in a loop like raw_write does, because
281 that will break applications that wait for interactive I/O. */
282 return read (s->fd, buf, nbyte);
285 static ssize_t
286 raw_write (unix_stream * s, const void * buf, ssize_t nbyte)
288 ssize_t trans, bytes_left;
289 char *buf_st;
291 bytes_left = nbyte;
292 buf_st = (char *) buf;
294 /* We must write in a loop since some systems don't restart system
295 calls in case of a signal. */
296 while (bytes_left > 0)
298 trans = write (s->fd, buf_st, bytes_left);
299 if (trans < 0)
301 if (errno == EINTR)
302 continue;
303 else
304 return trans;
306 buf_st += trans;
307 bytes_left -= trans;
310 return nbyte - bytes_left;
313 static gfc_offset
314 raw_seek (unix_stream * s, gfc_offset offset, int whence)
316 return lseek (s->fd, offset, whence);
319 static gfc_offset
320 raw_tell (unix_stream * s)
322 return lseek (s->fd, 0, SEEK_CUR);
325 static int
326 raw_truncate (unix_stream * s, gfc_offset length)
328 #ifdef __MINGW32__
329 HANDLE h;
330 gfc_offset cur;
332 if (isatty (s->fd))
334 errno = EBADF;
335 return -1;
337 h = (HANDLE) _get_osfhandle (s->fd);
338 if (h == INVALID_HANDLE_VALUE)
340 errno = EBADF;
341 return -1;
343 cur = lseek (s->fd, 0, SEEK_CUR);
344 if (cur == -1)
345 return -1;
346 if (lseek (s->fd, length, SEEK_SET) == -1)
347 goto error;
348 if (!SetEndOfFile (h))
350 errno = EBADF;
351 goto error;
353 if (lseek (s->fd, cur, SEEK_SET) == -1)
354 return -1;
355 return 0;
356 error:
357 lseek (s->fd, cur, SEEK_SET);
358 return -1;
359 #elif defined HAVE_FTRUNCATE
360 return ftruncate (s->fd, length);
361 #elif defined HAVE_CHSIZE
362 return chsize (s->fd, length);
363 #else
364 runtime_error ("required ftruncate or chsize support not present");
365 return -1;
366 #endif
369 static int
370 raw_close (unix_stream * s)
372 int retval;
374 if (s->fd != STDOUT_FILENO
375 && s->fd != STDERR_FILENO
376 && s->fd != STDIN_FILENO)
377 retval = close (s->fd);
378 else
379 retval = 0;
380 free (s);
381 return retval;
384 static int
385 raw_init (unix_stream * s)
387 s->st.read = (void *) raw_read;
388 s->st.write = (void *) raw_write;
389 s->st.seek = (void *) raw_seek;
390 s->st.tell = (void *) raw_tell;
391 s->st.trunc = (void *) raw_truncate;
392 s->st.close = (void *) raw_close;
393 s->st.flush = (void *) raw_flush;
395 s->buffer = NULL;
396 return 0;
400 /*********************************************************************
401 Buffered I/O functions. These functions have the same semantics as the
402 raw I/O functions above, except that they are buffered in order to
403 improve performance. The buffer must be flushed when switching from
404 reading to writing and vice versa.
405 *********************************************************************/
407 static int
408 buf_flush (unix_stream * s)
410 int writelen;
412 /* Flushing in read mode means discarding read bytes. */
413 s->active = 0;
415 if (s->ndirty == 0)
416 return 0;
418 if (s->file_length != -1 && s->physical_offset != s->buffer_offset
419 && lseek (s->fd, s->buffer_offset, SEEK_SET) < 0)
420 return -1;
422 writelen = raw_write (s, s->buffer, s->ndirty);
424 s->physical_offset = s->buffer_offset + writelen;
426 /* Don't increment file_length if the file is non-seekable. */
427 if (s->file_length != -1 && s->physical_offset > s->file_length)
428 s->file_length = s->physical_offset;
430 s->ndirty -= writelen;
431 if (s->ndirty != 0)
432 return -1;
434 #ifdef _WIN32
435 _commit (s->fd);
436 #endif
438 return 0;
441 static ssize_t
442 buf_read (unix_stream * s, void * buf, ssize_t nbyte)
444 if (s->active == 0)
445 s->buffer_offset = s->logical_offset;
447 /* Is the data we want in the buffer? */
448 if (s->logical_offset + nbyte <= s->buffer_offset + s->active
449 && s->buffer_offset <= s->logical_offset)
450 memcpy (buf, s->buffer + (s->logical_offset - s->buffer_offset), nbyte);
451 else
453 /* First copy the active bytes if applicable, then read the rest
454 either directly or filling the buffer. */
455 char *p;
456 int nread = 0;
457 ssize_t to_read, did_read;
458 gfc_offset new_logical;
460 p = (char *) buf;
461 if (s->logical_offset >= s->buffer_offset
462 && s->buffer_offset + s->active >= s->logical_offset)
464 nread = s->active - (s->logical_offset - s->buffer_offset);
465 memcpy (buf, s->buffer + (s->logical_offset - s->buffer_offset),
466 nread);
467 p += nread;
469 /* At this point we consider all bytes in the buffer discarded. */
470 to_read = nbyte - nread;
471 new_logical = s->logical_offset + nread;
472 if (s->file_length != -1 && s->physical_offset != new_logical
473 && lseek (s->fd, new_logical, SEEK_SET) < 0)
474 return -1;
475 s->buffer_offset = s->physical_offset = new_logical;
476 if (to_read <= BUFFER_SIZE/2)
478 did_read = raw_read (s, s->buffer, BUFFER_SIZE);
479 s->physical_offset += did_read;
480 s->active = did_read;
481 did_read = (did_read > to_read) ? to_read : did_read;
482 memcpy (p, s->buffer, did_read);
484 else
486 did_read = raw_read (s, p, to_read);
487 s->physical_offset += did_read;
488 s->active = 0;
490 nbyte = did_read + nread;
492 s->logical_offset += nbyte;
493 return nbyte;
496 static ssize_t
497 buf_write (unix_stream * s, const void * buf, ssize_t nbyte)
499 if (s->ndirty == 0)
500 s->buffer_offset = s->logical_offset;
502 /* Does the data fit into the buffer? As a special case, if the
503 buffer is empty and the request is bigger than BUFFER_SIZE/2,
504 write directly. This avoids the case where the buffer would have
505 to be flushed at every write. */
506 if (!(s->ndirty == 0 && nbyte > BUFFER_SIZE/2)
507 && s->logical_offset + nbyte <= s->buffer_offset + BUFFER_SIZE
508 && s->buffer_offset <= s->logical_offset
509 && s->buffer_offset + s->ndirty >= s->logical_offset)
511 memcpy (s->buffer + (s->logical_offset - s->buffer_offset), buf, nbyte);
512 int nd = (s->logical_offset - s->buffer_offset) + nbyte;
513 if (nd > s->ndirty)
514 s->ndirty = nd;
516 else
518 /* Flush, and either fill the buffer with the new data, or if
519 the request is bigger than the buffer size, write directly
520 bypassing the buffer. */
521 buf_flush (s);
522 if (nbyte <= BUFFER_SIZE/2)
524 memcpy (s->buffer, buf, nbyte);
525 s->buffer_offset = s->logical_offset;
526 s->ndirty += nbyte;
528 else
530 if (s->file_length != -1 && s->physical_offset != s->logical_offset)
532 if (lseek (s->fd, s->logical_offset, SEEK_SET) < 0)
533 return -1;
534 s->physical_offset = s->logical_offset;
537 nbyte = raw_write (s, buf, nbyte);
538 s->physical_offset += nbyte;
541 s->logical_offset += nbyte;
542 /* Don't increment file_length if the file is non-seekable. */
543 if (s->file_length != -1 && s->logical_offset > s->file_length)
544 s->file_length = s->logical_offset;
545 return nbyte;
548 static gfc_offset
549 buf_seek (unix_stream * s, gfc_offset offset, int whence)
551 switch (whence)
553 case SEEK_SET:
554 break;
555 case SEEK_CUR:
556 offset += s->logical_offset;
557 break;
558 case SEEK_END:
559 offset += s->file_length;
560 break;
561 default:
562 return -1;
564 if (offset < 0)
566 errno = EINVAL;
567 return -1;
569 s->logical_offset = offset;
570 return offset;
573 static gfc_offset
574 buf_tell (unix_stream * s)
576 return s->logical_offset;
579 static int
580 buf_truncate (unix_stream * s, gfc_offset length)
582 int r;
584 if (buf_flush (s) != 0)
585 return -1;
586 r = raw_truncate (s, length);
587 if (r == 0)
588 s->file_length = length;
589 return r;
592 static int
593 buf_close (unix_stream * s)
595 if (buf_flush (s) != 0)
596 return -1;
597 free (s->buffer);
598 return raw_close (s);
601 static int
602 buf_init (unix_stream * s)
604 s->st.read = (void *) buf_read;
605 s->st.write = (void *) buf_write;
606 s->st.seek = (void *) buf_seek;
607 s->st.tell = (void *) buf_tell;
608 s->st.trunc = (void *) buf_truncate;
609 s->st.close = (void *) buf_close;
610 s->st.flush = (void *) buf_flush;
612 s->buffer = get_mem (BUFFER_SIZE);
613 return 0;
617 /*********************************************************************
618 memory stream functions - These are used for internal files
620 The idea here is that a single stream structure is created and all
621 requests must be satisfied from it. The location and size of the
622 buffer is the character variable supplied to the READ or WRITE
623 statement.
625 *********************************************************************/
627 char *
628 mem_alloc_r (stream * strm, int * len)
630 unix_stream * s = (unix_stream *) strm;
631 gfc_offset n;
632 gfc_offset where = s->logical_offset;
634 if (where < s->buffer_offset || where > s->buffer_offset + s->active)
635 return NULL;
637 n = s->buffer_offset + s->active - where;
638 if (*len > n)
639 *len = n;
641 s->logical_offset = where + *len;
643 return s->buffer + (where - s->buffer_offset);
647 char *
648 mem_alloc_r4 (stream * strm, int * len)
650 unix_stream * s = (unix_stream *) strm;
651 gfc_offset n;
652 gfc_offset where = s->logical_offset;
654 if (where < s->buffer_offset || where > s->buffer_offset + s->active)
655 return NULL;
657 n = s->buffer_offset + s->active - where;
658 if (*len > n)
659 *len = n;
661 s->logical_offset = where + *len;
663 return s->buffer + (where - s->buffer_offset) * 4;
667 char *
668 mem_alloc_w (stream * strm, int * len)
670 unix_stream * s = (unix_stream *) strm;
671 gfc_offset m;
672 gfc_offset where = s->logical_offset;
674 m = where + *len;
676 if (where < s->buffer_offset)
677 return NULL;
679 if (m > s->file_length)
680 return NULL;
682 s->logical_offset = m;
684 return s->buffer + (where - s->buffer_offset);
688 gfc_char4_t *
689 mem_alloc_w4 (stream * strm, int * len)
691 unix_stream * s = (unix_stream *) strm;
692 gfc_offset m;
693 gfc_offset where = s->logical_offset;
694 gfc_char4_t *result = (gfc_char4_t *) s->buffer;
696 m = where + *len;
698 if (where < s->buffer_offset)
699 return NULL;
701 if (m > s->file_length)
702 return NULL;
704 s->logical_offset = m;
705 return &result[where - s->buffer_offset];
709 /* Stream read function for character(kine=1) internal units. */
711 static ssize_t
712 mem_read (stream * s, void * buf, ssize_t nbytes)
714 void *p;
715 int nb = nbytes;
717 p = mem_alloc_r (s, &nb);
718 if (p)
720 memcpy (buf, p, nb);
721 return (ssize_t) nb;
723 else
724 return 0;
728 /* Stream read function for chracter(kind=4) internal units. */
730 static ssize_t
731 mem_read4 (stream * s, void * buf, ssize_t nbytes)
733 void *p;
734 int nb = nbytes;
736 p = mem_alloc_r (s, &nb);
737 if (p)
739 memcpy (buf, p, nb);
740 return (ssize_t) nb;
742 else
743 return 0;
747 /* Stream write function for character(kind=1) internal units. */
749 static ssize_t
750 mem_write (stream * s, const void * buf, ssize_t nbytes)
752 void *p;
753 int nb = nbytes;
755 p = mem_alloc_w (s, &nb);
756 if (p)
758 memcpy (p, buf, nb);
759 return (ssize_t) nb;
761 else
762 return 0;
766 /* Stream write function for character(kind=4) internal units. */
768 static ssize_t
769 mem_write4 (stream * s, const void * buf, ssize_t nwords)
771 gfc_char4_t *p;
772 int nw = nwords;
774 p = mem_alloc_w4 (s, &nw);
775 if (p)
777 while (nw--)
778 *p++ = (gfc_char4_t) *((char *) buf);
779 return nwords;
781 else
782 return 0;
786 static gfc_offset
787 mem_seek (stream * strm, gfc_offset offset, int whence)
789 unix_stream * s = (unix_stream *) strm;
790 switch (whence)
792 case SEEK_SET:
793 break;
794 case SEEK_CUR:
795 offset += s->logical_offset;
796 break;
797 case SEEK_END:
798 offset += s->file_length;
799 break;
800 default:
801 return -1;
804 /* Note that for internal array I/O it's actually possible to have a
805 negative offset, so don't check for that. */
806 if (offset > s->file_length)
808 errno = EINVAL;
809 return -1;
812 s->logical_offset = offset;
814 /* Returning < 0 is the error indicator for sseek(), so return 0 if
815 offset is negative. Thus if the return value is 0, the caller
816 has to use stell() to get the real value of logical_offset. */
817 if (offset >= 0)
818 return offset;
819 return 0;
823 static gfc_offset
824 mem_tell (stream * s)
826 return ((unix_stream *)s)->logical_offset;
830 static int
831 mem_truncate (unix_stream * s __attribute__ ((unused)),
832 gfc_offset length __attribute__ ((unused)))
834 return 0;
838 static int
839 mem_flush (unix_stream * s __attribute__ ((unused)))
841 return 0;
845 static int
846 mem_close (unix_stream * s)
848 if (s != NULL)
849 free (s);
851 return 0;
855 /*********************************************************************
856 Public functions -- A reimplementation of this module needs to
857 define functional equivalents of the following.
858 *********************************************************************/
860 /* open_internal()-- Returns a stream structure from a character(kind=1)
861 internal file */
863 stream *
864 open_internal (char *base, int length, gfc_offset offset)
866 unix_stream *s;
868 s = get_mem (sizeof (unix_stream));
869 memset (s, '\0', sizeof (unix_stream));
871 s->buffer = base;
872 s->buffer_offset = offset;
874 s->logical_offset = 0;
875 s->active = s->file_length = length;
877 s->st.close = (void *) mem_close;
878 s->st.seek = (void *) mem_seek;
879 s->st.tell = (void *) mem_tell;
880 s->st.trunc = (void *) mem_truncate;
881 s->st.read = (void *) mem_read;
882 s->st.write = (void *) mem_write;
883 s->st.flush = (void *) mem_flush;
885 return (stream *) s;
888 /* open_internal4()-- Returns a stream structure from a character(kind=4)
889 internal file */
891 stream *
892 open_internal4 (char *base, int length, gfc_offset offset)
894 unix_stream *s;
896 s = get_mem (sizeof (unix_stream));
897 memset (s, '\0', sizeof (unix_stream));
899 s->buffer = base;
900 s->buffer_offset = offset;
902 s->logical_offset = 0;
903 s->active = s->file_length = length;
905 s->st.close = (void *) mem_close;
906 s->st.seek = (void *) mem_seek;
907 s->st.tell = (void *) mem_tell;
908 s->st.trunc = (void *) mem_truncate;
909 s->st.read = (void *) mem_read4;
910 s->st.write = (void *) mem_write4;
911 s->st.flush = (void *) mem_flush;
913 return (stream *) s;
917 /* fd_to_stream()-- Given an open file descriptor, build a stream
918 * around it. */
920 static stream *
921 fd_to_stream (int fd)
923 gfstat_t statbuf;
924 unix_stream *s;
926 s = get_mem (sizeof (unix_stream));
927 memset (s, '\0', sizeof (unix_stream));
929 s->fd = fd;
930 s->buffer_offset = 0;
931 s->physical_offset = 0;
932 s->logical_offset = 0;
934 /* Get the current length of the file. */
936 fstat (fd, &statbuf);
938 s->st_dev = statbuf.st_dev;
939 s->st_ino = statbuf.st_ino;
940 s->special_file = !S_ISREG (statbuf.st_mode);
942 if (S_ISREG (statbuf.st_mode))
943 s->file_length = statbuf.st_size;
944 else if (S_ISBLK (statbuf.st_mode))
946 /* Hopefully more portable than ioctl(fd, BLKGETSIZE64, &size)? */
947 gfc_offset cur = lseek (fd, 0, SEEK_CUR);
948 s->file_length = lseek (fd, 0, SEEK_END);
949 lseek (fd, cur, SEEK_SET);
951 else
952 s->file_length = -1;
954 if (!(S_ISREG (statbuf.st_mode) || S_ISBLK (statbuf.st_mode))
955 || options.all_unbuffered
956 ||(options.unbuffered_preconnected &&
957 (s->fd == STDIN_FILENO
958 || s->fd == STDOUT_FILENO
959 || s->fd == STDERR_FILENO))
960 || isatty (s->fd))
961 raw_init (s);
962 else
963 buf_init (s);
965 return (stream *) s;
969 /* Given the Fortran unit number, convert it to a C file descriptor. */
972 unit_to_fd (int unit)
974 gfc_unit *us;
975 int fd;
977 us = find_unit (unit);
978 if (us == NULL)
979 return -1;
981 fd = ((unix_stream *) us->s)->fd;
982 unlock_unit (us);
983 return fd;
987 /* unpack_filename()-- Given a fortran string and a pointer to a
988 * buffer that is PATH_MAX characters, convert the fortran string to a
989 * C string in the buffer. Returns nonzero if this is not possible. */
992 unpack_filename (char *cstring, const char *fstring, int len)
994 if (fstring == NULL)
995 return 1;
996 len = fstrlen (fstring, len);
997 if (len >= PATH_MAX)
998 return 1;
1000 memmove (cstring, fstring, len);
1001 cstring[len] = '\0';
1003 return 0;
1007 /* tempfile()-- Generate a temporary filename for a scratch file and
1008 * open it. mkstemp() opens the file for reading and writing, but the
1009 * library mode prevents anything that is not allowed. The descriptor
1010 * is returned, which is -1 on error. The template is pointed to by
1011 * opp->file, which is copied into the unit structure
1012 * and freed later. */
1014 static int
1015 tempfile (st_parameter_open *opp)
1017 const char *tempdir;
1018 char *template;
1019 const char *slash = "/";
1020 int fd;
1022 tempdir = getenv ("GFORTRAN_TMPDIR");
1023 #ifdef __MINGW32__
1024 if (tempdir == NULL)
1026 char buffer[MAX_PATH + 1];
1027 DWORD ret;
1028 ret = GetTempPath (MAX_PATH, buffer);
1029 /* If we are not able to get a temp-directory, we use
1030 current directory. */
1031 if (ret > MAX_PATH || !ret)
1032 buffer[0] = 0;
1033 else
1034 buffer[ret] = 0;
1035 tempdir = strdup (buffer);
1037 #else
1038 if (tempdir == NULL)
1039 tempdir = getenv ("TMP");
1040 if (tempdir == NULL)
1041 tempdir = getenv ("TEMP");
1042 if (tempdir == NULL)
1043 tempdir = DEFAULT_TEMPDIR;
1044 #endif
1045 /* Check for special case that tempdir contains slash
1046 or backslash at end. */
1047 if (*tempdir == 0 || tempdir[strlen (tempdir) - 1] == '/'
1048 #ifdef __MINGW32__
1049 || tempdir[strlen (tempdir) - 1] == '\\'
1050 #endif
1052 slash = "";
1054 template = get_mem (strlen (tempdir) + 20);
1056 #ifdef HAVE_MKSTEMP
1057 sprintf (template, "%s%sgfortrantmpXXXXXX", tempdir, slash);
1059 fd = mkstemp (template);
1061 #else /* HAVE_MKSTEMP */
1062 fd = -1;
1065 sprintf (template, "%s%sgfortrantmpXXXXXX", tempdir, slash);
1066 if (!mktemp (template))
1067 break;
1068 #if defined(HAVE_CRLF) && defined(O_BINARY)
1069 fd = open (template, O_RDWR | O_CREAT | O_EXCL | O_BINARY,
1070 S_IREAD | S_IWRITE);
1071 #else
1072 fd = open (template, O_RDWR | O_CREAT | O_EXCL, S_IREAD | S_IWRITE);
1073 #endif
1075 while (fd == -1 && errno == EEXIST);
1076 #endif /* HAVE_MKSTEMP */
1078 opp->file = template;
1079 opp->file_len = strlen (template); /* Don't include trailing nul */
1081 return fd;
1085 /* regular_file()-- Open a regular file.
1086 * Change flags->action if it is ACTION_UNSPECIFIED on entry,
1087 * unless an error occurs.
1088 * Returns the descriptor, which is less than zero on error. */
1090 static int
1091 regular_file (st_parameter_open *opp, unit_flags *flags)
1093 char path[PATH_MAX + 1];
1094 int mode;
1095 int rwflag;
1096 int crflag;
1097 int fd;
1099 if (unpack_filename (path, opp->file, opp->file_len))
1101 errno = ENOENT; /* Fake an OS error */
1102 return -1;
1105 #ifdef __CYGWIN__
1106 if (opp->file_len == 7)
1108 if (strncmp (path, "CONOUT$", 7) == 0
1109 || strncmp (path, "CONERR$", 7) == 0)
1111 fd = open ("/dev/conout", O_WRONLY);
1112 flags->action = ACTION_WRITE;
1113 return fd;
1117 if (opp->file_len == 6 && strncmp (path, "CONIN$", 6) == 0)
1119 fd = open ("/dev/conin", O_RDONLY);
1120 flags->action = ACTION_READ;
1121 return fd;
1123 #endif
1126 #ifdef __MINGW32__
1127 if (opp->file_len == 7)
1129 if (strncmp (path, "CONOUT$", 7) == 0
1130 || strncmp (path, "CONERR$", 7) == 0)
1132 fd = open ("CONOUT$", O_WRONLY);
1133 flags->action = ACTION_WRITE;
1134 return fd;
1138 if (opp->file_len == 6 && strncmp (path, "CONIN$", 6) == 0)
1140 fd = open ("CONIN$", O_RDONLY);
1141 flags->action = ACTION_READ;
1142 return fd;
1144 #endif
1146 rwflag = 0;
1148 switch (flags->action)
1150 case ACTION_READ:
1151 rwflag = O_RDONLY;
1152 break;
1154 case ACTION_WRITE:
1155 rwflag = O_WRONLY;
1156 break;
1158 case ACTION_READWRITE:
1159 case ACTION_UNSPECIFIED:
1160 rwflag = O_RDWR;
1161 break;
1163 default:
1164 internal_error (&opp->common, "regular_file(): Bad action");
1167 switch (flags->status)
1169 case STATUS_NEW:
1170 crflag = O_CREAT | O_EXCL;
1171 break;
1173 case STATUS_OLD: /* open will fail if the file does not exist*/
1174 crflag = 0;
1175 break;
1177 case STATUS_UNKNOWN:
1178 case STATUS_SCRATCH:
1179 crflag = O_CREAT;
1180 break;
1182 case STATUS_REPLACE:
1183 crflag = O_CREAT | O_TRUNC;
1184 break;
1186 default:
1187 internal_error (&opp->common, "regular_file(): Bad status");
1190 /* rwflag |= O_LARGEFILE; */
1192 #if defined(HAVE_CRLF) && defined(O_BINARY)
1193 crflag |= O_BINARY;
1194 #endif
1196 mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
1197 fd = open (path, rwflag | crflag, mode);
1198 if (flags->action != ACTION_UNSPECIFIED)
1199 return fd;
1201 if (fd >= 0)
1203 flags->action = ACTION_READWRITE;
1204 return fd;
1206 if (errno != EACCES && errno != EROFS)
1207 return fd;
1209 /* retry for read-only access */
1210 rwflag = O_RDONLY;
1211 fd = open (path, rwflag | crflag, mode);
1212 if (fd >=0)
1214 flags->action = ACTION_READ;
1215 return fd; /* success */
1218 if (errno != EACCES)
1219 return fd; /* failure */
1221 /* retry for write-only access */
1222 rwflag = O_WRONLY;
1223 fd = open (path, rwflag | crflag, mode);
1224 if (fd >=0)
1226 flags->action = ACTION_WRITE;
1227 return fd; /* success */
1229 return fd; /* failure */
1233 /* open_external()-- Open an external file, unix specific version.
1234 * Change flags->action if it is ACTION_UNSPECIFIED on entry.
1235 * Returns NULL on operating system error. */
1237 stream *
1238 open_external (st_parameter_open *opp, unit_flags *flags)
1240 int fd;
1242 if (flags->status == STATUS_SCRATCH)
1244 fd = tempfile (opp);
1245 if (flags->action == ACTION_UNSPECIFIED)
1246 flags->action = ACTION_READWRITE;
1248 #if HAVE_UNLINK_OPEN_FILE
1249 /* We can unlink scratch files now and it will go away when closed. */
1250 if (fd >= 0)
1251 unlink (opp->file);
1252 #endif
1254 else
1256 /* regular_file resets flags->action if it is ACTION_UNSPECIFIED and
1257 * if it succeeds */
1258 fd = regular_file (opp, flags);
1261 if (fd < 0)
1262 return NULL;
1263 fd = fix_fd (fd);
1265 return fd_to_stream (fd);
1269 /* input_stream()-- Return a stream pointer to the default input stream.
1270 * Called on initialization. */
1272 stream *
1273 input_stream (void)
1275 return fd_to_stream (STDIN_FILENO);
1279 /* output_stream()-- Return a stream pointer to the default output stream.
1280 * Called on initialization. */
1282 stream *
1283 output_stream (void)
1285 stream * s;
1287 #if defined(HAVE_CRLF) && defined(HAVE_SETMODE)
1288 setmode (STDOUT_FILENO, O_BINARY);
1289 #endif
1291 s = fd_to_stream (STDOUT_FILENO);
1292 return s;
1296 /* error_stream()-- Return a stream pointer to the default error stream.
1297 * Called on initialization. */
1299 stream *
1300 error_stream (void)
1302 stream * s;
1304 #if defined(HAVE_CRLF) && defined(HAVE_SETMODE)
1305 setmode (STDERR_FILENO, O_BINARY);
1306 #endif
1308 s = fd_to_stream (STDERR_FILENO);
1309 return s;
1313 /* st_vprintf()-- vprintf function for error output. To avoid buffer
1314 overruns, we limit the length of the buffer to ST_VPRINTF_SIZE. 2k
1315 is big enough to completely fill a 80x25 terminal, so it shuld be
1316 OK. We use a direct write() because it is simpler and least likely
1317 to be clobbered by memory corruption. Writing an error message
1318 longer than that is an error. */
1320 #define ST_VPRINTF_SIZE 2048
1323 st_vprintf (const char *format, va_list ap)
1325 static char buffer[ST_VPRINTF_SIZE];
1326 int written;
1327 int fd;
1329 fd = options.use_stderr ? STDERR_FILENO : STDOUT_FILENO;
1330 #ifdef HAVE_VSNPRINTF
1331 written = vsnprintf(buffer, ST_VPRINTF_SIZE, format, ap);
1332 #else
1333 written = vsprintf(buffer, format, ap);
1335 if (written >= ST_VPRINTF_SIZE-1)
1337 /* The error message was longer than our buffer. Ouch. Because
1338 we may have messed up things badly, report the error and
1339 quit. */
1340 #define ERROR_MESSAGE "Internal error: buffer overrun in st_vprintf()\n"
1341 write (fd, buffer, ST_VPRINTF_SIZE-1);
1342 write (fd, ERROR_MESSAGE, strlen(ERROR_MESSAGE));
1343 sys_exit(2);
1344 #undef ERROR_MESSAGE
1347 #endif
1349 written = write (fd, buffer, written);
1350 return written;
1353 /* st_printf()-- printf() function for error output. This just calls
1354 st_vprintf() to do the actual work. */
1357 st_printf (const char *format, ...)
1359 int written;
1360 va_list ap;
1361 va_start (ap, format);
1362 written = st_vprintf(format, ap);
1363 va_end (ap);
1364 return written;
1368 /* compare_file_filename()-- Given an open stream and a fortran string
1369 * that is a filename, figure out if the file is the same as the
1370 * filename. */
1373 compare_file_filename (gfc_unit *u, const char *name, int len)
1375 char path[PATH_MAX + 1];
1376 gfstat_t st;
1377 #ifdef HAVE_WORKING_STAT
1378 unix_stream *s;
1379 #else
1380 # ifdef __MINGW32__
1381 uint64_t id1, id2;
1382 # endif
1383 #endif
1385 if (unpack_filename (path, name, len))
1386 return 0; /* Can't be the same */
1388 /* If the filename doesn't exist, then there is no match with the
1389 * existing file. */
1391 if (stat (path, &st) < 0)
1392 return 0;
1394 #ifdef HAVE_WORKING_STAT
1395 s = (unix_stream *) (u->s);
1396 return (st.st_dev == s->st_dev) && (st.st_ino == s->st_ino);
1397 #else
1399 # ifdef __MINGW32__
1400 /* We try to match files by a unique ID. On some filesystems (network
1401 fs and FAT), we can't generate this unique ID, and will simply compare
1402 filenames. */
1403 id1 = id_from_path (path);
1404 id2 = id_from_fd (((unix_stream *) (u->s))->fd);
1405 if (id1 || id2)
1406 return (id1 == id2);
1407 # endif
1409 if (len != u->file_len)
1410 return 0;
1411 return (memcmp(path, u->file, len) == 0);
1412 #endif
1416 #ifdef HAVE_WORKING_STAT
1417 # define FIND_FILE0_DECL gfstat_t *st
1418 # define FIND_FILE0_ARGS st
1419 #else
1420 # define FIND_FILE0_DECL uint64_t id, const char *file, gfc_charlen_type file_len
1421 # define FIND_FILE0_ARGS id, file, file_len
1422 #endif
1424 /* find_file0()-- Recursive work function for find_file() */
1426 static gfc_unit *
1427 find_file0 (gfc_unit *u, FIND_FILE0_DECL)
1429 gfc_unit *v;
1430 #if defined(__MINGW32__) && !HAVE_WORKING_STAT
1431 uint64_t id1;
1432 #endif
1434 if (u == NULL)
1435 return NULL;
1437 #ifdef HAVE_WORKING_STAT
1438 if (u->s != NULL)
1440 unix_stream *s = (unix_stream *) (u->s);
1441 if (st[0].st_dev == s->st_dev && st[0].st_ino == s->st_ino)
1442 return u;
1444 #else
1445 # ifdef __MINGW32__
1446 if (u->s && ((id1 = id_from_fd (((unix_stream *) u->s)->fd)) || id1))
1448 if (id == id1)
1449 return u;
1451 else
1452 # endif
1453 if (compare_string (u->file_len, u->file, file_len, file) == 0)
1454 return u;
1455 #endif
1457 v = find_file0 (u->left, FIND_FILE0_ARGS);
1458 if (v != NULL)
1459 return v;
1461 v = find_file0 (u->right, FIND_FILE0_ARGS);
1462 if (v != NULL)
1463 return v;
1465 return NULL;
1469 /* find_file()-- Take the current filename and see if there is a unit
1470 * that has the file already open. Returns a pointer to the unit if so. */
1472 gfc_unit *
1473 find_file (const char *file, gfc_charlen_type file_len)
1475 char path[PATH_MAX + 1];
1476 gfstat_t st[1];
1477 gfc_unit *u;
1478 #if defined(__MINGW32__) && !HAVE_WORKING_STAT
1479 uint64_t id = 0ULL;
1480 #endif
1482 if (unpack_filename (path, file, file_len))
1483 return NULL;
1485 if (stat (path, &st[0]) < 0)
1486 return NULL;
1488 #if defined(__MINGW32__) && !HAVE_WORKING_STAT
1489 id = id_from_path (path);
1490 #endif
1492 __gthread_mutex_lock (&unit_lock);
1493 retry:
1494 u = find_file0 (unit_root, FIND_FILE0_ARGS);
1495 if (u != NULL)
1497 /* Fast path. */
1498 if (! __gthread_mutex_trylock (&u->lock))
1500 /* assert (u->closed == 0); */
1501 __gthread_mutex_unlock (&unit_lock);
1502 return u;
1505 inc_waiting_locked (u);
1507 __gthread_mutex_unlock (&unit_lock);
1508 if (u != NULL)
1510 __gthread_mutex_lock (&u->lock);
1511 if (u->closed)
1513 __gthread_mutex_lock (&unit_lock);
1514 __gthread_mutex_unlock (&u->lock);
1515 if (predec_waiting_locked (u) == 0)
1516 free (u);
1517 goto retry;
1520 dec_waiting_unlocked (u);
1522 return u;
1525 static gfc_unit *
1526 flush_all_units_1 (gfc_unit *u, int min_unit)
1528 while (u != NULL)
1530 if (u->unit_number > min_unit)
1532 gfc_unit *r = flush_all_units_1 (u->left, min_unit);
1533 if (r != NULL)
1534 return r;
1536 if (u->unit_number >= min_unit)
1538 if (__gthread_mutex_trylock (&u->lock))
1539 return u;
1540 if (u->s)
1541 sflush (u->s);
1542 __gthread_mutex_unlock (&u->lock);
1544 u = u->right;
1546 return NULL;
1549 void
1550 flush_all_units (void)
1552 gfc_unit *u;
1553 int min_unit = 0;
1555 __gthread_mutex_lock (&unit_lock);
1558 u = flush_all_units_1 (unit_root, min_unit);
1559 if (u != NULL)
1560 inc_waiting_locked (u);
1561 __gthread_mutex_unlock (&unit_lock);
1562 if (u == NULL)
1563 return;
1565 __gthread_mutex_lock (&u->lock);
1567 min_unit = u->unit_number + 1;
1569 if (u->closed == 0)
1571 sflush (u->s);
1572 __gthread_mutex_lock (&unit_lock);
1573 __gthread_mutex_unlock (&u->lock);
1574 (void) predec_waiting_locked (u);
1576 else
1578 __gthread_mutex_lock (&unit_lock);
1579 __gthread_mutex_unlock (&u->lock);
1580 if (predec_waiting_locked (u) == 0)
1581 free (u);
1584 while (1);
1588 /* delete_file()-- Given a unit structure, delete the file associated
1589 * with the unit. Returns nonzero if something went wrong. */
1592 delete_file (gfc_unit * u)
1594 char path[PATH_MAX + 1];
1596 if (unpack_filename (path, u->file, u->file_len))
1597 { /* Shouldn't be possible */
1598 errno = ENOENT;
1599 return 1;
1602 return unlink (path);
1606 /* file_exists()-- Returns nonzero if the current filename exists on
1607 * the system */
1610 file_exists (const char *file, gfc_charlen_type file_len)
1612 char path[PATH_MAX + 1];
1614 if (unpack_filename (path, file, file_len))
1615 return 0;
1617 return !(access (path, F_OK));
1621 /* file_size()-- Returns the size of the file. */
1623 GFC_IO_INT
1624 file_size (const char *file, gfc_charlen_type file_len)
1626 char path[PATH_MAX + 1];
1627 gfstat_t statbuf;
1629 if (unpack_filename (path, file, file_len))
1630 return -1;
1632 if (stat (path, &statbuf) < 0)
1633 return -1;
1635 return (GFC_IO_INT) statbuf.st_size;
1638 static const char yes[] = "YES", no[] = "NO", unknown[] = "UNKNOWN";
1640 /* inquire_sequential()-- Given a fortran string, determine if the
1641 * file is suitable for sequential access. Returns a C-style
1642 * string. */
1644 const char *
1645 inquire_sequential (const char *string, int len)
1647 char path[PATH_MAX + 1];
1648 gfstat_t statbuf;
1650 if (string == NULL ||
1651 unpack_filename (path, string, len) || stat (path, &statbuf) < 0)
1652 return unknown;
1654 if (S_ISREG (statbuf.st_mode) ||
1655 S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode))
1656 return unknown;
1658 if (S_ISDIR (statbuf.st_mode) || S_ISBLK (statbuf.st_mode))
1659 return no;
1661 return unknown;
1665 /* inquire_direct()-- Given a fortran string, determine if the file is
1666 * suitable for direct access. Returns a C-style string. */
1668 const char *
1669 inquire_direct (const char *string, int len)
1671 char path[PATH_MAX + 1];
1672 gfstat_t statbuf;
1674 if (string == NULL ||
1675 unpack_filename (path, string, len) || stat (path, &statbuf) < 0)
1676 return unknown;
1678 if (S_ISREG (statbuf.st_mode) || S_ISBLK (statbuf.st_mode))
1679 return unknown;
1681 if (S_ISDIR (statbuf.st_mode) ||
1682 S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode))
1683 return no;
1685 return unknown;
1689 /* inquire_formatted()-- Given a fortran string, determine if the file
1690 * is suitable for formatted form. Returns a C-style string. */
1692 const char *
1693 inquire_formatted (const char *string, int len)
1695 char path[PATH_MAX + 1];
1696 gfstat_t statbuf;
1698 if (string == NULL ||
1699 unpack_filename (path, string, len) || stat (path, &statbuf) < 0)
1700 return unknown;
1702 if (S_ISREG (statbuf.st_mode) ||
1703 S_ISBLK (statbuf.st_mode) ||
1704 S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode))
1705 return unknown;
1707 if (S_ISDIR (statbuf.st_mode))
1708 return no;
1710 return unknown;
1714 /* inquire_unformatted()-- Given a fortran string, determine if the file
1715 * is suitable for unformatted form. Returns a C-style string. */
1717 const char *
1718 inquire_unformatted (const char *string, int len)
1720 return inquire_formatted (string, len);
1724 /* inquire_access()-- Given a fortran string, determine if the file is
1725 * suitable for access. */
1727 static const char *
1728 inquire_access (const char *string, int len, int mode)
1730 char path[PATH_MAX + 1];
1732 if (string == NULL || unpack_filename (path, string, len) ||
1733 access (path, mode) < 0)
1734 return no;
1736 return yes;
1740 /* inquire_read()-- Given a fortran string, determine if the file is
1741 * suitable for READ access. */
1743 const char *
1744 inquire_read (const char *string, int len)
1746 return inquire_access (string, len, R_OK);
1750 /* inquire_write()-- Given a fortran string, determine if the file is
1751 * suitable for READ access. */
1753 const char *
1754 inquire_write (const char *string, int len)
1756 return inquire_access (string, len, W_OK);
1760 /* inquire_readwrite()-- Given a fortran string, determine if the file is
1761 * suitable for read and write access. */
1763 const char *
1764 inquire_readwrite (const char *string, int len)
1766 return inquire_access (string, len, R_OK | W_OK);
1770 /* file_length()-- Return the file length in bytes, -1 if unknown */
1772 gfc_offset
1773 file_length (stream * s)
1775 gfc_offset curr, end;
1776 if (!is_seekable (s))
1777 return -1;
1778 curr = stell (s);
1779 if (curr == -1)
1780 return curr;
1781 end = sseek (s, 0, SEEK_END);
1782 sseek (s, curr, SEEK_SET);
1783 return end;
1787 /* is_seekable()-- Return nonzero if the stream is seekable, zero if
1788 * it is not */
1791 is_seekable (stream *s)
1793 /* By convention, if file_length == -1, the file is not
1794 seekable. */
1795 return ((unix_stream *) s)->file_length!=-1;
1799 /* is_special()-- Return nonzero if the stream is not a regular file. */
1802 is_special (stream *s)
1804 return ((unix_stream *) s)->special_file;
1809 stream_isatty (stream *s)
1811 return isatty (((unix_stream *) s)->fd);
1815 stream_ttyname (stream *s __attribute__ ((unused)),
1816 char * buf __attribute__ ((unused)),
1817 size_t buflen __attribute__ ((unused)))
1819 #ifdef HAVE_TTYNAME_R
1820 return ttyname_r (((unix_stream *) s)->fd, buf, buflen);
1821 #elif defined HAVE_TTYNAME
1822 char *p;
1823 size_t plen;
1824 p = ttyname (((unix_stream *) s)->fd);
1825 if (!p)
1826 return errno;
1827 plen = strlen (p);
1828 if (buflen < plen)
1829 plen = buflen;
1830 memcpy (buf, p, plen);
1831 return 0;
1832 #else
1833 return ENOSYS;
1834 #endif
1840 /* How files are stored: This is an operating-system specific issue,
1841 and therefore belongs here. There are three cases to consider.
1843 Direct Access:
1844 Records are written as block of bytes corresponding to the record
1845 length of the file. This goes for both formatted and unformatted
1846 records. Positioning is done explicitly for each data transfer,
1847 so positioning is not much of an issue.
1849 Sequential Formatted:
1850 Records are separated by newline characters. The newline character
1851 is prohibited from appearing in a string. If it does, this will be
1852 messed up on the next read. End of file is also the end of a record.
1854 Sequential Unformatted:
1855 In this case, we are merely copying bytes to and from main storage,
1856 yet we need to keep track of varying record lengths. We adopt
1857 the solution used by f2c. Each record contains a pair of length
1858 markers:
1860 Length of record n in bytes
1861 Data of record n
1862 Length of record n in bytes
1864 Length of record n+1 in bytes
1865 Data of record n+1
1866 Length of record n+1 in bytes
1868 The length is stored at the end of a record to allow backspacing to the
1869 previous record. Between data transfer statements, the file pointer
1870 is left pointing to the first length of the current record.
1872 ENDFILE records are never explicitly stored.