OSDN Git Service

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