OSDN Git Service

gcc/fortran/
[pf3gnuchains/gcc-fork.git] / libgfortran / io / unix.c
1 /* Copyright (C) 2002, 2003, 2004, 2005
2    Free Software Foundation, Inc.
3    Contributed by Andy Vaught
4
5 This file is part of the GNU Fortran 95 runtime library (libgfortran).
6
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.
11
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.)
20
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.
25
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, 51 Franklin Street, Fifth Floor,
29 Boston, MA 02110-1301, USA.  */
30
31 /* Unix stream I/O module */
32
33 #include "config.h"
34 #include <stdlib.h>
35 #include <limits.h>
36
37 #include <unistd.h>
38 #include <stdio.h>
39 #include <sys/stat.h>
40 #include <fcntl.h>
41 #include <assert.h>
42
43 #include <string.h>
44 #include <errno.h>
45
46 #include "libgfortran.h"
47 #include "io.h"
48 #include "unix.h"
49
50 #ifndef SSIZE_MAX
51 #define SSIZE_MAX SHRT_MAX
52 #endif
53
54 #ifndef PATH_MAX
55 #define PATH_MAX 1024
56 #endif
57
58 #ifndef PROT_READ
59 #define PROT_READ 1
60 #endif
61
62 #ifndef PROT_WRITE
63 #define PROT_WRITE 2
64 #endif
65
66 /* These flags aren't defined on all targets (mingw32), so provide them
67    here.  */
68 #ifndef S_IRGRP
69 #define S_IRGRP 0
70 #endif
71
72 #ifndef S_IWGRP
73 #define S_IWGRP 0
74 #endif
75
76 #ifndef S_IROTH
77 #define S_IROTH 0
78 #endif
79
80 #ifndef S_IWOTH
81 #define S_IWOTH 0
82 #endif
83
84 /* This implementation of stream I/O is based on the paper:
85  *
86  *  "Exploiting the advantages of mapped files for stream I/O",
87  *  O. Krieger, M. Stumm and R. Umrau, "Proceedings of the 1992 Winter
88  *  USENIX conference", p. 27-42.
89  *
90  * It differs in a number of ways from the version described in the
91  * paper.  First of all, threads are not an issue during I/O and we
92  * also don't have to worry about having multiple regions, since
93  * fortran's I/O model only allows you to be one place at a time.
94  *
95  * On the other hand, we have to be able to writing at the end of a
96  * stream, read from the start of a stream or read and write blocks of
97  * bytes from an arbitrary position.  After opening a file, a pointer
98  * to a stream structure is returned, which is used to handle file
99  * accesses until the file is closed.
100  *
101  * salloc_at_r(stream, len, where)-- Given a stream pointer, return a
102  * pointer to a block of memory that mirror the file at position
103  * 'where' that is 'len' bytes long.  The len integer is updated to
104  * reflect how many bytes were actually read.  The only reason for a
105  * short read is end of file.  The file pointer is updated.  The
106  * pointer is valid until the next call to salloc_*.
107  *
108  * salloc_at_w(stream, len, where)-- Given the stream pointer, returns
109  * a pointer to a block of memory that is updated to reflect the state
110  * of the file.  The length of the buffer is always equal to that
111  * requested.  The buffer must be completely set by the caller.  When
112  * data has been written, the sfree() function must be called to
113  * indicate that the caller is done writing data to the buffer.  This
114  * may or may not cause a physical write.
115  *
116  * Short forms of these are salloc_r() and salloc_w() which drop the
117  * 'where' parameter and use the current file pointer. */
118
119
120 /*move_pos_offset()--  Move the record pointer right or left
121  *relative to current position */
122
123 int
124 move_pos_offset (stream* st, int pos_off)
125 {
126   unix_stream * str = (unix_stream*)st;
127   if (pos_off < 0)
128     {
129       str->logical_offset += pos_off;
130
131       if (str->dirty_offset + str->ndirty > str->logical_offset)
132         {
133           if (str->ndirty + pos_off > 0)
134             str->ndirty += pos_off;
135           else
136             {
137               str->dirty_offset +=  pos_off + pos_off;
138               str->ndirty = 0;
139             }
140         }
141
142     return pos_off;
143   }
144   return 0;
145 }
146
147
148 /* fix_fd()-- Given a file descriptor, make sure it is not one of the
149  * standard descriptors, returning a non-standard descriptor.  If the
150  * user specifies that system errors should go to standard output,
151  * then closes standard output, we don't want the system errors to a
152  * file that has been given file descriptor 1 or 0.  We want to send
153  * the error to the invalid descriptor. */
154
155 static int
156 fix_fd (int fd)
157 {
158   int input, output, error;
159
160   input = output = error = 0;
161
162   /* Unix allocates the lowest descriptors first, so a loop is not
163      required, but this order is. */
164
165   if (fd == STDIN_FILENO)
166     {
167       fd = dup (fd);
168       input = 1;
169     }
170   if (fd == STDOUT_FILENO)
171     {
172       fd = dup (fd);
173       output = 1;
174     }
175   if (fd == STDERR_FILENO)
176     {
177       fd = dup (fd);
178       error = 1;
179     }
180
181   if (input)
182     close (STDIN_FILENO);
183   if (output)
184     close (STDOUT_FILENO);
185   if (error)
186     close (STDERR_FILENO);
187
188   return fd;
189 }
190
191 int
192 is_preconnected (stream * s)
193 {
194   int fd;
195
196   fd = ((unix_stream *) s)->fd;
197   if (fd == STDIN_FILENO || fd == STDOUT_FILENO || fd == STDERR_FILENO)
198     return 1;
199   else
200     return 0;
201 }
202
203 /* If the stream corresponds to a preconnected unit, we flush the
204    corresponding C stream.  This is bugware for mixed C-Fortran codes
205    where the C code doesn't flush I/O before returning.  */
206 void
207 flush_if_preconnected (stream * s)
208 {
209   int fd;
210
211   fd = ((unix_stream *) s)->fd;
212   if (fd == STDIN_FILENO)
213     fflush (stdin);
214   else if (fd == STDOUT_FILENO)
215     fflush (stdout);
216   else if (fd == STDERR_FILENO)
217     fflush (stderr);
218 }
219
220
221 /* Reset a stream after reading/writing. Assumes that the buffers have
222    been flushed.  */
223
224 inline static void
225 reset_stream (unix_stream * s, size_t bytes_rw)
226 {
227   s->physical_offset += bytes_rw;
228   s->logical_offset = s->physical_offset;
229   if (s->file_length != -1 && s->physical_offset > s->file_length)
230     s->file_length = s->physical_offset;
231 }
232
233
234 /* Read bytes into a buffer, allowing for short reads.  If the nbytes
235  * argument is less on return than on entry, it is because we've hit
236  * the end of file. */
237
238 static int
239 do_read (unix_stream * s, void * buf, size_t * nbytes)
240 {
241   ssize_t trans;
242   size_t bytes_left;
243   char *buf_st;
244   int status;
245
246   status = 0;
247   bytes_left = *nbytes;
248   buf_st = (char *) buf;
249
250   /* We must read in a loop since some systems don't restart system
251      calls in case of a signal.  */
252   while (bytes_left > 0)
253     {
254       /* Requests between SSIZE_MAX and SIZE_MAX are undefined by SUSv3,
255          so we must read in chunks smaller than SSIZE_MAX.  */
256       trans = (bytes_left < SSIZE_MAX) ? bytes_left : SSIZE_MAX;
257       trans = read (s->fd, buf_st, trans);
258       if (trans < 0)
259         {
260           if (errno == EINTR)
261             continue;
262           else
263             {
264               status = errno;
265               break;
266             }
267         }
268       else if (trans == 0) /* We hit EOF.  */
269         break;
270       buf_st += trans;
271       bytes_left -= trans;
272     }
273
274   *nbytes -= bytes_left;
275   return status;
276 }
277
278
279 /* Write a buffer to a stream, allowing for short writes.  */
280
281 static int
282 do_write (unix_stream * s, const void * buf, size_t * nbytes)
283 {
284   ssize_t trans;
285   size_t bytes_left;
286   char *buf_st;
287   int status;
288
289   status = 0;
290   bytes_left = *nbytes;
291   buf_st = (char *) buf;
292
293   /* We must write in a loop since some systems don't restart system
294      calls in case of a signal.  */
295   while (bytes_left > 0)
296     {
297       /* Requests between SSIZE_MAX and SIZE_MAX are undefined by SUSv3,
298          so we must write in chunks smaller than SSIZE_MAX.  */
299       trans = (bytes_left < SSIZE_MAX) ? bytes_left : SSIZE_MAX;
300       trans = write (s->fd, buf_st, trans);
301       if (trans < 0)
302         {
303           if (errno == EINTR)
304             continue;
305           else
306             {
307               status = errno;
308               break;
309             }
310         }
311       buf_st += trans;
312       bytes_left -= trans;
313     }
314
315   *nbytes -= bytes_left;
316   return status;
317 }
318
319
320 /* get_oserror()-- Get the most recent operating system error.  For
321  * unix, this is errno. */
322
323 const char *
324 get_oserror (void)
325 {
326   return strerror (errno);
327 }
328
329
330 /* sys_exit()-- Terminate the program with an exit code */
331
332 void
333 sys_exit (int code)
334 {
335   exit (code);
336 }
337
338
339 /*********************************************************************
340     File descriptor stream functions
341 *********************************************************************/
342
343
344 /* fd_flush()-- Write bytes that need to be written */
345
346 static try
347 fd_flush (unix_stream * s)
348 {
349   size_t writelen;
350
351   if (s->ndirty == 0)
352     return SUCCESS;;
353
354   if (s->physical_offset != s->dirty_offset &&
355       lseek (s->fd, s->dirty_offset, SEEK_SET) < 0)
356     return FAILURE;
357
358   writelen = s->ndirty;
359   if (do_write (s, s->buffer + (s->dirty_offset - s->buffer_offset),
360                 &writelen) != 0)
361     return FAILURE;
362
363   s->physical_offset = s->dirty_offset + writelen;
364
365   /* don't increment file_length if the file is non-seekable */
366   if (s->file_length != -1 && s->physical_offset > s->file_length)
367       s->file_length = s->physical_offset; 
368
369   s->ndirty -= writelen;
370   if (s->ndirty != 0)
371     return FAILURE;
372
373   return SUCCESS;
374 }
375
376
377 /* fd_alloc()-- Arrange a buffer such that the salloc() request can be
378  * satisfied.  This subroutine gets the buffer ready for whatever is
379  * to come next. */
380
381 static void
382 fd_alloc (unix_stream * s, gfc_offset where,
383           int *len __attribute__ ((unused)))
384 {
385   char *new_buffer;
386   int n, read_len;
387
388   if (*len <= BUFFER_SIZE)
389     {
390       new_buffer = s->small_buffer;
391       read_len = BUFFER_SIZE;
392     }
393   else
394     {
395       new_buffer = get_mem (*len);
396       read_len = *len;
397     }
398
399   /* Salvage bytes currently within the buffer.  This is important for
400    * devices that cannot seek. */
401
402   if (s->buffer != NULL && s->buffer_offset <= where &&
403       where <= s->buffer_offset + s->active)
404     {
405
406       n = s->active - (where - s->buffer_offset);
407       memmove (new_buffer, s->buffer + (where - s->buffer_offset), n);
408
409       s->active = n;
410     }
411   else
412     {                           /* new buffer starts off empty */
413       s->active = 0;
414     }
415
416   s->buffer_offset = where;
417
418   /* free the old buffer if necessary */
419
420   if (s->buffer != NULL && s->buffer != s->small_buffer)
421     free_mem (s->buffer);
422
423   s->buffer = new_buffer;
424   s->len = read_len;
425 }
426
427
428 /* fd_alloc_r_at()-- Allocate a stream buffer for reading.  Either
429  * we've already buffered the data or we need to load it.  Returns
430  * NULL on I/O error. */
431
432 static char *
433 fd_alloc_r_at (unix_stream * s, int *len, gfc_offset where)
434 {
435   gfc_offset m;
436
437   if (where == -1)
438     where = s->logical_offset;
439
440   if (s->buffer != NULL && s->buffer_offset <= where &&
441       where + *len <= s->buffer_offset + s->active)
442     {
443
444       /* Return a position within the current buffer */
445
446       s->logical_offset = where + *len;
447       return s->buffer + where - s->buffer_offset;
448     }
449
450   fd_alloc (s, where, len);
451
452   m = where + s->active;
453
454   if (s->physical_offset != m && lseek (s->fd, m, SEEK_SET) < 0)
455     return NULL;
456
457   /* do_read() hangs on read from terminals for *BSD-systems.  Only
458      use read() in that case.  */
459
460   if (s->special_file)
461     {
462       ssize_t n;
463
464       n = read (s->fd, s->buffer + s->active, s->len - s->active);
465       if (n < 0)
466         return NULL;
467
468       s->physical_offset = where + n;
469       s->active += n;
470     }
471   else
472     {
473       size_t n;
474
475       n = s->len - s->active;
476       if (do_read (s, s->buffer + s->active, &n) != 0)
477         return NULL;
478
479       s->physical_offset = where + n;
480       s->active += n;
481     }
482
483   if (s->active < *len)
484     *len = s->active;           /* Bytes actually available */
485
486   s->logical_offset = where + *len;
487
488   return s->buffer;
489 }
490
491
492 /* fd_alloc_w_at()-- Allocate a stream buffer for writing.  Either
493  * we've already buffered the data or we need to load it. */
494
495 static char *
496 fd_alloc_w_at (unix_stream * s, int *len, gfc_offset where)
497 {
498   gfc_offset n;
499
500   if (where == -1)
501     where = s->logical_offset;
502
503   if (s->buffer == NULL || s->buffer_offset > where ||
504       where + *len > s->buffer_offset + s->len)
505     {
506
507       if (fd_flush (s) == FAILURE)
508         return NULL;
509       fd_alloc (s, where, len);
510     }
511
512   /* Return a position within the current buffer */
513   if (s->ndirty == 0 
514       || where > s->dirty_offset + s->ndirty    
515       || s->dirty_offset > where + *len)
516     {  /* Discontiguous blocks, start with a clean buffer.  */  
517         /* Flush the buffer.  */  
518        if (s->ndirty != 0)    
519          fd_flush (s);  
520        s->dirty_offset = where;  
521        s->ndirty = *len;
522     }
523   else
524     {  
525       gfc_offset start;  /* Merge with the existing data.  */  
526       if (where < s->dirty_offset)    
527         start = where;  
528       else    
529         start = s->dirty_offset;  
530       if (where + *len > s->dirty_offset + s->ndirty)    
531         s->ndirty = where + *len - start;  
532       else    
533         s->ndirty = s->dirty_offset + s->ndirty - start;  
534         s->dirty_offset = start;
535     }
536
537   s->logical_offset = where + *len;
538
539   if (where + *len > s->file_length)
540     s->file_length = where + *len;
541
542   n = s->logical_offset - s->buffer_offset;
543   if (n > s->active)
544     s->active = n;
545
546   return s->buffer + where - s->buffer_offset;
547 }
548
549
550 static try
551 fd_sfree (unix_stream * s)
552 {
553   if (s->ndirty != 0 &&
554       (s->buffer != s->small_buffer || options.all_unbuffered ||
555        s->unbuffered))
556     return fd_flush (s);
557
558   return SUCCESS;
559 }
560
561
562 static try
563 fd_seek (unix_stream * s, gfc_offset offset)
564 {
565   if (s->physical_offset == offset) /* Are we lucky and avoid syscall?  */
566     {
567       s->logical_offset = offset;
568       return SUCCESS;
569     }
570
571   s->physical_offset = s->logical_offset = offset;
572
573   return (lseek (s->fd, offset, SEEK_SET) < 0) ? FAILURE : SUCCESS;
574 }
575
576
577 /* truncate_file()-- Given a unit, truncate the file at the current
578  * position.  Sets the physical location to the new end of the file.
579  * Returns nonzero on error. */
580
581 static try
582 fd_truncate (unix_stream * s)
583 {
584   if (lseek (s->fd, s->logical_offset, SEEK_SET) == -1)
585     return FAILURE;
586
587   /* non-seekable files, like terminals and fifo's fail the lseek.
588      Using ftruncate on a seekable special file (like /dev/null)
589      is undefined, so we treat it as if the ftruncate failed.
590   */
591 #ifdef HAVE_FTRUNCATE
592   if (s->special_file || ftruncate (s->fd, s->logical_offset))
593 #else
594 #ifdef HAVE_CHSIZE
595   if (s->special_file || chsize (s->fd, s->logical_offset))
596 #endif
597 #endif
598     {
599       s->physical_offset = s->file_length = 0;
600       return FAILURE;
601     }
602
603   s->physical_offset = s->file_length = s->logical_offset;
604
605   return SUCCESS;
606 }
607
608
609
610
611 /* Stream read function. Avoids using a buffer for big reads. The
612    interface is like POSIX read(), but the nbytes argument is a
613    pointer; on return it contains the number of bytes written. The
614    function return value is the status indicator (0 for success).  */
615
616 static int
617 fd_read (unix_stream * s, void * buf, size_t * nbytes)
618 {
619   void *p;
620   int tmp, status;
621
622   if (*nbytes < BUFFER_SIZE && !s->unbuffered)
623     {
624       tmp = *nbytes;
625       p = fd_alloc_r_at (s, &tmp, -1);
626       if (p)
627         {
628           *nbytes = tmp;
629           memcpy (buf, p, *nbytes);
630           return 0;
631         }
632       else
633         {
634           *nbytes = 0;
635           return errno;
636         }
637     }
638
639   /* If the request is bigger than BUFFER_SIZE we flush the buffers
640      and read directly.  */
641   if (fd_flush (s) == FAILURE)
642     {
643       *nbytes = 0;
644       return errno;
645     }
646
647   if (is_seekable ((stream *) s) && fd_seek (s, s->logical_offset) == FAILURE)
648     {
649       *nbytes = 0;
650       return errno;
651     }
652
653   status = do_read (s, buf, nbytes);
654   reset_stream (s, *nbytes);
655   return status;
656 }
657
658
659 /* Stream write function. Avoids using a buffer for big writes. The
660    interface is like POSIX write(), but the nbytes argument is a
661    pointer; on return it contains the number of bytes written. The
662    function return value is the status indicator (0 for success).  */
663
664 static int
665 fd_write (unix_stream * s, const void * buf, size_t * nbytes)
666 {
667   void *p;
668   int tmp, status;
669
670   if (*nbytes < BUFFER_SIZE && !s->unbuffered)
671     {
672       tmp = *nbytes;
673       p = fd_alloc_w_at (s, &tmp, -1);
674       if (p)
675         {
676           *nbytes = tmp;
677           memcpy (p, buf, *nbytes);
678           return 0;
679         }
680       else
681         {
682           *nbytes = 0;
683           return errno;
684         }
685     }
686
687   /* If the request is bigger than BUFFER_SIZE we flush the buffers
688      and write directly.  */
689   if (fd_flush (s) == FAILURE)
690     {
691       *nbytes = 0;
692       return errno;
693     }
694
695   if (is_seekable ((stream *) s) && fd_seek (s, s->logical_offset) == FAILURE)
696     {
697       *nbytes = 0;
698       return errno;
699     }
700
701   status =  do_write (s, buf, nbytes);
702   reset_stream (s, *nbytes);
703   return status;
704 }
705
706
707 static try
708 fd_close (unix_stream * s)
709 {
710   if (fd_flush (s) == FAILURE)
711     return FAILURE;
712
713   if (s->buffer != NULL && s->buffer != s->small_buffer)
714     free_mem (s->buffer);
715
716   if (s->fd != STDOUT_FILENO && s->fd != STDERR_FILENO)
717     {
718       if (close (s->fd) < 0)
719         return FAILURE;
720     }
721
722   free_mem (s);
723
724   return SUCCESS;
725 }
726
727
728 static void
729 fd_open (unix_stream * s)
730 {
731   if (isatty (s->fd))
732     s->unbuffered = 1;
733
734   s->st.alloc_r_at = (void *) fd_alloc_r_at;
735   s->st.alloc_w_at = (void *) fd_alloc_w_at;
736   s->st.sfree = (void *) fd_sfree;
737   s->st.close = (void *) fd_close;
738   s->st.seek = (void *) fd_seek;
739   s->st.truncate = (void *) fd_truncate;
740   s->st.read = (void *) fd_read;
741   s->st.write = (void *) fd_write;
742
743   s->buffer = NULL;
744 }
745
746
747
748
749 /*********************************************************************
750   memory stream functions - These are used for internal files
751
752   The idea here is that a single stream structure is created and all
753   requests must be satisfied from it.  The location and size of the
754   buffer is the character variable supplied to the READ or WRITE
755   statement.
756
757 *********************************************************************/
758
759
760 static char *
761 mem_alloc_r_at (unix_stream * s, int *len, gfc_offset where)
762 {
763   gfc_offset n;
764
765   if (where == -1)
766     where = s->logical_offset;
767
768   if (where < s->buffer_offset || where > s->buffer_offset + s->active)
769     return NULL;
770
771   s->logical_offset = where + *len;
772
773   n = s->buffer_offset + s->active - where;
774   if (*len > n)
775     *len = n;
776
777   return s->buffer + (where - s->buffer_offset);
778 }
779
780
781 static char *
782 mem_alloc_w_at (unix_stream * s, int *len, gfc_offset where)
783 {
784   gfc_offset m;
785
786   assert (*len >= 0);  /* Negative values not allowed. */
787   
788   if (where == -1)
789     where = s->logical_offset;
790
791   m = where + *len;
792
793   if (where < s->buffer_offset)
794     return NULL;
795
796   if (m > s->file_length)
797     return NULL;
798
799   s->logical_offset = m;
800
801   return s->buffer + (where - s->buffer_offset);
802 }
803
804
805 /* Stream read function for internal units. This is not actually used
806    at the moment, as all internal IO is formatted and the formatted IO
807    routines use mem_alloc_r_at.  */
808
809 static int
810 mem_read (unix_stream * s, void * buf, size_t * nbytes)
811 {
812   void *p;
813   int tmp;
814
815   tmp = *nbytes;
816   p = mem_alloc_r_at (s, &tmp, -1);
817   if (p)
818     {
819       *nbytes = tmp;
820       memcpy (buf, p, *nbytes);
821       return 0;
822     }
823   else
824     {
825       *nbytes = 0;
826       return errno;
827     }
828 }
829
830
831 /* Stream write function for internal units. This is not actually used
832    at the moment, as all internal IO is formatted and the formatted IO
833    routines use mem_alloc_w_at.  */
834
835 static int
836 mem_write (unix_stream * s, const void * buf, size_t * nbytes)
837 {
838   void *p;
839   int tmp;
840
841   errno = 0;
842
843   tmp = *nbytes;
844   p = mem_alloc_w_at (s, &tmp, -1);
845   if (p)
846     {
847       *nbytes = tmp;
848       memcpy (p, buf, *nbytes);
849       return 0;
850     }
851   else
852     {
853       *nbytes = 0;
854       return errno;
855     }
856 }
857
858
859 static int
860 mem_seek (unix_stream * s, gfc_offset offset)
861 {
862   if (offset > s->file_length)
863     {
864       errno = ESPIPE;
865       return FAILURE;
866     }
867
868   s->logical_offset = offset;
869   return SUCCESS;
870 }
871
872
873 static int
874 mem_truncate (unix_stream * s __attribute__ ((unused)))
875 {
876   return SUCCESS;
877 }
878
879
880 static try
881 mem_close (unix_stream * s)
882 {
883   free_mem (s);
884
885   return SUCCESS;
886 }
887
888
889 static try
890 mem_sfree (unix_stream * s __attribute__ ((unused)))
891 {
892   return SUCCESS;
893 }
894
895
896
897 /*********************************************************************
898   Public functions -- A reimplementation of this module needs to
899   define functional equivalents of the following.
900 *********************************************************************/
901
902 /* empty_internal_buffer()-- Zero the buffer of Internal file */
903
904 void
905 empty_internal_buffer(stream *strm)
906 {
907   unix_stream * s = (unix_stream *) strm;
908   memset(s->buffer, ' ', s->file_length);
909 }
910
911 /* open_internal()-- Returns a stream structure from an internal file */
912
913 stream *
914 open_internal (char *base, int length)
915 {
916   unix_stream *s;
917
918   s = get_mem (sizeof (unix_stream));
919   memset (s, '\0', sizeof (unix_stream));
920
921   s->buffer = base;
922   s->buffer_offset = 0;
923
924   s->logical_offset = 0;
925   s->active = s->file_length = length;
926
927   s->st.alloc_r_at = (void *) mem_alloc_r_at;
928   s->st.alloc_w_at = (void *) mem_alloc_w_at;
929   s->st.sfree = (void *) mem_sfree;
930   s->st.close = (void *) mem_close;
931   s->st.seek = (void *) mem_seek;
932   s->st.truncate = (void *) mem_truncate;
933   s->st.read = (void *) mem_read;
934   s->st.write = (void *) mem_write;
935
936   return (stream *) s;
937 }
938
939
940 /* fd_to_stream()-- Given an open file descriptor, build a stream
941  * around it. */
942
943 static stream *
944 fd_to_stream (int fd, int prot)
945 {
946   struct stat statbuf;
947   unix_stream *s;
948
949   s = get_mem (sizeof (unix_stream));
950   memset (s, '\0', sizeof (unix_stream));
951
952   s->fd = fd;
953   s->buffer_offset = 0;
954   s->physical_offset = 0;
955   s->logical_offset = 0;
956   s->prot = prot;
957
958   /* Get the current length of the file. */
959
960   fstat (fd, &statbuf);
961   s->file_length = S_ISREG (statbuf.st_mode) ? statbuf.st_size : -1;
962   s->special_file = !S_ISREG (statbuf.st_mode);
963
964   fd_open (s);
965
966   return (stream *) s;
967 }
968
969
970 /* Given the Fortran unit number, convert it to a C file descriptor.  */
971
972 int
973 unit_to_fd (int unit)
974 {
975   gfc_unit *us;
976   int fd;
977
978   us = find_unit (unit);
979   if (us == NULL)
980     return -1;
981
982   fd = ((unix_stream *) us->s)->fd;
983   unlock_unit (us);
984   return fd;
985 }
986
987
988 /* unpack_filename()-- Given a fortran string and a pointer to a
989  * buffer that is PATH_MAX characters, convert the fortran string to a
990  * C string in the buffer.  Returns nonzero if this is not possible.  */
991
992 int
993 unpack_filename (char *cstring, const char *fstring, int len)
994 {
995   len = fstrlen (fstring, len);
996   if (len >= PATH_MAX)
997     return 1;
998
999   memmove (cstring, fstring, len);
1000   cstring[len] = '\0';
1001
1002   return 0;
1003 }
1004
1005
1006 /* tempfile()-- Generate a temporary filename for a scratch file and
1007  * open it.  mkstemp() opens the file for reading and writing, but the
1008  * library mode prevents anything that is not allowed.  The descriptor
1009  * is returned, which is -1 on error.  The template is pointed to by 
1010  * opp->file, which is copied into the unit structure
1011  * and freed later. */
1012
1013 static int
1014 tempfile (st_parameter_open *opp)
1015 {
1016   const char *tempdir;
1017   char *template;
1018   int fd;
1019
1020   tempdir = getenv ("GFORTRAN_TMPDIR");
1021   if (tempdir == NULL)
1022     tempdir = getenv ("TMP");
1023   if (tempdir == NULL)
1024     tempdir = getenv ("TEMP");
1025   if (tempdir == NULL)
1026     tempdir = DEFAULT_TEMPDIR;
1027
1028   template = get_mem (strlen (tempdir) + 20);
1029
1030   st_sprintf (template, "%s/gfortrantmpXXXXXX", tempdir);
1031
1032 #ifdef HAVE_MKSTEMP
1033
1034   fd = mkstemp (template);
1035
1036 #else /* HAVE_MKSTEMP */
1037
1038   if (mktemp (template))
1039     do
1040 #ifdef HAVE_CRLF
1041       fd = open (template, O_RDWR | O_CREAT | O_EXCL | O_BINARY,
1042                  S_IREAD | S_IWRITE);
1043 #else
1044       fd = open (template, O_RDWR | O_CREAT | O_EXCL, S_IREAD | S_IWRITE);
1045 #endif
1046     while (!(fd == -1 && errno == EEXIST) && mktemp (template));
1047   else
1048     fd = -1;
1049
1050 #endif /* HAVE_MKSTEMP */
1051
1052   if (fd < 0)
1053     free_mem (template);
1054   else
1055     {
1056       opp->file = template;
1057       opp->file_len = strlen (template);        /* Don't include trailing nul */
1058     }
1059
1060   return fd;
1061 }
1062
1063
1064 /* regular_file()-- Open a regular file.
1065  * Change flags->action if it is ACTION_UNSPECIFIED on entry,
1066  * unless an error occurs.
1067  * Returns the descriptor, which is less than zero on error. */
1068
1069 static int
1070 regular_file (st_parameter_open *opp, unit_flags *flags)
1071 {
1072   char path[PATH_MAX + 1];
1073   int mode;
1074   int rwflag;
1075   int crflag;
1076   int fd;
1077
1078   if (unpack_filename (path, opp->file, opp->file_len))
1079     {
1080       errno = ENOENT;           /* Fake an OS error */
1081       return -1;
1082     }
1083
1084   rwflag = 0;
1085
1086   switch (flags->action)
1087     {
1088     case ACTION_READ:
1089       rwflag = O_RDONLY;
1090       break;
1091
1092     case ACTION_WRITE:
1093       rwflag = O_WRONLY;
1094       break;
1095
1096     case ACTION_READWRITE:
1097     case ACTION_UNSPECIFIED:
1098       rwflag = O_RDWR;
1099       break;
1100
1101     default:
1102       internal_error (&opp->common, "regular_file(): Bad action");
1103     }
1104
1105   switch (flags->status)
1106     {
1107     case STATUS_NEW:
1108       crflag = O_CREAT | O_EXCL;
1109       break;
1110
1111     case STATUS_OLD:            /* open will fail if the file does not exist*/
1112       crflag = 0;
1113       break;
1114
1115     case STATUS_UNKNOWN:
1116     case STATUS_SCRATCH:
1117       crflag = O_CREAT;
1118       break;
1119
1120     case STATUS_REPLACE:
1121         crflag = O_CREAT | O_TRUNC;
1122       break;
1123
1124     default:
1125       internal_error (&opp->common, "regular_file(): Bad status");
1126     }
1127
1128   /* rwflag |= O_LARGEFILE; */
1129
1130 #ifdef HAVE_CRLF
1131   crflag |= O_BINARY;
1132 #endif
1133
1134   mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
1135   fd = open (path, rwflag | crflag, mode);
1136   if (flags->action != ACTION_UNSPECIFIED)
1137       return fd;
1138
1139   if (fd >= 0)
1140     {
1141       flags->action = ACTION_READWRITE;
1142       return fd;
1143     }
1144   if (errno != EACCES)
1145      return fd;
1146
1147   /* retry for read-only access */
1148   rwflag = O_RDONLY;
1149   fd = open (path, rwflag | crflag, mode);
1150   if (fd >=0)
1151     {
1152       flags->action = ACTION_READ;
1153       return fd;               /* success */
1154     }
1155   
1156   if (errno != EACCES)
1157     return fd;                 /* failure */
1158
1159   /* retry for write-only access */
1160   rwflag = O_WRONLY;
1161   fd = open (path, rwflag | crflag, mode);
1162   if (fd >=0)
1163     {
1164       flags->action = ACTION_WRITE;
1165       return fd;               /* success */
1166     }
1167   return fd;                   /* failure */
1168 }
1169
1170
1171 /* open_external()-- Open an external file, unix specific version.
1172  * Change flags->action if it is ACTION_UNSPECIFIED on entry.
1173  * Returns NULL on operating system error. */
1174
1175 stream *
1176 open_external (st_parameter_open *opp, unit_flags *flags)
1177 {
1178   int fd, prot;
1179
1180   if (flags->status == STATUS_SCRATCH)
1181     {
1182       fd = tempfile (opp);
1183       if (flags->action == ACTION_UNSPECIFIED)
1184         flags->action = ACTION_READWRITE;
1185
1186 #if HAVE_UNLINK_OPEN_FILE
1187       /* We can unlink scratch files now and it will go away when closed. */
1188       if (fd >= 0)
1189         unlink (opp->file);
1190 #endif
1191     }
1192   else
1193     {
1194       /* regular_file resets flags->action if it is ACTION_UNSPECIFIED and
1195        * if it succeeds */
1196       fd = regular_file (opp, flags);
1197     }
1198
1199   if (fd < 0)
1200     return NULL;
1201   fd = fix_fd (fd);
1202
1203   switch (flags->action)
1204     {
1205     case ACTION_READ:
1206       prot = PROT_READ;
1207       break;
1208
1209     case ACTION_WRITE:
1210       prot = PROT_WRITE;
1211       break;
1212
1213     case ACTION_READWRITE:
1214       prot = PROT_READ | PROT_WRITE;
1215       break;
1216
1217     default:
1218       internal_error (&opp->common, "open_external(): Bad action");
1219     }
1220
1221   return fd_to_stream (fd, prot);
1222 }
1223
1224
1225 /* input_stream()-- Return a stream pointer to the default input stream.
1226  * Called on initialization. */
1227
1228 stream *
1229 input_stream (void)
1230 {
1231   return fd_to_stream (STDIN_FILENO, PROT_READ);
1232 }
1233
1234
1235 /* output_stream()-- Return a stream pointer to the default output stream.
1236  * Called on initialization. */
1237
1238 stream *
1239 output_stream (void)
1240 {
1241   return fd_to_stream (STDOUT_FILENO, PROT_WRITE);
1242 }
1243
1244
1245 /* error_stream()-- Return a stream pointer to the default error stream.
1246  * Called on initialization. */
1247
1248 stream *
1249 error_stream (void)
1250 {
1251   return fd_to_stream (STDERR_FILENO, PROT_WRITE);
1252 }
1253
1254 /* init_error_stream()-- Return a pointer to the error stream.  This
1255  * subroutine is called when the stream is needed, rather than at
1256  * initialization.  We want to work even if memory has been seriously
1257  * corrupted. */
1258
1259 stream *
1260 init_error_stream (unix_stream *error)
1261 {
1262   memset (error, '\0', sizeof (*error));
1263
1264   error->fd = options.use_stderr ? STDERR_FILENO : STDOUT_FILENO;
1265
1266   error->st.alloc_w_at = (void *) fd_alloc_w_at;
1267   error->st.sfree = (void *) fd_sfree;
1268
1269   error->unbuffered = 1;
1270   error->buffer = error->small_buffer;
1271
1272   return (stream *) error;
1273 }
1274
1275
1276 /* compare_file_filename()-- Given an open stream and a fortran string
1277  * that is a filename, figure out if the file is the same as the
1278  * filename. */
1279
1280 int
1281 compare_file_filename (gfc_unit *u, const char *name, int len)
1282 {
1283   char path[PATH_MAX + 1];
1284   struct stat st1;
1285 #ifdef HAVE_WORKING_STAT
1286   struct stat st2;
1287 #endif
1288
1289   if (unpack_filename (path, name, len))
1290     return 0;                   /* Can't be the same */
1291
1292   /* If the filename doesn't exist, then there is no match with the
1293    * existing file. */
1294
1295   if (stat (path, &st1) < 0)
1296     return 0;
1297
1298 #ifdef HAVE_WORKING_STAT
1299   fstat (((unix_stream *) (u->s))->fd, &st2);
1300   return (st1.st_dev == st2.st_dev) && (st1.st_ino == st2.st_ino);
1301 #else
1302   if (len != u->file_len)
1303     return 0;
1304   return (memcmp(path, u->file, len) == 0);
1305 #endif
1306 }
1307
1308
1309 #ifdef HAVE_WORKING_STAT
1310 # define FIND_FILE0_DECL struct stat *st
1311 # define FIND_FILE0_ARGS st
1312 #else
1313 # define FIND_FILE0_DECL const char *file, gfc_charlen_type file_len
1314 # define FIND_FILE0_ARGS file, file_len
1315 #endif
1316
1317 /* find_file0()-- Recursive work function for find_file() */
1318
1319 static gfc_unit *
1320 find_file0 (gfc_unit *u, FIND_FILE0_DECL)
1321 {
1322   gfc_unit *v;
1323
1324   if (u == NULL)
1325     return NULL;
1326
1327 #ifdef HAVE_WORKING_STAT
1328   if (u->s != NULL
1329       && fstat (((unix_stream *) u->s)->fd, &st[1]) >= 0 &&
1330       st[0].st_dev == st[1].st_dev && st[0].st_ino == st[1].st_ino)
1331     return u;
1332 #else
1333   if (compare_string (u->file_len, u->file, file_len, file) == 0)
1334     return u;
1335 #endif
1336
1337   v = find_file0 (u->left, FIND_FILE0_ARGS);
1338   if (v != NULL)
1339     return v;
1340
1341   v = find_file0 (u->right, FIND_FILE0_ARGS);
1342   if (v != NULL)
1343     return v;
1344
1345   return NULL;
1346 }
1347
1348
1349 /* find_file()-- Take the current filename and see if there is a unit
1350  * that has the file already open.  Returns a pointer to the unit if so. */
1351
1352 gfc_unit *
1353 find_file (const char *file, gfc_charlen_type file_len)
1354 {
1355   char path[PATH_MAX + 1];
1356   struct stat st[2];
1357   gfc_unit *u;
1358
1359   if (unpack_filename (path, file, file_len))
1360     return NULL;
1361
1362   if (stat (path, &st[0]) < 0)
1363     return NULL;
1364
1365   __gthread_mutex_lock (&unit_lock);
1366 retry:
1367   u = find_file0 (unit_root, FIND_FILE0_ARGS);
1368   if (u != NULL)
1369     {
1370       /* Fast path.  */
1371       if (! __gthread_mutex_trylock (&u->lock))
1372         {
1373           /* assert (u->closed == 0); */
1374           __gthread_mutex_unlock (&unit_lock);
1375           return u;
1376         }
1377
1378       inc_waiting_locked (u);
1379     }
1380   __gthread_mutex_unlock (&unit_lock);
1381   if (u != NULL)
1382     {
1383       __gthread_mutex_lock (&u->lock);
1384       if (u->closed)
1385         {
1386           __gthread_mutex_lock (&unit_lock);
1387           __gthread_mutex_unlock (&u->lock);
1388           if (predec_waiting_locked (u) == 0)
1389             free_mem (u);
1390           goto retry;
1391         }
1392
1393       dec_waiting_unlocked (u);
1394     }
1395   return u;
1396 }
1397
1398 static gfc_unit *
1399 flush_all_units_1 (gfc_unit *u, int min_unit)
1400 {
1401   while (u != NULL)
1402     {
1403       if (u->unit_number > min_unit)
1404         {
1405           gfc_unit *r = flush_all_units_1 (u->left, min_unit);
1406           if (r != NULL)
1407             return r;
1408         }
1409       if (u->unit_number >= min_unit)
1410         {
1411           if (__gthread_mutex_trylock (&u->lock))
1412             return u;
1413           if (u->s)
1414             flush (u->s);
1415           __gthread_mutex_unlock (&u->lock);
1416         }
1417       u = u->right;
1418     }
1419   return NULL;
1420 }
1421
1422 void
1423 flush_all_units (void)
1424 {
1425   gfc_unit *u;
1426   int min_unit = 0;
1427
1428   __gthread_mutex_lock (&unit_lock);
1429   do
1430     {
1431       u = flush_all_units_1 (unit_root, min_unit);
1432       if (u != NULL)
1433         inc_waiting_locked (u);
1434       __gthread_mutex_unlock (&unit_lock);
1435       if (u == NULL)
1436         return;
1437
1438       __gthread_mutex_lock (&u->lock);
1439
1440       min_unit = u->unit_number + 1;
1441
1442       if (u->closed == 0)
1443         {
1444           flush (u->s);
1445           __gthread_mutex_lock (&unit_lock);
1446           __gthread_mutex_unlock (&u->lock);
1447           (void) predec_waiting_locked (u);
1448         }
1449       else
1450         {
1451           __gthread_mutex_lock (&unit_lock);
1452           __gthread_mutex_unlock (&u->lock);
1453           if (predec_waiting_locked (u) == 0)
1454             free_mem (u);
1455         }
1456     }
1457   while (1);
1458 }
1459
1460
1461 /* stream_at_bof()-- Returns nonzero if the stream is at the beginning
1462  * of the file. */
1463
1464 int
1465 stream_at_bof (stream * s)
1466 {
1467   unix_stream *us;
1468
1469   if (!is_seekable (s))
1470     return 0;
1471
1472   us = (unix_stream *) s;
1473
1474   return us->logical_offset == 0;
1475 }
1476
1477
1478 /* stream_at_eof()-- Returns nonzero if the stream is at the beginning
1479  * of the file. */
1480
1481 int
1482 stream_at_eof (stream * s)
1483 {
1484   unix_stream *us;
1485
1486   if (!is_seekable (s))
1487     return 0;
1488
1489   us = (unix_stream *) s;
1490
1491   return us->logical_offset == us->dirty_offset;
1492 }
1493
1494
1495 /* delete_file()-- Given a unit structure, delete the file associated
1496  * with the unit.  Returns nonzero if something went wrong. */
1497
1498 int
1499 delete_file (gfc_unit * u)
1500 {
1501   char path[PATH_MAX + 1];
1502
1503   if (unpack_filename (path, u->file, u->file_len))
1504     {                           /* Shouldn't be possible */
1505       errno = ENOENT;
1506       return 1;
1507     }
1508
1509   return unlink (path);
1510 }
1511
1512
1513 /* file_exists()-- Returns nonzero if the current filename exists on
1514  * the system */
1515
1516 int
1517 file_exists (const char *file, gfc_charlen_type file_len)
1518 {
1519   char path[PATH_MAX + 1];
1520   struct stat statbuf;
1521
1522   if (unpack_filename (path, file, file_len))
1523     return 0;
1524
1525   if (stat (path, &statbuf) < 0)
1526     return 0;
1527
1528   return 1;
1529 }
1530
1531
1532
1533 static const char yes[] = "YES", no[] = "NO", unknown[] = "UNKNOWN";
1534
1535 /* inquire_sequential()-- Given a fortran string, determine if the
1536  * file is suitable for sequential access.  Returns a C-style
1537  * string. */
1538
1539 const char *
1540 inquire_sequential (const char *string, int len)
1541 {
1542   char path[PATH_MAX + 1];
1543   struct stat statbuf;
1544
1545   if (string == NULL ||
1546       unpack_filename (path, string, len) || stat (path, &statbuf) < 0)
1547     return unknown;
1548
1549   if (S_ISREG (statbuf.st_mode) ||
1550       S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode))
1551     return yes;
1552
1553   if (S_ISDIR (statbuf.st_mode) || S_ISBLK (statbuf.st_mode))
1554     return no;
1555
1556   return unknown;
1557 }
1558
1559
1560 /* inquire_direct()-- Given a fortran string, determine if the file is
1561  * suitable for direct access.  Returns a C-style string. */
1562
1563 const char *
1564 inquire_direct (const char *string, int len)
1565 {
1566   char path[PATH_MAX + 1];
1567   struct stat statbuf;
1568
1569   if (string == NULL ||
1570       unpack_filename (path, string, len) || stat (path, &statbuf) < 0)
1571     return unknown;
1572
1573   if (S_ISREG (statbuf.st_mode) || S_ISBLK (statbuf.st_mode))
1574     return yes;
1575
1576   if (S_ISDIR (statbuf.st_mode) ||
1577       S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode))
1578     return no;
1579
1580   return unknown;
1581 }
1582
1583
1584 /* inquire_formatted()-- Given a fortran string, determine if the file
1585  * is suitable for formatted form.  Returns a C-style string. */
1586
1587 const char *
1588 inquire_formatted (const char *string, int len)
1589 {
1590   char path[PATH_MAX + 1];
1591   struct stat statbuf;
1592
1593   if (string == NULL ||
1594       unpack_filename (path, string, len) || stat (path, &statbuf) < 0)
1595     return unknown;
1596
1597   if (S_ISREG (statbuf.st_mode) ||
1598       S_ISBLK (statbuf.st_mode) ||
1599       S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode))
1600     return yes;
1601
1602   if (S_ISDIR (statbuf.st_mode))
1603     return no;
1604
1605   return unknown;
1606 }
1607
1608
1609 /* inquire_unformatted()-- Given a fortran string, determine if the file
1610  * is suitable for unformatted form.  Returns a C-style string. */
1611
1612 const char *
1613 inquire_unformatted (const char *string, int len)
1614 {
1615   return inquire_formatted (string, len);
1616 }
1617
1618
1619 /* inquire_access()-- Given a fortran string, determine if the file is
1620  * suitable for access. */
1621
1622 static const char *
1623 inquire_access (const char *string, int len, int mode)
1624 {
1625   char path[PATH_MAX + 1];
1626
1627   if (string == NULL || unpack_filename (path, string, len) ||
1628       access (path, mode) < 0)
1629     return no;
1630
1631   return yes;
1632 }
1633
1634
1635 /* inquire_read()-- Given a fortran string, determine if the file is
1636  * suitable for READ access. */
1637
1638 const char *
1639 inquire_read (const char *string, int len)
1640 {
1641   return inquire_access (string, len, R_OK);
1642 }
1643
1644
1645 /* inquire_write()-- Given a fortran string, determine if the file is
1646  * suitable for READ access. */
1647
1648 const char *
1649 inquire_write (const char *string, int len)
1650 {
1651   return inquire_access (string, len, W_OK);
1652 }
1653
1654
1655 /* inquire_readwrite()-- Given a fortran string, determine if the file is
1656  * suitable for read and write access. */
1657
1658 const char *
1659 inquire_readwrite (const char *string, int len)
1660 {
1661   return inquire_access (string, len, R_OK | W_OK);
1662 }
1663
1664
1665 /* file_length()-- Return the file length in bytes, -1 if unknown */
1666
1667 gfc_offset
1668 file_length (stream * s)
1669 {
1670   return ((unix_stream *) s)->file_length;
1671 }
1672
1673
1674 /* file_position()-- Return the current position of the file */
1675
1676 gfc_offset
1677 file_position (stream * s)
1678 {
1679   return ((unix_stream *) s)->logical_offset;
1680 }
1681
1682
1683 /* is_seekable()-- Return nonzero if the stream is seekable, zero if
1684  * it is not */
1685
1686 int
1687 is_seekable (stream * s)
1688 {
1689   /* By convention, if file_length == -1, the file is not
1690      seekable.  */
1691   return ((unix_stream *) s)->file_length!=-1;
1692 }
1693
1694 try
1695 flush (stream *s)
1696 {
1697   return fd_flush( (unix_stream *) s);
1698 }
1699
1700 int
1701 stream_isatty (stream *s)
1702 {
1703   return isatty (((unix_stream *) s)->fd);
1704 }
1705
1706 char *
1707 stream_ttyname (stream *s)
1708 {
1709 #ifdef HAVE_TTYNAME
1710   return ttyname (((unix_stream *) s)->fd);
1711 #else
1712   return NULL;
1713 #endif
1714 }
1715
1716 gfc_offset
1717 stream_offset (stream *s)
1718 {
1719   return (((unix_stream *) s)->logical_offset);
1720 }
1721
1722
1723 /* How files are stored:  This is an operating-system specific issue,
1724    and therefore belongs here.  There are three cases to consider.
1725
1726    Direct Access:
1727       Records are written as block of bytes corresponding to the record
1728       length of the file.  This goes for both formatted and unformatted
1729       records.  Positioning is done explicitly for each data transfer,
1730       so positioning is not much of an issue.
1731
1732    Sequential Formatted:
1733       Records are separated by newline characters.  The newline character
1734       is prohibited from appearing in a string.  If it does, this will be
1735       messed up on the next read.  End of file is also the end of a record.
1736
1737    Sequential Unformatted:
1738       In this case, we are merely copying bytes to and from main storage,
1739       yet we need to keep track of varying record lengths.  We adopt
1740       the solution used by f2c.  Each record contains a pair of length
1741       markers:
1742
1743         Length of record n in bytes
1744         Data of record n
1745         Length of record n in bytes
1746
1747         Length of record n+1 in bytes
1748         Data of record n+1
1749         Length of record n+1 in bytes
1750
1751      The length is stored at the end of a record to allow backspacing to the
1752      previous record.  Between data transfer statements, the file pointer
1753      is left pointing to the first length of the current record.
1754
1755      ENDFILE records are never explicitly stored.
1756
1757 */