OSDN Git Service

2006-03-09 Jerry DeLisle <jvdelisle@gcc.gnu.org>
[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 succeeded.
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 SUCCESS;
601     }
602
603   s->physical_offset = s->file_length = s->logical_offset;
604   s->active = 0;
605   return SUCCESS;
606 }
607
608
609 /* Similar to memset(), but operating on a stream instead of a string.
610    Takes care of not using too much memory.  */
611
612 static try
613 fd_sset (unix_stream * s, int c, size_t n)
614 {
615   size_t bytes_left;
616   int trans;
617   void *p;
618
619   bytes_left = n;
620
621   while (bytes_left > 0)
622     {
623       /* memset() in chunks of BUFFER_SIZE.  */
624       trans = (bytes_left < BUFFER_SIZE) ? bytes_left : BUFFER_SIZE;
625
626       p = fd_alloc_w_at (s, &trans, -1);
627       if (p)
628           memset (p, c, trans);
629       else
630         return FAILURE;
631
632       bytes_left -= trans;
633     }
634
635   return SUCCESS;
636 }
637
638
639 /* Stream read function. Avoids using a buffer for big reads. The
640    interface is like POSIX read(), but the nbytes argument is a
641    pointer; on return it contains the number of bytes written. The
642    function return value is the status indicator (0 for success).  */
643
644 static int
645 fd_read (unix_stream * s, void * buf, size_t * nbytes)
646 {
647   void *p;
648   int tmp, status;
649
650   if (*nbytes < BUFFER_SIZE && !s->unbuffered)
651     {
652       tmp = *nbytes;
653       p = fd_alloc_r_at (s, &tmp, -1);
654       if (p)
655         {
656           *nbytes = tmp;
657           memcpy (buf, p, *nbytes);
658           return 0;
659         }
660       else
661         {
662           *nbytes = 0;
663           return errno;
664         }
665     }
666
667   /* If the request is bigger than BUFFER_SIZE we flush the buffers
668      and read directly.  */
669   if (fd_flush (s) == FAILURE)
670     {
671       *nbytes = 0;
672       return errno;
673     }
674
675   if (is_seekable ((stream *) s) && fd_seek (s, s->logical_offset) == FAILURE)
676     {
677       *nbytes = 0;
678       return errno;
679     }
680
681   status = do_read (s, buf, nbytes);
682   reset_stream (s, *nbytes);
683   return status;
684 }
685
686
687 /* Stream write function. Avoids using a buffer for big writes. The
688    interface is like POSIX write(), but the nbytes argument is a
689    pointer; on return it contains the number of bytes written. The
690    function return value is the status indicator (0 for success).  */
691
692 static int
693 fd_write (unix_stream * s, const void * buf, size_t * nbytes)
694 {
695   void *p;
696   int tmp, status;
697
698   if (*nbytes < BUFFER_SIZE && !s->unbuffered)
699     {
700       tmp = *nbytes;
701       p = fd_alloc_w_at (s, &tmp, -1);
702       if (p)
703         {
704           *nbytes = tmp;
705           memcpy (p, buf, *nbytes);
706           return 0;
707         }
708       else
709         {
710           *nbytes = 0;
711           return errno;
712         }
713     }
714
715   /* If the request is bigger than BUFFER_SIZE we flush the buffers
716      and write directly.  */
717   if (fd_flush (s) == FAILURE)
718     {
719       *nbytes = 0;
720       return errno;
721     }
722
723   if (is_seekable ((stream *) s) && fd_seek (s, s->logical_offset) == FAILURE)
724     {
725       *nbytes = 0;
726       return errno;
727     }
728
729   status =  do_write (s, buf, nbytes);
730   reset_stream (s, *nbytes);
731   return status;
732 }
733
734
735 static try
736 fd_close (unix_stream * s)
737 {
738   if (fd_flush (s) == FAILURE)
739     return FAILURE;
740
741   if (s->buffer != NULL && s->buffer != s->small_buffer)
742     free_mem (s->buffer);
743
744   if (s->fd != STDOUT_FILENO && s->fd != STDERR_FILENO)
745     {
746       if (close (s->fd) < 0)
747         return FAILURE;
748     }
749
750   free_mem (s);
751
752   return SUCCESS;
753 }
754
755
756 static void
757 fd_open (unix_stream * s)
758 {
759   if (isatty (s->fd))
760     s->unbuffered = 1;
761
762   s->st.alloc_r_at = (void *) fd_alloc_r_at;
763   s->st.alloc_w_at = (void *) fd_alloc_w_at;
764   s->st.sfree = (void *) fd_sfree;
765   s->st.close = (void *) fd_close;
766   s->st.seek = (void *) fd_seek;
767   s->st.truncate = (void *) fd_truncate;
768   s->st.read = (void *) fd_read;
769   s->st.write = (void *) fd_write;
770   s->st.set = (void *) fd_sset;
771
772   s->buffer = NULL;
773 }
774
775
776
777
778 /*********************************************************************
779   memory stream functions - These are used for internal files
780
781   The idea here is that a single stream structure is created and all
782   requests must be satisfied from it.  The location and size of the
783   buffer is the character variable supplied to the READ or WRITE
784   statement.
785
786 *********************************************************************/
787
788
789 static char *
790 mem_alloc_r_at (unix_stream * s, int *len, gfc_offset where)
791 {
792   gfc_offset n;
793
794   if (where == -1)
795     where = s->logical_offset;
796
797   if (where < s->buffer_offset || where > s->buffer_offset + s->active)
798     return NULL;
799
800   s->logical_offset = where + *len;
801
802   n = s->buffer_offset + s->active - where;
803   if (*len > n)
804     *len = n;
805
806   return s->buffer + (where - s->buffer_offset);
807 }
808
809
810 static char *
811 mem_alloc_w_at (unix_stream * s, int *len, gfc_offset where)
812 {
813   gfc_offset m;
814
815   assert (*len >= 0);  /* Negative values not allowed. */
816   
817   if (where == -1)
818     where = s->logical_offset;
819
820   m = where + *len;
821
822   if (where < s->buffer_offset)
823     return NULL;
824
825   if (m > s->file_length)
826     return NULL;
827
828   s->logical_offset = m;
829
830   return s->buffer + (where - s->buffer_offset);
831 }
832
833
834 /* Stream read function for internal units. This is not actually used
835    at the moment, as all internal IO is formatted and the formatted IO
836    routines use mem_alloc_r_at.  */
837
838 static int
839 mem_read (unix_stream * s, void * buf, size_t * nbytes)
840 {
841   void *p;
842   int tmp;
843
844   tmp = *nbytes;
845   p = mem_alloc_r_at (s, &tmp, -1);
846   if (p)
847     {
848       *nbytes = tmp;
849       memcpy (buf, p, *nbytes);
850       return 0;
851     }
852   else
853     {
854       *nbytes = 0;
855       return errno;
856     }
857 }
858
859
860 /* Stream write function for internal units. This is not actually used
861    at the moment, as all internal IO is formatted and the formatted IO
862    routines use mem_alloc_w_at.  */
863
864 static int
865 mem_write (unix_stream * s, const void * buf, size_t * nbytes)
866 {
867   void *p;
868   int tmp;
869
870   errno = 0;
871
872   tmp = *nbytes;
873   p = mem_alloc_w_at (s, &tmp, -1);
874   if (p)
875     {
876       *nbytes = tmp;
877       memcpy (p, buf, *nbytes);
878       return 0;
879     }
880   else
881     {
882       *nbytes = 0;
883       return errno;
884     }
885 }
886
887
888 static int
889 mem_seek (unix_stream * s, gfc_offset offset)
890 {
891   if (offset > s->file_length)
892     {
893       errno = ESPIPE;
894       return FAILURE;
895     }
896
897   s->logical_offset = offset;
898   return SUCCESS;
899 }
900
901
902 static try
903 mem_set (unix_stream * s, int c, size_t n)
904 {
905   void *p;
906   int len;
907
908   len = n;
909   
910   p = mem_alloc_w_at (s, &len, -1);
911   if (p)
912     {
913       memset (p, c, len);
914       return SUCCESS;
915     }
916   else
917     return FAILURE;
918 }
919
920
921 static int
922 mem_truncate (unix_stream * s __attribute__ ((unused)))
923 {
924   return SUCCESS;
925 }
926
927
928 static try
929 mem_close (unix_stream * s)
930 {
931   free_mem (s);
932
933   return SUCCESS;
934 }
935
936
937 static try
938 mem_sfree (unix_stream * s __attribute__ ((unused)))
939 {
940   return SUCCESS;
941 }
942
943
944
945 /*********************************************************************
946   Public functions -- A reimplementation of this module needs to
947   define functional equivalents of the following.
948 *********************************************************************/
949
950 /* empty_internal_buffer()-- Zero the buffer of Internal file */
951
952 void
953 empty_internal_buffer(stream *strm)
954 {
955   unix_stream * s = (unix_stream *) strm;
956   memset(s->buffer, ' ', s->file_length);
957 }
958
959 /* open_internal()-- Returns a stream structure from an internal file */
960
961 stream *
962 open_internal (char *base, int length)
963 {
964   unix_stream *s;
965
966   s = get_mem (sizeof (unix_stream));
967   memset (s, '\0', sizeof (unix_stream));
968
969   s->buffer = base;
970   s->buffer_offset = 0;
971
972   s->logical_offset = 0;
973   s->active = s->file_length = length;
974
975   s->st.alloc_r_at = (void *) mem_alloc_r_at;
976   s->st.alloc_w_at = (void *) mem_alloc_w_at;
977   s->st.sfree = (void *) mem_sfree;
978   s->st.close = (void *) mem_close;
979   s->st.seek = (void *) mem_seek;
980   s->st.truncate = (void *) mem_truncate;
981   s->st.read = (void *) mem_read;
982   s->st.write = (void *) mem_write;
983   s->st.set = (void *) mem_set;
984
985   return (stream *) s;
986 }
987
988
989 /* fd_to_stream()-- Given an open file descriptor, build a stream
990  * around it. */
991
992 static stream *
993 fd_to_stream (int fd, int prot)
994 {
995   struct stat statbuf;
996   unix_stream *s;
997
998   s = get_mem (sizeof (unix_stream));
999   memset (s, '\0', sizeof (unix_stream));
1000
1001   s->fd = fd;
1002   s->buffer_offset = 0;
1003   s->physical_offset = 0;
1004   s->logical_offset = 0;
1005   s->prot = prot;
1006
1007   /* Get the current length of the file. */
1008
1009   fstat (fd, &statbuf);
1010   s->file_length = S_ISREG (statbuf.st_mode) ? statbuf.st_size : -1;
1011   s->special_file = !S_ISREG (statbuf.st_mode);
1012
1013   fd_open (s);
1014
1015   return (stream *) s;
1016 }
1017
1018
1019 /* Given the Fortran unit number, convert it to a C file descriptor.  */
1020
1021 int
1022 unit_to_fd (int unit)
1023 {
1024   gfc_unit *us;
1025   int fd;
1026
1027   us = find_unit (unit);
1028   if (us == NULL)
1029     return -1;
1030
1031   fd = ((unix_stream *) us->s)->fd;
1032   unlock_unit (us);
1033   return fd;
1034 }
1035
1036
1037 /* unpack_filename()-- Given a fortran string and a pointer to a
1038  * buffer that is PATH_MAX characters, convert the fortran string to a
1039  * C string in the buffer.  Returns nonzero if this is not possible.  */
1040
1041 int
1042 unpack_filename (char *cstring, const char *fstring, int len)
1043 {
1044   len = fstrlen (fstring, len);
1045   if (len >= PATH_MAX)
1046     return 1;
1047
1048   memmove (cstring, fstring, len);
1049   cstring[len] = '\0';
1050
1051   return 0;
1052 }
1053
1054
1055 /* tempfile()-- Generate a temporary filename for a scratch file and
1056  * open it.  mkstemp() opens the file for reading and writing, but the
1057  * library mode prevents anything that is not allowed.  The descriptor
1058  * is returned, which is -1 on error.  The template is pointed to by 
1059  * opp->file, which is copied into the unit structure
1060  * and freed later. */
1061
1062 static int
1063 tempfile (st_parameter_open *opp)
1064 {
1065   const char *tempdir;
1066   char *template;
1067   int fd;
1068
1069   tempdir = getenv ("GFORTRAN_TMPDIR");
1070   if (tempdir == NULL)
1071     tempdir = getenv ("TMP");
1072   if (tempdir == NULL)
1073     tempdir = getenv ("TEMP");
1074   if (tempdir == NULL)
1075     tempdir = DEFAULT_TEMPDIR;
1076
1077   template = get_mem (strlen (tempdir) + 20);
1078
1079   st_sprintf (template, "%s/gfortrantmpXXXXXX", tempdir);
1080
1081 #ifdef HAVE_MKSTEMP
1082
1083   fd = mkstemp (template);
1084
1085 #else /* HAVE_MKSTEMP */
1086
1087   if (mktemp (template))
1088     do
1089 #if defined(HAVE_CRLF) && defined(O_BINARY)
1090       fd = open (template, O_RDWR | O_CREAT | O_EXCL | O_BINARY,
1091                  S_IREAD | S_IWRITE);
1092 #else
1093       fd = open (template, O_RDWR | O_CREAT | O_EXCL, S_IREAD | S_IWRITE);
1094 #endif
1095     while (!(fd == -1 && errno == EEXIST) && mktemp (template));
1096   else
1097     fd = -1;
1098
1099 #endif /* HAVE_MKSTEMP */
1100
1101   if (fd < 0)
1102     free_mem (template);
1103   else
1104     {
1105       opp->file = template;
1106       opp->file_len = strlen (template);        /* Don't include trailing nul */
1107     }
1108
1109   return fd;
1110 }
1111
1112
1113 /* regular_file()-- Open a regular file.
1114  * Change flags->action if it is ACTION_UNSPECIFIED on entry,
1115  * unless an error occurs.
1116  * Returns the descriptor, which is less than zero on error. */
1117
1118 static int
1119 regular_file (st_parameter_open *opp, unit_flags *flags)
1120 {
1121   char path[PATH_MAX + 1];
1122   int mode;
1123   int rwflag;
1124   int crflag;
1125   int fd;
1126
1127   if (unpack_filename (path, opp->file, opp->file_len))
1128     {
1129       errno = ENOENT;           /* Fake an OS error */
1130       return -1;
1131     }
1132
1133   rwflag = 0;
1134
1135   switch (flags->action)
1136     {
1137     case ACTION_READ:
1138       rwflag = O_RDONLY;
1139       break;
1140
1141     case ACTION_WRITE:
1142       rwflag = O_WRONLY;
1143       break;
1144
1145     case ACTION_READWRITE:
1146     case ACTION_UNSPECIFIED:
1147       rwflag = O_RDWR;
1148       break;
1149
1150     default:
1151       internal_error (&opp->common, "regular_file(): Bad action");
1152     }
1153
1154   switch (flags->status)
1155     {
1156     case STATUS_NEW:
1157       crflag = O_CREAT | O_EXCL;
1158       break;
1159
1160     case STATUS_OLD:            /* open will fail if the file does not exist*/
1161       crflag = 0;
1162       break;
1163
1164     case STATUS_UNKNOWN:
1165     case STATUS_SCRATCH:
1166       crflag = O_CREAT;
1167       break;
1168
1169     case STATUS_REPLACE:
1170         crflag = O_CREAT | O_TRUNC;
1171       break;
1172
1173     default:
1174       internal_error (&opp->common, "regular_file(): Bad status");
1175     }
1176
1177   /* rwflag |= O_LARGEFILE; */
1178
1179 #if defined(HAVE_CRLF) && defined(O_BINARY)
1180   crflag |= O_BINARY;
1181 #endif
1182
1183   mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
1184   fd = open (path, rwflag | crflag, mode);
1185   if (flags->action != ACTION_UNSPECIFIED)
1186       return fd;
1187
1188   if (fd >= 0)
1189     {
1190       flags->action = ACTION_READWRITE;
1191       return fd;
1192     }
1193   if (errno != EACCES)
1194      return fd;
1195
1196   /* retry for read-only access */
1197   rwflag = O_RDONLY;
1198   fd = open (path, rwflag | crflag, mode);
1199   if (fd >=0)
1200     {
1201       flags->action = ACTION_READ;
1202       return fd;               /* success */
1203     }
1204   
1205   if (errno != EACCES)
1206     return fd;                 /* failure */
1207
1208   /* retry for write-only access */
1209   rwflag = O_WRONLY;
1210   fd = open (path, rwflag | crflag, mode);
1211   if (fd >=0)
1212     {
1213       flags->action = ACTION_WRITE;
1214       return fd;               /* success */
1215     }
1216   return fd;                   /* failure */
1217 }
1218
1219
1220 /* open_external()-- Open an external file, unix specific version.
1221  * Change flags->action if it is ACTION_UNSPECIFIED on entry.
1222  * Returns NULL on operating system error. */
1223
1224 stream *
1225 open_external (st_parameter_open *opp, unit_flags *flags)
1226 {
1227   int fd, prot;
1228
1229   if (flags->status == STATUS_SCRATCH)
1230     {
1231       fd = tempfile (opp);
1232       if (flags->action == ACTION_UNSPECIFIED)
1233         flags->action = ACTION_READWRITE;
1234
1235 #if HAVE_UNLINK_OPEN_FILE
1236       /* We can unlink scratch files now and it will go away when closed. */
1237       if (fd >= 0)
1238         unlink (opp->file);
1239 #endif
1240     }
1241   else
1242     {
1243       /* regular_file resets flags->action if it is ACTION_UNSPECIFIED and
1244        * if it succeeds */
1245       fd = regular_file (opp, flags);
1246     }
1247
1248   if (fd < 0)
1249     return NULL;
1250   fd = fix_fd (fd);
1251
1252   switch (flags->action)
1253     {
1254     case ACTION_READ:
1255       prot = PROT_READ;
1256       break;
1257
1258     case ACTION_WRITE:
1259       prot = PROT_WRITE;
1260       break;
1261
1262     case ACTION_READWRITE:
1263       prot = PROT_READ | PROT_WRITE;
1264       break;
1265
1266     default:
1267       internal_error (&opp->common, "open_external(): Bad action");
1268     }
1269
1270   return fd_to_stream (fd, prot);
1271 }
1272
1273
1274 /* input_stream()-- Return a stream pointer to the default input stream.
1275  * Called on initialization. */
1276
1277 stream *
1278 input_stream (void)
1279 {
1280   return fd_to_stream (STDIN_FILENO, PROT_READ);
1281 }
1282
1283
1284 /* output_stream()-- Return a stream pointer to the default output stream.
1285  * Called on initialization. */
1286
1287 stream *
1288 output_stream (void)
1289 {
1290   return fd_to_stream (STDOUT_FILENO, PROT_WRITE);
1291 }
1292
1293
1294 /* error_stream()-- Return a stream pointer to the default error stream.
1295  * Called on initialization. */
1296
1297 stream *
1298 error_stream (void)
1299 {
1300   return fd_to_stream (STDERR_FILENO, PROT_WRITE);
1301 }
1302
1303 /* init_error_stream()-- Return a pointer to the error stream.  This
1304  * subroutine is called when the stream is needed, rather than at
1305  * initialization.  We want to work even if memory has been seriously
1306  * corrupted. */
1307
1308 stream *
1309 init_error_stream (unix_stream *error)
1310 {
1311   memset (error, '\0', sizeof (*error));
1312
1313   error->fd = options.use_stderr ? STDERR_FILENO : STDOUT_FILENO;
1314
1315   error->st.alloc_w_at = (void *) fd_alloc_w_at;
1316   error->st.sfree = (void *) fd_sfree;
1317
1318   error->unbuffered = 1;
1319   error->buffer = error->small_buffer;
1320
1321   return (stream *) error;
1322 }
1323
1324
1325 /* compare_file_filename()-- Given an open stream and a fortran string
1326  * that is a filename, figure out if the file is the same as the
1327  * filename. */
1328
1329 int
1330 compare_file_filename (gfc_unit *u, const char *name, int len)
1331 {
1332   char path[PATH_MAX + 1];
1333   struct stat st1;
1334 #ifdef HAVE_WORKING_STAT
1335   struct stat st2;
1336 #endif
1337
1338   if (unpack_filename (path, name, len))
1339     return 0;                   /* Can't be the same */
1340
1341   /* If the filename doesn't exist, then there is no match with the
1342    * existing file. */
1343
1344   if (stat (path, &st1) < 0)
1345     return 0;
1346
1347 #ifdef HAVE_WORKING_STAT
1348   fstat (((unix_stream *) (u->s))->fd, &st2);
1349   return (st1.st_dev == st2.st_dev) && (st1.st_ino == st2.st_ino);
1350 #else
1351   if (len != u->file_len)
1352     return 0;
1353   return (memcmp(path, u->file, len) == 0);
1354 #endif
1355 }
1356
1357
1358 #ifdef HAVE_WORKING_STAT
1359 # define FIND_FILE0_DECL struct stat *st
1360 # define FIND_FILE0_ARGS st
1361 #else
1362 # define FIND_FILE0_DECL const char *file, gfc_charlen_type file_len
1363 # define FIND_FILE0_ARGS file, file_len
1364 #endif
1365
1366 /* find_file0()-- Recursive work function for find_file() */
1367
1368 static gfc_unit *
1369 find_file0 (gfc_unit *u, FIND_FILE0_DECL)
1370 {
1371   gfc_unit *v;
1372
1373   if (u == NULL)
1374     return NULL;
1375
1376 #ifdef HAVE_WORKING_STAT
1377   if (u->s != NULL
1378       && fstat (((unix_stream *) u->s)->fd, &st[1]) >= 0 &&
1379       st[0].st_dev == st[1].st_dev && st[0].st_ino == st[1].st_ino)
1380     return u;
1381 #else
1382   if (compare_string (u->file_len, u->file, file_len, file) == 0)
1383     return u;
1384 #endif
1385
1386   v = find_file0 (u->left, FIND_FILE0_ARGS);
1387   if (v != NULL)
1388     return v;
1389
1390   v = find_file0 (u->right, FIND_FILE0_ARGS);
1391   if (v != NULL)
1392     return v;
1393
1394   return NULL;
1395 }
1396
1397
1398 /* find_file()-- Take the current filename and see if there is a unit
1399  * that has the file already open.  Returns a pointer to the unit if so. */
1400
1401 gfc_unit *
1402 find_file (const char *file, gfc_charlen_type file_len)
1403 {
1404   char path[PATH_MAX + 1];
1405   struct stat st[2];
1406   gfc_unit *u;
1407
1408   if (unpack_filename (path, file, file_len))
1409     return NULL;
1410
1411   if (stat (path, &st[0]) < 0)
1412     return NULL;
1413
1414   __gthread_mutex_lock (&unit_lock);
1415 retry:
1416   u = find_file0 (unit_root, FIND_FILE0_ARGS);
1417   if (u != NULL)
1418     {
1419       /* Fast path.  */
1420       if (! __gthread_mutex_trylock (&u->lock))
1421         {
1422           /* assert (u->closed == 0); */
1423           __gthread_mutex_unlock (&unit_lock);
1424           return u;
1425         }
1426
1427       inc_waiting_locked (u);
1428     }
1429   __gthread_mutex_unlock (&unit_lock);
1430   if (u != NULL)
1431     {
1432       __gthread_mutex_lock (&u->lock);
1433       if (u->closed)
1434         {
1435           __gthread_mutex_lock (&unit_lock);
1436           __gthread_mutex_unlock (&u->lock);
1437           if (predec_waiting_locked (u) == 0)
1438             free_mem (u);
1439           goto retry;
1440         }
1441
1442       dec_waiting_unlocked (u);
1443     }
1444   return u;
1445 }
1446
1447 static gfc_unit *
1448 flush_all_units_1 (gfc_unit *u, int min_unit)
1449 {
1450   while (u != NULL)
1451     {
1452       if (u->unit_number > min_unit)
1453         {
1454           gfc_unit *r = flush_all_units_1 (u->left, min_unit);
1455           if (r != NULL)
1456             return r;
1457         }
1458       if (u->unit_number >= min_unit)
1459         {
1460           if (__gthread_mutex_trylock (&u->lock))
1461             return u;
1462           if (u->s)
1463             flush (u->s);
1464           __gthread_mutex_unlock (&u->lock);
1465         }
1466       u = u->right;
1467     }
1468   return NULL;
1469 }
1470
1471 void
1472 flush_all_units (void)
1473 {
1474   gfc_unit *u;
1475   int min_unit = 0;
1476
1477   __gthread_mutex_lock (&unit_lock);
1478   do
1479     {
1480       u = flush_all_units_1 (unit_root, min_unit);
1481       if (u != NULL)
1482         inc_waiting_locked (u);
1483       __gthread_mutex_unlock (&unit_lock);
1484       if (u == NULL)
1485         return;
1486
1487       __gthread_mutex_lock (&u->lock);
1488
1489       min_unit = u->unit_number + 1;
1490
1491       if (u->closed == 0)
1492         {
1493           flush (u->s);
1494           __gthread_mutex_lock (&unit_lock);
1495           __gthread_mutex_unlock (&u->lock);
1496           (void) predec_waiting_locked (u);
1497         }
1498       else
1499         {
1500           __gthread_mutex_lock (&unit_lock);
1501           __gthread_mutex_unlock (&u->lock);
1502           if (predec_waiting_locked (u) == 0)
1503             free_mem (u);
1504         }
1505     }
1506   while (1);
1507 }
1508
1509
1510 /* stream_at_bof()-- Returns nonzero if the stream is at the beginning
1511  * of the file. */
1512
1513 int
1514 stream_at_bof (stream * s)
1515 {
1516   unix_stream *us;
1517
1518   if (!is_seekable (s))
1519     return 0;
1520
1521   us = (unix_stream *) s;
1522
1523   return us->logical_offset == 0;
1524 }
1525
1526
1527 /* stream_at_eof()-- Returns nonzero if the stream is at the end
1528  * of the file. */
1529
1530 int
1531 stream_at_eof (stream * s)
1532 {
1533   unix_stream *us;
1534
1535   if (!is_seekable (s))
1536     return 0;
1537
1538   us = (unix_stream *) s;
1539
1540   return us->logical_offset == us->dirty_offset;
1541 }
1542
1543
1544 /* delete_file()-- Given a unit structure, delete the file associated
1545  * with the unit.  Returns nonzero if something went wrong. */
1546
1547 int
1548 delete_file (gfc_unit * u)
1549 {
1550   char path[PATH_MAX + 1];
1551
1552   if (unpack_filename (path, u->file, u->file_len))
1553     {                           /* Shouldn't be possible */
1554       errno = ENOENT;
1555       return 1;
1556     }
1557
1558   return unlink (path);
1559 }
1560
1561
1562 /* file_exists()-- Returns nonzero if the current filename exists on
1563  * the system */
1564
1565 int
1566 file_exists (const char *file, gfc_charlen_type file_len)
1567 {
1568   char path[PATH_MAX + 1];
1569   struct stat statbuf;
1570
1571   if (unpack_filename (path, file, file_len))
1572     return 0;
1573
1574   if (stat (path, &statbuf) < 0)
1575     return 0;
1576
1577   return 1;
1578 }
1579
1580
1581
1582 static const char yes[] = "YES", no[] = "NO", unknown[] = "UNKNOWN";
1583
1584 /* inquire_sequential()-- Given a fortran string, determine if the
1585  * file is suitable for sequential access.  Returns a C-style
1586  * string. */
1587
1588 const char *
1589 inquire_sequential (const char *string, int len)
1590 {
1591   char path[PATH_MAX + 1];
1592   struct stat statbuf;
1593
1594   if (string == NULL ||
1595       unpack_filename (path, string, len) || stat (path, &statbuf) < 0)
1596     return unknown;
1597
1598   if (S_ISREG (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) || S_ISBLK (statbuf.st_mode))
1603     return no;
1604
1605   return unknown;
1606 }
1607
1608
1609 /* inquire_direct()-- Given a fortran string, determine if the file is
1610  * suitable for direct access.  Returns a C-style string. */
1611
1612 const char *
1613 inquire_direct (const char *string, int len)
1614 {
1615   char path[PATH_MAX + 1];
1616   struct stat statbuf;
1617
1618   if (string == NULL ||
1619       unpack_filename (path, string, len) || stat (path, &statbuf) < 0)
1620     return unknown;
1621
1622   if (S_ISREG (statbuf.st_mode) || S_ISBLK (statbuf.st_mode))
1623     return yes;
1624
1625   if (S_ISDIR (statbuf.st_mode) ||
1626       S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode))
1627     return no;
1628
1629   return unknown;
1630 }
1631
1632
1633 /* inquire_formatted()-- Given a fortran string, determine if the file
1634  * is suitable for formatted form.  Returns a C-style string. */
1635
1636 const char *
1637 inquire_formatted (const char *string, int len)
1638 {
1639   char path[PATH_MAX + 1];
1640   struct stat statbuf;
1641
1642   if (string == NULL ||
1643       unpack_filename (path, string, len) || stat (path, &statbuf) < 0)
1644     return unknown;
1645
1646   if (S_ISREG (statbuf.st_mode) ||
1647       S_ISBLK (statbuf.st_mode) ||
1648       S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode))
1649     return yes;
1650
1651   if (S_ISDIR (statbuf.st_mode))
1652     return no;
1653
1654   return unknown;
1655 }
1656
1657
1658 /* inquire_unformatted()-- Given a fortran string, determine if the file
1659  * is suitable for unformatted form.  Returns a C-style string. */
1660
1661 const char *
1662 inquire_unformatted (const char *string, int len)
1663 {
1664   return inquire_formatted (string, len);
1665 }
1666
1667
1668 /* inquire_access()-- Given a fortran string, determine if the file is
1669  * suitable for access. */
1670
1671 static const char *
1672 inquire_access (const char *string, int len, int mode)
1673 {
1674   char path[PATH_MAX + 1];
1675
1676   if (string == NULL || unpack_filename (path, string, len) ||
1677       access (path, mode) < 0)
1678     return no;
1679
1680   return yes;
1681 }
1682
1683
1684 /* inquire_read()-- Given a fortran string, determine if the file is
1685  * suitable for READ access. */
1686
1687 const char *
1688 inquire_read (const char *string, int len)
1689 {
1690   return inquire_access (string, len, R_OK);
1691 }
1692
1693
1694 /* inquire_write()-- Given a fortran string, determine if the file is
1695  * suitable for READ access. */
1696
1697 const char *
1698 inquire_write (const char *string, int len)
1699 {
1700   return inquire_access (string, len, W_OK);
1701 }
1702
1703
1704 /* inquire_readwrite()-- Given a fortran string, determine if the file is
1705  * suitable for read and write access. */
1706
1707 const char *
1708 inquire_readwrite (const char *string, int len)
1709 {
1710   return inquire_access (string, len, R_OK | W_OK);
1711 }
1712
1713
1714 /* file_length()-- Return the file length in bytes, -1 if unknown */
1715
1716 gfc_offset
1717 file_length (stream * s)
1718 {
1719   return ((unix_stream *) s)->file_length;
1720 }
1721
1722
1723 /* file_position()-- Return the current position of the file */
1724
1725 gfc_offset
1726 file_position (stream * s)
1727 {
1728   return ((unix_stream *) s)->logical_offset;
1729 }
1730
1731
1732 /* is_seekable()-- Return nonzero if the stream is seekable, zero if
1733  * it is not */
1734
1735 int
1736 is_seekable (stream * s)
1737 {
1738   /* By convention, if file_length == -1, the file is not
1739      seekable.  */
1740   return ((unix_stream *) s)->file_length!=-1;
1741 }
1742
1743 try
1744 flush (stream *s)
1745 {
1746   return fd_flush( (unix_stream *) s);
1747 }
1748
1749 int
1750 stream_isatty (stream *s)
1751 {
1752   return isatty (((unix_stream *) s)->fd);
1753 }
1754
1755 char *
1756 stream_ttyname (stream *s)
1757 {
1758 #ifdef HAVE_TTYNAME
1759   return ttyname (((unix_stream *) s)->fd);
1760 #else
1761   return NULL;
1762 #endif
1763 }
1764
1765 gfc_offset
1766 stream_offset (stream *s)
1767 {
1768   return (((unix_stream *) s)->logical_offset);
1769 }
1770
1771
1772 /* How files are stored:  This is an operating-system specific issue,
1773    and therefore belongs here.  There are three cases to consider.
1774
1775    Direct Access:
1776       Records are written as block of bytes corresponding to the record
1777       length of the file.  This goes for both formatted and unformatted
1778       records.  Positioning is done explicitly for each data transfer,
1779       so positioning is not much of an issue.
1780
1781    Sequential Formatted:
1782       Records are separated by newline characters.  The newline character
1783       is prohibited from appearing in a string.  If it does, this will be
1784       messed up on the next read.  End of file is also the end of a record.
1785
1786    Sequential Unformatted:
1787       In this case, we are merely copying bytes to and from main storage,
1788       yet we need to keep track of varying record lengths.  We adopt
1789       the solution used by f2c.  Each record contains a pair of length
1790       markers:
1791
1792         Length of record n in bytes
1793         Data of record n
1794         Length of record n in bytes
1795
1796         Length of record n+1 in bytes
1797         Data of record n+1
1798         Length of record n+1 in bytes
1799
1800      The length is stored at the end of a record to allow backspacing to the
1801      previous record.  Between data transfer statements, the file pointer
1802      is left pointing to the first length of the current record.
1803
1804      ENDFILE records are never explicitly stored.
1805
1806 */