1 /* Copyright (C) 2002-2021 Free Software Foundation, Inc.
2    Contributed by Andy Vaught
3    F2003 I/O support contributed by Jerry DeLisle
4 
5 This file is part of the GNU Fortran 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 3, or (at your option)
10 any later version.
11 
12 Libgfortran is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16 
17 Under Section 7 of GPL version 3, you are granted additional
18 permissions described in the GCC Runtime Library Exception, version
19 3.1, as published by the Free Software Foundation.
20 
21 You should have received a copy of the GNU General Public License and
22 a copy of the GCC Runtime Library Exception along with this program;
23 see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
24 <http://www.gnu.org/licenses/>.  */
25 
26 /* Unix stream I/O module */
27 
28 #include "io.h"
29 #include "unix.h"
30 #include "async.h"
31 #include <limits.h>
32 
33 #ifdef HAVE_UNISTD_H
34 #include <unistd.h>
35 #endif
36 
37 #include <sys/stat.h>
38 #include <fcntl.h>
39 
40 #include <string.h>
41 #include <errno.h>
42 
43 
44 /* For mingw, we don't identify files by their inode number, but by a
45    64-bit identifier created from a BY_HANDLE_FILE_INFORMATION. */
46 #ifdef __MINGW32__
47 
48 #define WIN32_LEAN_AND_MEAN
49 #include <windows.h>
50 
51 #if !defined(_FILE_OFFSET_BITS) || _FILE_OFFSET_BITS != 64
52 #undef lseek
53 #define lseek _lseeki64
54 #undef fstat
55 #define fstat _fstati64
56 #undef stat
57 #define stat _stati64
58 #endif
59 
60 #ifndef HAVE_WORKING_STAT
61 static uint64_t
id_from_handle(HANDLE hFile)62 id_from_handle (HANDLE hFile)
63 {
64   BY_HANDLE_FILE_INFORMATION FileInformation;
65 
66   if (hFile == INVALID_HANDLE_VALUE)
67       return 0;
68 
69   memset (&FileInformation, 0, sizeof(FileInformation));
70   if (!GetFileInformationByHandle (hFile, &FileInformation))
71     return 0;
72 
73   return ((uint64_t) FileInformation.nFileIndexLow)
74 	 | (((uint64_t) FileInformation.nFileIndexHigh) << 32);
75 }
76 
77 
78 static uint64_t
id_from_path(const char * path)79 id_from_path (const char *path)
80 {
81   HANDLE hFile;
82   uint64_t res;
83 
84   if (!path || !*path || access (path, F_OK))
85     return (uint64_t) -1;
86 
87   hFile = CreateFile (path, 0, 0, NULL, OPEN_EXISTING,
88 		      FILE_FLAG_BACKUP_SEMANTICS | FILE_ATTRIBUTE_READONLY,
89 		      NULL);
90   res = id_from_handle (hFile);
91   CloseHandle (hFile);
92   return res;
93 }
94 
95 
96 static uint64_t
id_from_fd(const int fd)97 id_from_fd (const int fd)
98 {
99   return id_from_handle ((HANDLE) _get_osfhandle (fd));
100 }
101 
102 #endif /* HAVE_WORKING_STAT */
103 
104 
105 /* On mingw, we don't use umask in tempfile_open(), because it
106    doesn't support the user/group/other-based permissions.  */
107 #undef HAVE_UMASK
108 
109 #endif /* __MINGW32__ */
110 
111 
112 /* These flags aren't defined on all targets (mingw32), so provide them
113    here.  */
114 #ifndef S_IRGRP
115 #define S_IRGRP 0
116 #endif
117 
118 #ifndef S_IWGRP
119 #define S_IWGRP 0
120 #endif
121 
122 #ifndef S_IROTH
123 #define S_IROTH 0
124 #endif
125 
126 #ifndef S_IWOTH
127 #define S_IWOTH 0
128 #endif
129 
130 
131 #ifndef HAVE_ACCESS
132 
133 #ifndef W_OK
134 #define W_OK 2
135 #endif
136 
137 #ifndef R_OK
138 #define R_OK 4
139 #endif
140 
141 #ifndef F_OK
142 #define F_OK 0
143 #endif
144 
145 /* Fallback implementation of access() on systems that don't have it.
146    Only modes R_OK, W_OK and F_OK are used in this file.  */
147 
148 static int
fallback_access(const char * path,int mode)149 fallback_access (const char *path, int mode)
150 {
151   int fd;
152 
153   if (mode & R_OK)
154     {
155       if ((fd = open (path, O_RDONLY)) < 0)
156 	return -1;
157       else
158 	close (fd);
159     }
160 
161   if (mode & W_OK)
162     {
163       if ((fd = open (path, O_WRONLY)) < 0)
164 	return -1;
165       else
166 	close (fd);
167     }
168 
169   if (mode == F_OK)
170     {
171       struct stat st;
172       return stat (path, &st);
173     }
174 
175   return 0;
176 }
177 
178 #undef access
179 #define access fallback_access
180 #endif
181 
182 
183 /* Fallback directory for creating temporary files.  P_tmpdir is
184    defined on many POSIX platforms.  */
185 #ifndef P_tmpdir
186 #ifdef _P_tmpdir
187 #define P_tmpdir _P_tmpdir  /* MinGW */
188 #else
189 #define P_tmpdir "/tmp"
190 #endif
191 #endif
192 
193 
194 /* Unix and internal stream I/O module */
195 
196 static const int FORMATTED_BUFFER_SIZE_DEFAULT = 8192;
197 static const int UNFORMATTED_BUFFER_SIZE_DEFAULT = 128*1024;
198 
199 typedef struct
200 {
201   stream st;
202 
203   gfc_offset buffer_offset;	/* File offset of the start of the buffer */
204   gfc_offset physical_offset;	/* Current physical file offset */
205   gfc_offset logical_offset;	/* Current logical file offset */
206   gfc_offset file_length;	/* Length of the file. */
207 
208   char *buffer;                 /* Pointer to the buffer.  */
209   ssize_t buffer_size;           /* Length of the buffer.  */
210   int fd;                       /* The POSIX file descriptor.  */
211 
212   int active;			/* Length of valid bytes in the buffer */
213 
214   int ndirty;			/* Dirty bytes starting at buffer_offset */
215 
216   /* Cached stat(2) values.  */
217   dev_t st_dev;
218   ino_t st_ino;
219 
220   bool unbuffered;  /* Buffer should be flushed after each I/O statement.  */
221 }
222 unix_stream;
223 
224 
225 /* fix_fd()-- Given a file descriptor, make sure it is not one of the
226    standard descriptors, returning a non-standard descriptor.  If the
227    user specifies that system errors should go to standard output,
228    then closes standard output, we don't want the system errors to a
229    file that has been given file descriptor 1 or 0.  We want to send
230    the error to the invalid descriptor. */
231 
232 static int
fix_fd(int fd)233 fix_fd (int fd)
234 {
235 #ifdef HAVE_DUP
236   int input, output, error;
237 
238   input = output = error = 0;
239 
240   /* Unix allocates the lowest descriptors first, so a loop is not
241      required, but this order is. */
242   if (fd == STDIN_FILENO)
243     {
244       fd = dup (fd);
245       input = 1;
246     }
247   if (fd == STDOUT_FILENO)
248     {
249       fd = dup (fd);
250       output = 1;
251     }
252   if (fd == STDERR_FILENO)
253     {
254       fd = dup (fd);
255       error = 1;
256     }
257 
258   if (input)
259     close (STDIN_FILENO);
260   if (output)
261     close (STDOUT_FILENO);
262   if (error)
263     close (STDERR_FILENO);
264 #endif
265 
266   return fd;
267 }
268 
269 
270 /* If the stream corresponds to a preconnected unit, we flush the
271    corresponding C stream.  This is bugware for mixed C-Fortran codes
272    where the C code doesn't flush I/O before returning.  */
273 void
flush_if_preconnected(stream * s)274 flush_if_preconnected (stream *s)
275 {
276   int fd;
277 
278   fd = ((unix_stream *) s)->fd;
279   if (fd == STDIN_FILENO)
280     fflush (stdin);
281   else if (fd == STDOUT_FILENO)
282     fflush (stdout);
283   else if (fd == STDERR_FILENO)
284     fflush (stderr);
285 }
286 
287 
288 /********************************************************************
289 Raw I/O functions (read, write, seek, tell, truncate, close).
290 
291 These functions wrap the basic POSIX I/O syscalls. Any deviation in
292 semantics is a bug, except the following: write restarts in case
293 of being interrupted by a signal, and as the first argument the
294 functions take the unix_stream struct rather than an integer file
295 descriptor. Also, for POSIX read() and write() a nbyte argument larger
296 than SSIZE_MAX is undefined; here the type of nbyte is ssize_t rather
297 than size_t as for POSIX read/write.
298 *********************************************************************/
299 
300 static int
raw_flush(unix_stream * s)301 raw_flush (unix_stream *s  __attribute__ ((unused)))
302 {
303   return 0;
304 }
305 
306 /* Write/read at most 2 GB - 4k chunks at a time. Linux never reads or
307    writes more than this, and there are reports that macOS fails for
308    larger than 2 GB as well.  */
309 #define MAX_CHUNK 2147479552
310 
311 static ssize_t
raw_read(unix_stream * s,void * buf,ssize_t nbyte)312 raw_read (unix_stream *s, void *buf, ssize_t nbyte)
313 {
314   /* For read we can't do I/O in a loop like raw_write does, because
315      that will break applications that wait for interactive I/O.  We
316      still can loop around EINTR, though.  This however causes a
317      problem for large reads which must be chunked, see comment above.
318      So assume that if the size is larger than the chunk size, we're
319      reading from a file and not the terminal.  */
320   if (nbyte <= MAX_CHUNK)
321     {
322       while (true)
323 	{
324 	  ssize_t trans = read (s->fd, buf, nbyte);
325 	  if (trans == -1 && errno == EINTR)
326 	    continue;
327 	  return trans;
328 	}
329     }
330   else
331     {
332       ssize_t bytes_left = nbyte;
333       char *buf_st = buf;
334       while (bytes_left > 0)
335 	{
336 	  ssize_t to_read = bytes_left < MAX_CHUNK ? bytes_left: MAX_CHUNK;
337 	  ssize_t trans = read (s->fd, buf_st, to_read);
338 	  if (trans == -1)
339 	    {
340 	      if (errno == EINTR)
341 		continue;
342 	      else
343 		return trans;
344 	    }
345 	  buf_st += trans;
346 	  bytes_left -= trans;
347 	}
348       return nbyte - bytes_left;
349     }
350 }
351 
352 static ssize_t
raw_write(unix_stream * s,const void * buf,ssize_t nbyte)353 raw_write (unix_stream *s, const void *buf, ssize_t nbyte)
354 {
355   ssize_t trans, bytes_left;
356   char *buf_st;
357 
358   bytes_left = nbyte;
359   buf_st = (char *) buf;
360 
361   /* We must write in a loop since some systems don't restart system
362      calls in case of a signal.  Also some systems might fail outright
363      if we try to write more than 2 GB in a single syscall, so chunk
364      up large writes.  */
365   while (bytes_left > 0)
366     {
367       ssize_t to_write = bytes_left < MAX_CHUNK ? bytes_left: MAX_CHUNK;
368       trans = write (s->fd, buf_st, to_write);
369       if (trans == -1)
370 	{
371 	  if (errno == EINTR)
372 	    continue;
373 	  else
374 	    return trans;
375 	}
376       buf_st += trans;
377       bytes_left -= trans;
378     }
379 
380   return nbyte - bytes_left;
381 }
382 
383 static gfc_offset
raw_seek(unix_stream * s,gfc_offset offset,int whence)384 raw_seek (unix_stream *s, gfc_offset offset, int whence)
385 {
386   while (true)
387     {
388       gfc_offset off = lseek (s->fd, offset, whence);
389       if (off == (gfc_offset) -1 && errno == EINTR)
390 	continue;
391       return off;
392     }
393 }
394 
395 static gfc_offset
raw_tell(unix_stream * s)396 raw_tell (unix_stream *s)
397 {
398   while (true)
399     {
400       gfc_offset off = lseek (s->fd, 0, SEEK_CUR);
401       if (off == (gfc_offset) -1 && errno == EINTR)
402 	continue;
403       return off;
404     }
405 }
406 
407 static gfc_offset
raw_size(unix_stream * s)408 raw_size (unix_stream *s)
409 {
410   struct stat statbuf;
411   if (TEMP_FAILURE_RETRY (fstat (s->fd, &statbuf)) == -1)
412     return -1;
413   if (S_ISREG (statbuf.st_mode))
414     return statbuf.st_size;
415   else
416     return 0;
417 }
418 
419 static int
raw_truncate(unix_stream * s,gfc_offset length)420 raw_truncate (unix_stream *s, gfc_offset length)
421 {
422 #ifdef __MINGW32__
423   HANDLE h;
424   gfc_offset cur;
425 
426   if (isatty (s->fd))
427     {
428       errno = EBADF;
429       return -1;
430     }
431   h = (HANDLE) _get_osfhandle (s->fd);
432   if (h == INVALID_HANDLE_VALUE)
433     {
434       errno = EBADF;
435       return -1;
436     }
437   cur = lseek (s->fd, 0, SEEK_CUR);
438   if (cur == -1)
439     return -1;
440   if (lseek (s->fd, length, SEEK_SET) == -1)
441     goto error;
442   if (!SetEndOfFile (h))
443     {
444       errno = EBADF;
445       goto error;
446     }
447   if (lseek (s->fd, cur, SEEK_SET) == -1)
448     return -1;
449   return 0;
450  error:
451   lseek (s->fd, cur, SEEK_SET);
452   return -1;
453 #elif defined HAVE_FTRUNCATE
454   if (TEMP_FAILURE_RETRY (ftruncate (s->fd, length)) == -1)
455     return -1;
456   return 0;
457 #elif defined HAVE_CHSIZE
458   return chsize (s->fd, length);
459 #else
460   runtime_error ("required ftruncate or chsize support not present");
461   return -1;
462 #endif
463 }
464 
465 static int
raw_close(unix_stream * s)466 raw_close (unix_stream *s)
467 {
468   int retval;
469 
470   if (s->fd == -1)
471     retval = -1;
472   else if (s->fd != STDOUT_FILENO
473       && s->fd != STDERR_FILENO
474       && s->fd != STDIN_FILENO)
475     {
476       retval = close (s->fd);
477       /* close() and EINTR is special, as the file descriptor is
478 	 deallocated before doing anything that might cause the
479 	 operation to be interrupted. Thus if we get EINTR the best we
480 	 can do is ignore it and continue (otherwise if we try again
481 	 the file descriptor may have been allocated again to some
482 	 other file).  */
483       if (retval == -1 && errno == EINTR)
484 	retval = errno = 0;
485     }
486   else
487     retval = 0;
488   free (s);
489   return retval;
490 }
491 
492 static int
raw_markeor(unix_stream * s)493 raw_markeor (unix_stream *s __attribute__ ((unused)))
494 {
495   return 0;
496 }
497 
498 static const struct stream_vtable raw_vtable = {
499   .read = (void *) raw_read,
500   .write = (void *) raw_write,
501   .seek = (void *) raw_seek,
502   .tell = (void *) raw_tell,
503   .size = (void *) raw_size,
504   .trunc = (void *) raw_truncate,
505   .close = (void *) raw_close,
506   .flush = (void *) raw_flush,
507   .markeor = (void *) raw_markeor
508 };
509 
510 static int
raw_init(unix_stream * s)511 raw_init (unix_stream *s)
512 {
513   s->st.vptr = &raw_vtable;
514 
515   s->buffer = NULL;
516   return 0;
517 }
518 
519 
520 /*********************************************************************
521 Buffered I/O functions. These functions have the same semantics as the
522 raw I/O functions above, except that they are buffered in order to
523 improve performance. The buffer must be flushed when switching from
524 reading to writing and vice versa.
525 *********************************************************************/
526 
527 static int
buf_flush(unix_stream * s)528 buf_flush (unix_stream *s)
529 {
530   int writelen;
531 
532   /* Flushing in read mode means discarding read bytes.  */
533   s->active = 0;
534 
535   if (s->ndirty == 0)
536     return 0;
537 
538   if (s->physical_offset != s->buffer_offset
539       && raw_seek (s, s->buffer_offset, SEEK_SET) < 0)
540     return -1;
541 
542   writelen = raw_write (s, s->buffer, s->ndirty);
543 
544   s->physical_offset = s->buffer_offset + writelen;
545 
546   if (s->physical_offset > s->file_length)
547       s->file_length = s->physical_offset;
548 
549   s->ndirty -= writelen;
550   if (s->ndirty != 0)
551     return -1;
552 
553   return 0;
554 }
555 
556 static ssize_t
buf_read(unix_stream * s,void * buf,ssize_t nbyte)557 buf_read (unix_stream *s, void *buf, ssize_t nbyte)
558 {
559   if (s->active == 0)
560     s->buffer_offset = s->logical_offset;
561 
562   /* Is the data we want in the buffer?  */
563   if (s->logical_offset + nbyte <= s->buffer_offset + s->active
564       && s->buffer_offset <= s->logical_offset)
565     {
566       /* When nbyte == 0, buf can be NULL which would lead to undefined
567 	 behavior if we called memcpy().  */
568       if (nbyte != 0)
569 	memcpy (buf, s->buffer + (s->logical_offset - s->buffer_offset),
570 		nbyte);
571     }
572   else
573     {
574       /* First copy the active bytes if applicable, then read the rest
575          either directly or filling the buffer.  */
576       char *p;
577       int nread = 0;
578       ssize_t to_read, did_read;
579       gfc_offset new_logical;
580 
581       p = (char *) buf;
582       if (s->logical_offset >= s->buffer_offset
583           && s->buffer_offset + s->active >= s->logical_offset)
584         {
585           nread = s->active - (s->logical_offset - s->buffer_offset);
586           memcpy (buf, s->buffer + (s->logical_offset - s->buffer_offset),
587                   nread);
588           p += nread;
589         }
590       /* At this point we consider all bytes in the buffer discarded.  */
591       to_read = nbyte - nread;
592       new_logical = s->logical_offset + nread;
593       if (s->physical_offset != new_logical
594           && raw_seek (s, new_logical, SEEK_SET) < 0)
595         return -1;
596       s->buffer_offset = s->physical_offset = new_logical;
597       if (to_read <= s->buffer_size/2)
598         {
599           did_read = raw_read (s, s->buffer, s->buffer_size);
600 	  if (likely (did_read >= 0))
601 	    {
602 	      s->physical_offset += did_read;
603 	      s->active = did_read;
604 	      did_read = (did_read > to_read) ? to_read : did_read;
605 	      memcpy (p, s->buffer, did_read);
606 	    }
607 	  else
608 	    return did_read;
609         }
610       else
611         {
612           did_read = raw_read (s, p, to_read);
613 	  if (likely (did_read >= 0))
614 	    {
615 	      s->physical_offset += did_read;
616 	      s->active = 0;
617 	    }
618 	  else
619 	    return did_read;
620         }
621       nbyte = did_read + nread;
622     }
623   s->logical_offset += nbyte;
624   return nbyte;
625 }
626 
627 static ssize_t
buf_write(unix_stream * s,const void * buf,ssize_t nbyte)628 buf_write (unix_stream *s, const void *buf, ssize_t nbyte)
629 {
630   if (nbyte == 0)
631     return 0;
632 
633   if (s->ndirty == 0)
634     s->buffer_offset = s->logical_offset;
635 
636   /* Does the data fit into the buffer?  As a special case, if the
637      buffer is empty and the request is bigger than s->buffer_size/2,
638      write directly. This avoids the case where the buffer would have
639      to be flushed at every write.  */
640   if (!(s->ndirty == 0 && nbyte > s->buffer_size/2)
641       && s->logical_offset + nbyte <= s->buffer_offset + s->buffer_size
642       && s->buffer_offset <= s->logical_offset
643       && s->buffer_offset + s->ndirty >= s->logical_offset)
644     {
645       memcpy (s->buffer + (s->logical_offset - s->buffer_offset), buf, nbyte);
646       int nd = (s->logical_offset - s->buffer_offset) + nbyte;
647       if (nd > s->ndirty)
648         s->ndirty = nd;
649     }
650   else
651     {
652       /* Flush, and either fill the buffer with the new data, or if
653          the request is bigger than the buffer size, write directly
654          bypassing the buffer.  */
655       buf_flush (s);
656       if (nbyte <= s->buffer_size/2)
657         {
658           memcpy (s->buffer, buf, nbyte);
659           s->buffer_offset = s->logical_offset;
660           s->ndirty += nbyte;
661         }
662       else
663 	{
664 	  if (s->physical_offset != s->logical_offset)
665 	    {
666 	      if (raw_seek (s, s->logical_offset, SEEK_SET) < 0)
667 		return -1;
668 	      s->physical_offset = s->logical_offset;
669 	    }
670 
671 	  nbyte = raw_write (s, buf, nbyte);
672 	  s->physical_offset += nbyte;
673 	}
674     }
675   s->logical_offset += nbyte;
676   if (s->logical_offset > s->file_length)
677     s->file_length = s->logical_offset;
678   return nbyte;
679 }
680 
681 
682 /* "Unbuffered" really means I/O statement buffering. For formatted
683    I/O, the fbuf manages this, and then uses raw I/O. For unformatted
684    I/O, buffered I/O is used, and the buffer is flushed at the end of
685    each I/O statement, where this function is called.  Alternatively,
686    the buffer is flushed at the end of the record if the buffer is
687    more than half full; this prevents needless seeking back and forth
688    when writing sequential unformatted.  */
689 
690 static int
buf_markeor(unix_stream * s)691 buf_markeor (unix_stream *s)
692 {
693   if (s->unbuffered || s->ndirty >= s->buffer_size / 2)
694     return buf_flush (s);
695   return 0;
696 }
697 
698 static gfc_offset
buf_seek(unix_stream * s,gfc_offset offset,int whence)699 buf_seek (unix_stream *s, gfc_offset offset, int whence)
700 {
701   switch (whence)
702     {
703     case SEEK_SET:
704       break;
705     case SEEK_CUR:
706       offset += s->logical_offset;
707       break;
708     case SEEK_END:
709       offset += s->file_length;
710       break;
711     default:
712       return -1;
713     }
714   if (offset < 0)
715     {
716       errno = EINVAL;
717       return -1;
718     }
719   s->logical_offset = offset;
720   return offset;
721 }
722 
723 static gfc_offset
buf_tell(unix_stream * s)724 buf_tell (unix_stream *s)
725 {
726   return buf_seek (s, 0, SEEK_CUR);
727 }
728 
729 static gfc_offset
buf_size(unix_stream * s)730 buf_size (unix_stream *s)
731 {
732   return s->file_length;
733 }
734 
735 static int
buf_truncate(unix_stream * s,gfc_offset length)736 buf_truncate (unix_stream *s, gfc_offset length)
737 {
738   int r;
739 
740   if (buf_flush (s) != 0)
741     return -1;
742   r = raw_truncate (s, length);
743   if (r == 0)
744     s->file_length = length;
745   return r;
746 }
747 
748 static int
buf_close(unix_stream * s)749 buf_close (unix_stream *s)
750 {
751   if (buf_flush (s) != 0)
752     return -1;
753   free (s->buffer);
754   return raw_close (s);
755 }
756 
757 static const struct stream_vtable buf_vtable = {
758   .read = (void *) buf_read,
759   .write = (void *) buf_write,
760   .seek = (void *) buf_seek,
761   .tell = (void *) buf_tell,
762   .size = (void *) buf_size,
763   .trunc = (void *) buf_truncate,
764   .close = (void *) buf_close,
765   .flush = (void *) buf_flush,
766   .markeor = (void *) buf_markeor
767 };
768 
769 static int
buf_init(unix_stream * s,bool unformatted)770 buf_init (unix_stream *s, bool unformatted)
771 {
772   s->st.vptr = &buf_vtable;
773 
774   /* Try to guess a good value for the buffer size.  For formatted
775      I/O, we use so many CPU cycles converting the data that there is
776      more sense in converving memory and especially cache.  For
777      unformatted, a bigger block can have a large impact in some
778      environments.  */
779 
780   if (unformatted)
781     {
782       if (options.unformatted_buffer_size > 0)
783 	s->buffer_size = options.unformatted_buffer_size;
784       else
785 	s->buffer_size = UNFORMATTED_BUFFER_SIZE_DEFAULT;
786     }
787   else
788     {
789       if (options.formatted_buffer_size > 0)
790 	s->buffer_size = options.formatted_buffer_size;
791       else
792 	s->buffer_size = FORMATTED_BUFFER_SIZE_DEFAULT;
793     }
794 
795   s->buffer = xmalloc (s->buffer_size);
796   return 0;
797 }
798 
799 
800 /*********************************************************************
801   memory stream functions - These are used for internal files
802 
803   The idea here is that a single stream structure is created and all
804   requests must be satisfied from it.  The location and size of the
805   buffer is the character variable supplied to the READ or WRITE
806   statement.
807 
808 *********************************************************************/
809 
810 char *
mem_alloc_r(stream * strm,size_t * len)811 mem_alloc_r (stream *strm, size_t *len)
812 {
813   unix_stream *s = (unix_stream *) strm;
814   gfc_offset n;
815   gfc_offset where = s->logical_offset;
816 
817   if (where < s->buffer_offset || where > s->buffer_offset + s->active)
818     return NULL;
819 
820   n = s->buffer_offset + s->active - where;
821   if ((gfc_offset) *len > n)
822     *len = n;
823 
824   s->logical_offset = where + *len;
825 
826   return s->buffer + (where - s->buffer_offset);
827 }
828 
829 
830 char *
mem_alloc_r4(stream * strm,size_t * len)831 mem_alloc_r4 (stream *strm, size_t *len)
832 {
833   unix_stream *s = (unix_stream *) strm;
834   gfc_offset n;
835   gfc_offset where = s->logical_offset;
836 
837   if (where < s->buffer_offset || where > s->buffer_offset + s->active)
838     return NULL;
839 
840   n = s->buffer_offset + s->active - where;
841   if ((gfc_offset) *len > n)
842     *len = n;
843 
844   s->logical_offset = where + *len;
845 
846   return s->buffer + (where - s->buffer_offset) * 4;
847 }
848 
849 
850 char *
mem_alloc_w(stream * strm,size_t * len)851 mem_alloc_w (stream *strm, size_t *len)
852 {
853   unix_stream *s = (unix_stream *)strm;
854   gfc_offset m;
855   gfc_offset where = s->logical_offset;
856 
857   m = where + *len;
858 
859   if (where < s->buffer_offset)
860     return NULL;
861 
862   if (m > s->file_length)
863     return NULL;
864 
865   s->logical_offset = m;
866 
867   return s->buffer + (where - s->buffer_offset);
868 }
869 
870 
871 gfc_char4_t *
mem_alloc_w4(stream * strm,size_t * len)872 mem_alloc_w4 (stream *strm, size_t *len)
873 {
874   unix_stream *s = (unix_stream *)strm;
875   gfc_offset m;
876   gfc_offset where = s->logical_offset;
877   gfc_char4_t *result = (gfc_char4_t *) s->buffer;
878 
879   m = where + *len;
880 
881   if (where < s->buffer_offset)
882     return NULL;
883 
884   if (m > s->file_length)
885     return NULL;
886 
887   s->logical_offset = m;
888   return &result[where - s->buffer_offset];
889 }
890 
891 
892 /* Stream read function for character(kind=1) internal units.  */
893 
894 static ssize_t
mem_read(stream * s,void * buf,ssize_t nbytes)895 mem_read (stream *s, void *buf, ssize_t nbytes)
896 {
897   void *p;
898   size_t nb = nbytes;
899 
900   p = mem_alloc_r (s, &nb);
901   if (p)
902     {
903       memcpy (buf, p, nb);
904       return (ssize_t) nb;
905     }
906   else
907     return 0;
908 }
909 
910 
911 /* Stream read function for chracter(kind=4) internal units.  */
912 
913 static ssize_t
mem_read4(stream * s,void * buf,ssize_t nbytes)914 mem_read4 (stream *s, void *buf, ssize_t nbytes)
915 {
916   void *p;
917   size_t nb = nbytes;
918 
919   p = mem_alloc_r4 (s, &nb);
920   if (p)
921     {
922       memcpy (buf, p, nb * 4);
923       return (ssize_t) nb;
924     }
925   else
926     return 0;
927 }
928 
929 
930 /* Stream write function for character(kind=1) internal units.  */
931 
932 static ssize_t
mem_write(stream * s,const void * buf,ssize_t nbytes)933 mem_write (stream *s, const void *buf, ssize_t nbytes)
934 {
935   void *p;
936   size_t nb = nbytes;
937 
938   p = mem_alloc_w (s, &nb);
939   if (p)
940     {
941       memcpy (p, buf, nb);
942       return (ssize_t) nb;
943     }
944   else
945     return 0;
946 }
947 
948 
949 /* Stream write function for character(kind=4) internal units.  */
950 
951 static ssize_t
mem_write4(stream * s,const void * buf,ssize_t nwords)952 mem_write4 (stream *s, const void *buf, ssize_t nwords)
953 {
954   gfc_char4_t *p;
955   size_t nw = nwords;
956 
957   p = mem_alloc_w4 (s, &nw);
958   if (p)
959     {
960       while (nw--)
961 	*p++ = (gfc_char4_t) *((char *) buf);
962       return nwords;
963     }
964   else
965     return 0;
966 }
967 
968 
969 static gfc_offset
mem_seek(stream * strm,gfc_offset offset,int whence)970 mem_seek (stream *strm, gfc_offset offset, int whence)
971 {
972   unix_stream *s = (unix_stream *)strm;
973   switch (whence)
974     {
975     case SEEK_SET:
976       break;
977     case SEEK_CUR:
978       offset += s->logical_offset;
979       break;
980     case SEEK_END:
981       offset += s->file_length;
982       break;
983     default:
984       return -1;
985     }
986 
987   /* Note that for internal array I/O it's actually possible to have a
988      negative offset, so don't check for that.  */
989   if (offset > s->file_length)
990     {
991       errno = EINVAL;
992       return -1;
993     }
994 
995   s->logical_offset = offset;
996 
997   /* Returning < 0 is the error indicator for sseek(), so return 0 if
998      offset is negative.  Thus if the return value is 0, the caller
999      has to use stell() to get the real value of logical_offset.  */
1000   if (offset >= 0)
1001     return offset;
1002   return 0;
1003 }
1004 
1005 
1006 static gfc_offset
mem_tell(stream * s)1007 mem_tell (stream *s)
1008 {
1009   return ((unix_stream *)s)->logical_offset;
1010 }
1011 
1012 
1013 static int
mem_truncate(unix_stream * s,gfc_offset length)1014 mem_truncate (unix_stream *s __attribute__ ((unused)),
1015 	      gfc_offset length __attribute__ ((unused)))
1016 {
1017   return 0;
1018 }
1019 
1020 
1021 static int
mem_flush(unix_stream * s)1022 mem_flush (unix_stream *s __attribute__ ((unused)))
1023 {
1024   return 0;
1025 }
1026 
1027 
1028 static int
mem_close(unix_stream * s)1029 mem_close (unix_stream *s)
1030 {
1031   if (s)
1032     free (s);
1033   return 0;
1034 }
1035 
1036 static const struct stream_vtable mem_vtable = {
1037   .read = (void *) mem_read,
1038   .write = (void *) mem_write,
1039   .seek = (void *) mem_seek,
1040   .tell = (void *) mem_tell,
1041   /* buf_size is not a typo, we just reuse an identical
1042      implementation.  */
1043   .size = (void *) buf_size,
1044   .trunc = (void *) mem_truncate,
1045   .close = (void *) mem_close,
1046   .flush = (void *) mem_flush,
1047   .markeor = (void *) raw_markeor
1048 };
1049 
1050 static const struct stream_vtable mem4_vtable = {
1051   .read = (void *) mem_read4,
1052   .write = (void *) mem_write4,
1053   .seek = (void *) mem_seek,
1054   .tell = (void *) mem_tell,
1055   /* buf_size is not a typo, we just reuse an identical
1056      implementation.  */
1057   .size = (void *) buf_size,
1058   .trunc = (void *) mem_truncate,
1059   .close = (void *) mem_close,
1060   .flush = (void *) mem_flush,
1061   .markeor = (void *) raw_markeor
1062 };
1063 
1064 /*********************************************************************
1065   Public functions -- A reimplementation of this module needs to
1066   define functional equivalents of the following.
1067 *********************************************************************/
1068 
1069 /* open_internal()-- Returns a stream structure from a character(kind=1)
1070    internal file */
1071 
1072 stream *
open_internal(char * base,size_t length,gfc_offset offset)1073 open_internal (char *base, size_t length, gfc_offset offset)
1074 {
1075   unix_stream *s;
1076 
1077   s = xcalloc (1, sizeof (unix_stream));
1078 
1079   s->buffer = base;
1080   s->buffer_offset = offset;
1081 
1082   s->active = s->file_length = length;
1083 
1084   s->st.vptr = &mem_vtable;
1085 
1086   return (stream *) s;
1087 }
1088 
1089 /* open_internal4()-- Returns a stream structure from a character(kind=4)
1090    internal file */
1091 
1092 stream *
open_internal4(char * base,size_t length,gfc_offset offset)1093 open_internal4 (char *base, size_t length, gfc_offset offset)
1094 {
1095   unix_stream *s;
1096 
1097   s = xcalloc (1, sizeof (unix_stream));
1098 
1099   s->buffer = base;
1100   s->buffer_offset = offset;
1101 
1102   s->active = s->file_length = length * sizeof (gfc_char4_t);
1103 
1104   s->st.vptr = &mem4_vtable;
1105 
1106   return (stream *)s;
1107 }
1108 
1109 
1110 /* fd_to_stream()-- Given an open file descriptor, build a stream
1111    around it. */
1112 
1113 static stream *
fd_to_stream(int fd,bool unformatted)1114 fd_to_stream (int fd, bool unformatted)
1115 {
1116   struct stat statbuf;
1117   unix_stream *s;
1118 
1119   s = xcalloc (1, sizeof (unix_stream));
1120 
1121   s->fd = fd;
1122 
1123   /* Get the current length of the file. */
1124 
1125   if (TEMP_FAILURE_RETRY (fstat (fd, &statbuf)) == -1)
1126     {
1127       s->st_dev = s->st_ino = -1;
1128       s->file_length = 0;
1129       if (errno == EBADF)
1130 	s->fd = -1;
1131       raw_init (s);
1132       return (stream *) s;
1133     }
1134 
1135   s->st_dev = statbuf.st_dev;
1136   s->st_ino = statbuf.st_ino;
1137   s->file_length = statbuf.st_size;
1138 
1139   /* Only use buffered IO for regular files.  */
1140   if (S_ISREG (statbuf.st_mode)
1141       && !options.all_unbuffered
1142       && !(options.unbuffered_preconnected &&
1143 	   (s->fd == STDIN_FILENO
1144 	    || s->fd == STDOUT_FILENO
1145 	    || s->fd == STDERR_FILENO)))
1146     buf_init (s, unformatted);
1147   else
1148     {
1149       if (unformatted)
1150 	{
1151 	  s->unbuffered = true;
1152 	  buf_init (s, unformatted);
1153 	}
1154       else
1155 	raw_init (s);
1156     }
1157 
1158   return (stream *) s;
1159 }
1160 
1161 
1162 /* Given the Fortran unit number, convert it to a C file descriptor.  */
1163 
1164 int
unit_to_fd(int unit)1165 unit_to_fd (int unit)
1166 {
1167   gfc_unit *us;
1168   int fd;
1169 
1170   us = find_unit (unit);
1171   if (us == NULL)
1172     return -1;
1173 
1174   fd = ((unix_stream *) us->s)->fd;
1175   unlock_unit (us);
1176   return fd;
1177 }
1178 
1179 
1180 /* Set the close-on-exec flag for an existing fd, if the system
1181    supports such.  */
1182 
1183 static void __attribute__ ((unused))
set_close_on_exec(int fd)1184 set_close_on_exec (int fd __attribute__ ((unused)))
1185 {
1186   /* Mingw does not define F_SETFD.  */
1187 #if defined(HAVE_FCNTL) && defined(F_SETFD) && defined(FD_CLOEXEC)
1188   if (fd >= 0)
1189     fcntl(fd, F_SETFD, FD_CLOEXEC);
1190 #endif
1191 }
1192 
1193 
1194 /* Helper function for tempfile(). Tries to open a temporary file in
1195    the directory specified by tempdir. If successful, the file name is
1196    stored in fname and the descriptor returned. Returns -1 on
1197    failure.  */
1198 
1199 static int
tempfile_open(const char * tempdir,char ** fname)1200 tempfile_open (const char *tempdir, char **fname)
1201 {
1202   int fd;
1203   const char *slash = "/";
1204 #if defined(HAVE_UMASK) && defined(HAVE_MKSTEMP)
1205   mode_t mode_mask;
1206 #endif
1207 
1208   if (!tempdir)
1209     return -1;
1210 
1211   /* Check for the special case that tempdir ends with a slash or
1212      backslash.  */
1213   size_t tempdirlen = strlen (tempdir);
1214   if (*tempdir == 0 || tempdir[tempdirlen - 1] == '/'
1215 #ifdef __MINGW32__
1216       || tempdir[tempdirlen - 1] == '\\'
1217 #endif
1218      )
1219     slash = "";
1220 
1221   /* Take care that the template is longer in the mktemp() branch.  */
1222   char *template = xmalloc (tempdirlen + 23);
1223 
1224 #ifdef HAVE_MKSTEMP
1225   snprintf (template, tempdirlen + 23, "%s%sgfortrantmpXXXXXX",
1226 	    tempdir, slash);
1227 
1228 #ifdef HAVE_UMASK
1229   /* Temporarily set the umask such that the file has 0600 permissions.  */
1230   mode_mask = umask (S_IXUSR | S_IRWXG | S_IRWXO);
1231 #endif
1232 
1233 #if defined(HAVE_MKOSTEMP) && defined(O_CLOEXEC)
1234   TEMP_FAILURE_RETRY (fd = mkostemp (template, O_CLOEXEC));
1235 #else
1236   TEMP_FAILURE_RETRY (fd = mkstemp (template));
1237   set_close_on_exec (fd);
1238 #endif
1239 
1240 #ifdef HAVE_UMASK
1241   (void) umask (mode_mask);
1242 #endif
1243 
1244 #else /* HAVE_MKSTEMP */
1245   fd = -1;
1246   int count = 0;
1247   size_t slashlen = strlen (slash);
1248   int flags = O_RDWR | O_CREAT | O_EXCL;
1249 #if defined(HAVE_CRLF) && defined(O_BINARY)
1250   flags |= O_BINARY;
1251 #endif
1252 #ifdef O_CLOEXEC
1253   flags |= O_CLOEXEC;
1254 #endif
1255   do
1256     {
1257       snprintf (template, tempdirlen + 23, "%s%sgfortrantmpaaaXXXXXX",
1258 		tempdir, slash);
1259       if (count > 0)
1260 	{
1261 	  int c = count;
1262 	  template[tempdirlen + slashlen + 13] = 'a' + (c% 26);
1263 	  c /= 26;
1264 	  template[tempdirlen + slashlen + 12] = 'a' + (c % 26);
1265 	  c /= 26;
1266 	  template[tempdirlen + slashlen + 11] = 'a' + (c % 26);
1267 	  if (c >= 26)
1268 	    break;
1269 	}
1270 
1271       if (!mktemp (template))
1272       {
1273 	errno = EEXIST;
1274 	count++;
1275 	continue;
1276       }
1277 
1278       TEMP_FAILURE_RETRY (fd = open (template, flags, S_IRUSR | S_IWUSR));
1279     }
1280   while (fd == -1 && errno == EEXIST);
1281 #ifndef O_CLOEXEC
1282   set_close_on_exec (fd);
1283 #endif
1284 #endif /* HAVE_MKSTEMP */
1285 
1286   *fname = template;
1287   return fd;
1288 }
1289 
1290 
1291 /* tempfile()-- Generate a temporary filename for a scratch file and
1292    open it.  mkstemp() opens the file for reading and writing, but the
1293    library mode prevents anything that is not allowed.  The descriptor
1294    is returned, which is -1 on error.  The template is pointed to by
1295    opp->file, which is copied into the unit structure
1296    and freed later. */
1297 
1298 static int
tempfile(st_parameter_open * opp)1299 tempfile (st_parameter_open *opp)
1300 {
1301   const char *tempdir;
1302   char *fname;
1303   int fd = -1;
1304 
1305   tempdir = secure_getenv ("TMPDIR");
1306   fd = tempfile_open (tempdir, &fname);
1307 #ifdef __MINGW32__
1308   if (fd == -1)
1309     {
1310       char buffer[MAX_PATH + 1];
1311       DWORD ret;
1312       ret = GetTempPath (MAX_PATH, buffer);
1313       /* If we are not able to get a temp-directory, we use
1314 	 current directory.  */
1315       if (ret > MAX_PATH || !ret)
1316         buffer[0] = 0;
1317       else
1318         buffer[ret] = 0;
1319       tempdir = strdup (buffer);
1320       fd = tempfile_open (tempdir, &fname);
1321     }
1322 #elif defined(__CYGWIN__)
1323   if (fd == -1)
1324     {
1325       tempdir = secure_getenv ("TMP");
1326       fd = tempfile_open (tempdir, &fname);
1327     }
1328   if (fd == -1)
1329     {
1330       tempdir = secure_getenv ("TEMP");
1331       fd = tempfile_open (tempdir, &fname);
1332     }
1333 #endif
1334   if (fd == -1)
1335     fd = tempfile_open (P_tmpdir, &fname);
1336 
1337   opp->file = fname;
1338   opp->file_len = strlen (fname);	/* Don't include trailing nul */
1339 
1340   return fd;
1341 }
1342 
1343 
1344 /* regular_file2()-- Open a regular file.
1345    Change flags->action if it is ACTION_UNSPECIFIED on entry,
1346    unless an error occurs.
1347    Returns the descriptor, which is less than zero on error. */
1348 
1349 static int
regular_file2(const char * path,st_parameter_open * opp,unit_flags * flags)1350 regular_file2 (const char *path, st_parameter_open *opp, unit_flags *flags)
1351 {
1352   int mode;
1353   int rwflag;
1354   int crflag, crflag2;
1355   int fd;
1356 
1357 #ifdef __CYGWIN__
1358   if (opp->file_len == 7)
1359     {
1360       if (strncmp (path, "CONOUT$", 7) == 0
1361 	  || strncmp (path, "CONERR$", 7) == 0)
1362 	{
1363 	  fd = open ("/dev/conout", O_WRONLY);
1364 	  flags->action = ACTION_WRITE;
1365 	  return fd;
1366 	}
1367     }
1368 
1369   if (opp->file_len == 6 && strncmp (path, "CONIN$", 6) == 0)
1370     {
1371       fd = open ("/dev/conin", O_RDONLY);
1372       flags->action = ACTION_READ;
1373       return fd;
1374     }
1375 #endif
1376 
1377 
1378 #ifdef __MINGW32__
1379   if (opp->file_len == 7)
1380     {
1381       if (strncmp (path, "CONOUT$", 7) == 0
1382 	  || strncmp (path, "CONERR$", 7) == 0)
1383 	{
1384 	  fd = open ("CONOUT$", O_WRONLY);
1385 	  flags->action = ACTION_WRITE;
1386 	  return fd;
1387 	}
1388     }
1389 
1390   if (opp->file_len == 6 && strncmp (path, "CONIN$", 6) == 0)
1391     {
1392       fd = open ("CONIN$", O_RDONLY);
1393       flags->action = ACTION_READ;
1394       return fd;
1395     }
1396 #endif
1397 
1398   switch (flags->action)
1399     {
1400     case ACTION_READ:
1401       rwflag = O_RDONLY;
1402       break;
1403 
1404     case ACTION_WRITE:
1405       rwflag = O_WRONLY;
1406       break;
1407 
1408     case ACTION_READWRITE:
1409     case ACTION_UNSPECIFIED:
1410       rwflag = O_RDWR;
1411       break;
1412 
1413     default:
1414       internal_error (&opp->common, "regular_file(): Bad action");
1415     }
1416 
1417   switch (flags->status)
1418     {
1419     case STATUS_NEW:
1420       crflag = O_CREAT | O_EXCL;
1421       break;
1422 
1423     case STATUS_OLD:		/* open will fail if the file does not exist*/
1424       crflag = 0;
1425       break;
1426 
1427     case STATUS_UNKNOWN:
1428       if (rwflag == O_RDONLY)
1429 	crflag = 0;
1430       else
1431 	crflag = O_CREAT;
1432       break;
1433 
1434     case STATUS_REPLACE:
1435       crflag = O_CREAT | O_TRUNC;
1436       break;
1437 
1438     default:
1439       /* Note: STATUS_SCRATCH is handled by tempfile () and should
1440 	 never be seen here.  */
1441       internal_error (&opp->common, "regular_file(): Bad status");
1442     }
1443 
1444   /* rwflag |= O_LARGEFILE; */
1445 
1446 #if defined(HAVE_CRLF) && defined(O_BINARY)
1447   crflag |= O_BINARY;
1448 #endif
1449 
1450 #ifdef O_CLOEXEC
1451   crflag |= O_CLOEXEC;
1452 #endif
1453 
1454   mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
1455   TEMP_FAILURE_RETRY (fd = open (path, rwflag | crflag, mode));
1456   if (flags->action != ACTION_UNSPECIFIED)
1457     return fd;
1458 
1459   if (fd >= 0)
1460     {
1461       flags->action = ACTION_READWRITE;
1462       return fd;
1463     }
1464   if (errno != EACCES && errno != EPERM && errno != EROFS)
1465      return fd;
1466 
1467   /* retry for read-only access */
1468   rwflag = O_RDONLY;
1469   if (flags->status == STATUS_UNKNOWN)
1470     crflag2 = crflag & ~(O_CREAT);
1471   else
1472     crflag2 = crflag;
1473   TEMP_FAILURE_RETRY (fd = open (path, rwflag | crflag2, mode));
1474   if (fd >=0)
1475     {
1476       flags->action = ACTION_READ;
1477       return fd;		/* success */
1478     }
1479 
1480   if (errno != EACCES && errno != EPERM && errno != ENOENT)
1481     return fd;			/* failure */
1482 
1483   /* retry for write-only access */
1484   rwflag = O_WRONLY;
1485   TEMP_FAILURE_RETRY (fd = open (path, rwflag | crflag, mode));
1486   if (fd >=0)
1487     {
1488       flags->action = ACTION_WRITE;
1489       return fd;		/* success */
1490     }
1491   return fd;			/* failure */
1492 }
1493 
1494 
1495 /* Lock the file, if necessary, based on SHARE flags.  */
1496 
1497 #if defined(HAVE_FCNTL) && defined(F_SETLK) && defined(F_UNLCK)
1498 static int
open_share(st_parameter_open * opp,int fd,unit_flags * flags)1499 open_share (st_parameter_open *opp, int fd, unit_flags *flags)
1500 {
1501   int r = 0;
1502   struct flock f;
1503   if (fd == STDOUT_FILENO || fd == STDERR_FILENO || fd == STDIN_FILENO)
1504     return 0;
1505 
1506   f.l_start = 0;
1507   f.l_len = 0;
1508   f.l_whence = SEEK_SET;
1509 
1510   switch (flags->share)
1511   {
1512     case SHARE_DENYNONE:
1513       f.l_type = F_RDLCK;
1514       r = fcntl (fd, F_SETLK, &f);
1515       break;
1516     case SHARE_DENYRW:
1517       /* Must be writable to hold write lock.  */
1518       if (flags->action == ACTION_READ)
1519 	{
1520 	  generate_error (&opp->common, LIBERROR_BAD_ACTION,
1521 	      "Cannot set write lock on file opened for READ");
1522 	  return -1;
1523 	}
1524       f.l_type = F_WRLCK;
1525       r = fcntl (fd, F_SETLK, &f);
1526       break;
1527     case SHARE_UNSPECIFIED:
1528     default:
1529       break;
1530   }
1531 
1532   return r;
1533 }
1534 #else
1535 static int
open_share(st_parameter_open * opp,int fd,unit_flags * flags)1536 open_share (st_parameter_open *opp __attribute__ ((unused)),
1537     int fd __attribute__ ((unused)),
1538     unit_flags *flags __attribute__ ((unused)))
1539 {
1540   return 0;
1541 }
1542 #endif /* defined(HAVE_FCNTL) ... */
1543 
1544 
1545 /* Wrapper around regular_file2, to make sure we free the path after
1546    we're done.  */
1547 
1548 static int
regular_file(st_parameter_open * opp,unit_flags * flags)1549 regular_file (st_parameter_open *opp, unit_flags *flags)
1550 {
1551   char *path = fc_strdup (opp->file, opp->file_len);
1552   int fd = regular_file2 (path, opp, flags);
1553   free (path);
1554   return fd;
1555 }
1556 
1557 /* open_external()-- Open an external file, unix specific version.
1558    Change flags->action if it is ACTION_UNSPECIFIED on entry.
1559    Returns NULL on operating system error. */
1560 
1561 stream *
open_external(st_parameter_open * opp,unit_flags * flags)1562 open_external (st_parameter_open *opp, unit_flags *flags)
1563 {
1564   int fd;
1565 
1566   if (flags->status == STATUS_SCRATCH)
1567     {
1568       fd = tempfile (opp);
1569       if (flags->action == ACTION_UNSPECIFIED)
1570 	flags->action = flags->readonly ? ACTION_READ : ACTION_READWRITE;
1571 
1572 #if HAVE_UNLINK_OPEN_FILE
1573       /* We can unlink scratch files now and it will go away when closed. */
1574       if (fd >= 0)
1575 	unlink (opp->file);
1576 #endif
1577     }
1578   else
1579     {
1580       /* regular_file resets flags->action if it is ACTION_UNSPECIFIED and
1581          if it succeeds */
1582       fd = regular_file (opp, flags);
1583 #ifndef O_CLOEXEC
1584       set_close_on_exec (fd);
1585 #endif
1586     }
1587 
1588   if (fd < 0)
1589     return NULL;
1590   fd = fix_fd (fd);
1591 
1592   if (open_share (opp, fd, flags) < 0)
1593     return NULL;
1594 
1595   return fd_to_stream (fd, flags->form == FORM_UNFORMATTED);
1596 }
1597 
1598 
1599 /* input_stream()-- Return a stream pointer to the default input stream.
1600    Called on initialization. */
1601 
1602 stream *
input_stream(void)1603 input_stream (void)
1604 {
1605   return fd_to_stream (STDIN_FILENO, false);
1606 }
1607 
1608 
1609 /* output_stream()-- Return a stream pointer to the default output stream.
1610    Called on initialization. */
1611 
1612 stream *
output_stream(void)1613 output_stream (void)
1614 {
1615   stream *s;
1616 
1617 #if defined(HAVE_CRLF) && defined(HAVE_SETMODE)
1618   setmode (STDOUT_FILENO, O_BINARY);
1619 #endif
1620 
1621   s = fd_to_stream (STDOUT_FILENO, false);
1622   return s;
1623 }
1624 
1625 
1626 /* error_stream()-- Return a stream pointer to the default error stream.
1627    Called on initialization. */
1628 
1629 stream *
error_stream(void)1630 error_stream (void)
1631 {
1632   stream *s;
1633 
1634 #if defined(HAVE_CRLF) && defined(HAVE_SETMODE)
1635   setmode (STDERR_FILENO, O_BINARY);
1636 #endif
1637 
1638   s = fd_to_stream (STDERR_FILENO, false);
1639   return s;
1640 }
1641 
1642 
1643 /* compare_file_filename()-- Given an open stream and a fortran string
1644    that is a filename, figure out if the file is the same as the
1645    filename. */
1646 
1647 int
compare_file_filename(gfc_unit * u,const char * name,gfc_charlen_type len)1648 compare_file_filename (gfc_unit *u, const char *name, gfc_charlen_type len)
1649 {
1650   struct stat st;
1651   int ret;
1652 #ifdef HAVE_WORKING_STAT
1653   unix_stream *s;
1654 #else
1655 # ifdef __MINGW32__
1656   uint64_t id1, id2;
1657 # endif
1658 #endif
1659 
1660   char *path = fc_strdup (name, len);
1661 
1662   /* If the filename doesn't exist, then there is no match with the
1663      existing file. */
1664 
1665   if (TEMP_FAILURE_RETRY (stat (path, &st)) < 0)
1666     {
1667       ret = 0;
1668       goto done;
1669     }
1670 
1671 #ifdef HAVE_WORKING_STAT
1672   s = (unix_stream *) (u->s);
1673   ret = (st.st_dev == s->st_dev) && (st.st_ino == s->st_ino);
1674   goto done;
1675 #else
1676 
1677 # ifdef __MINGW32__
1678   /* We try to match files by a unique ID.  On some filesystems (network
1679      fs and FAT), we can't generate this unique ID, and will simply compare
1680      filenames.  */
1681   id1 = id_from_path (path);
1682   id2 = id_from_fd (((unix_stream *) (u->s))->fd);
1683   if (id1 || id2)
1684     {
1685       ret = (id1 == id2);
1686       goto done;
1687     }
1688 # endif
1689   if (u->filename)
1690     ret = (strcmp(path, u->filename) == 0);
1691   else
1692     ret = 0;
1693 #endif
1694  done:
1695   free (path);
1696   return ret;
1697 }
1698 
1699 
1700 #ifdef HAVE_WORKING_STAT
1701 # define FIND_FILE0_DECL struct stat *st
1702 # define FIND_FILE0_ARGS st
1703 #else
1704 # define FIND_FILE0_DECL uint64_t id, const char *path
1705 # define FIND_FILE0_ARGS id, path
1706 #endif
1707 
1708 /* find_file0()-- Recursive work function for find_file() */
1709 
1710 static gfc_unit *
find_file0(gfc_unit * u,FIND_FILE0_DECL)1711 find_file0 (gfc_unit *u, FIND_FILE0_DECL)
1712 {
1713   gfc_unit *v;
1714 #if defined(__MINGW32__) && !HAVE_WORKING_STAT
1715   uint64_t id1;
1716 #endif
1717 
1718   if (u == NULL)
1719     return NULL;
1720 
1721 #ifdef HAVE_WORKING_STAT
1722   if (u->s != NULL)
1723     {
1724       unix_stream *s = (unix_stream *) (u->s);
1725       if (st[0].st_dev == s->st_dev && st[0].st_ino == s->st_ino)
1726 	return u;
1727     }
1728 #else
1729 # ifdef __MINGW32__
1730   if (u->s && ((id1 = id_from_fd (((unix_stream *) u->s)->fd)) || id1))
1731     {
1732       if (id == id1)
1733 	return u;
1734     }
1735   else
1736 # endif
1737     if (u->filename && strcmp (u->filename, path) == 0)
1738       return u;
1739 #endif
1740 
1741   v = find_file0 (u->left, FIND_FILE0_ARGS);
1742   if (v != NULL)
1743     return v;
1744 
1745   v = find_file0 (u->right, FIND_FILE0_ARGS);
1746   if (v != NULL)
1747     return v;
1748 
1749   return NULL;
1750 }
1751 
1752 
1753 /* find_file()-- Take the current filename and see if there is a unit
1754    that has the file already open.  Returns a pointer to the unit if so. */
1755 
1756 gfc_unit *
find_file(const char * file,gfc_charlen_type file_len)1757 find_file (const char *file, gfc_charlen_type file_len)
1758 {
1759   struct stat st[1];
1760   gfc_unit *u;
1761 #if defined(__MINGW32__) && !HAVE_WORKING_STAT
1762   uint64_t id = 0ULL;
1763 #endif
1764 
1765   char *path = fc_strdup (file, file_len);
1766 
1767   if (TEMP_FAILURE_RETRY (stat (path, &st[0])) < 0)
1768     {
1769       u = NULL;
1770       goto done;
1771     }
1772 
1773 #if defined(__MINGW32__) && !HAVE_WORKING_STAT
1774   id = id_from_path (path);
1775 #endif
1776 
1777   LOCK (&unit_lock);
1778 retry:
1779   u = find_file0 (unit_root, FIND_FILE0_ARGS);
1780   if (u != NULL)
1781     {
1782       /* Fast path.  */
1783       if (! __gthread_mutex_trylock (&u->lock))
1784 	{
1785 	  /* assert (u->closed == 0); */
1786 	  UNLOCK (&unit_lock);
1787 	  goto done;
1788 	}
1789 
1790       inc_waiting_locked (u);
1791     }
1792   UNLOCK (&unit_lock);
1793   if (u != NULL)
1794     {
1795       LOCK (&u->lock);
1796       if (u->closed)
1797 	{
1798 	  LOCK (&unit_lock);
1799 	  UNLOCK (&u->lock);
1800 	  if (predec_waiting_locked (u) == 0)
1801 	    free (u);
1802 	  goto retry;
1803 	}
1804 
1805       dec_waiting_unlocked (u);
1806     }
1807  done:
1808   free (path);
1809   return u;
1810 }
1811 
1812 static gfc_unit *
flush_all_units_1(gfc_unit * u,int min_unit)1813 flush_all_units_1 (gfc_unit *u, int min_unit)
1814 {
1815   while (u != NULL)
1816     {
1817       if (u->unit_number > min_unit)
1818 	{
1819 	  gfc_unit *r = flush_all_units_1 (u->left, min_unit);
1820 	  if (r != NULL)
1821 	    return r;
1822 	}
1823       if (u->unit_number >= min_unit)
1824 	{
1825 	  if (__gthread_mutex_trylock (&u->lock))
1826 	    return u;
1827 	  if (u->s)
1828 	    sflush (u->s);
1829 	  UNLOCK (&u->lock);
1830 	}
1831       u = u->right;
1832     }
1833   return NULL;
1834 }
1835 
1836 void
flush_all_units(void)1837 flush_all_units (void)
1838 {
1839   gfc_unit *u;
1840   int min_unit = 0;
1841 
1842   LOCK (&unit_lock);
1843   do
1844     {
1845       u = flush_all_units_1 (unit_root, min_unit);
1846       if (u != NULL)
1847 	inc_waiting_locked (u);
1848       UNLOCK (&unit_lock);
1849       if (u == NULL)
1850 	return;
1851 
1852       LOCK (&u->lock);
1853 
1854       min_unit = u->unit_number + 1;
1855 
1856       if (u->closed == 0)
1857 	{
1858 	  sflush (u->s);
1859 	  LOCK (&unit_lock);
1860 	  UNLOCK (&u->lock);
1861 	  (void) predec_waiting_locked (u);
1862 	}
1863       else
1864 	{
1865 	  LOCK (&unit_lock);
1866 	  UNLOCK (&u->lock);
1867 	  if (predec_waiting_locked (u) == 0)
1868 	    free (u);
1869 	}
1870     }
1871   while (1);
1872 }
1873 
1874 
1875 /* Unlock the unit if necessary, based on SHARE flags.  */
1876 
1877 int
close_share(gfc_unit * u)1878 close_share (gfc_unit *u __attribute__ ((unused)))
1879 {
1880   int r = 0;
1881 #if defined(HAVE_FCNTL) && defined(F_SETLK) && defined(F_UNLCK)
1882   unix_stream *s = (unix_stream *) u->s;
1883   int fd = s->fd;
1884   struct flock f;
1885 
1886   switch (u->flags.share)
1887   {
1888     case SHARE_DENYRW:
1889     case SHARE_DENYNONE:
1890       if (fd != STDOUT_FILENO && fd != STDERR_FILENO && fd != STDIN_FILENO)
1891 	{
1892 	  f.l_start = 0;
1893 	  f.l_len = 0;
1894 	  f.l_whence = SEEK_SET;
1895 	  f.l_type = F_UNLCK;
1896 	  r = fcntl (fd, F_SETLK, &f);
1897 	}
1898       break;
1899     case SHARE_UNSPECIFIED:
1900     default:
1901       break;
1902   }
1903 
1904 #endif
1905   return r;
1906 }
1907 
1908 
1909 /* file_exists()-- Returns nonzero if the current filename exists on
1910    the system */
1911 
1912 int
file_exists(const char * file,gfc_charlen_type file_len)1913 file_exists (const char *file, gfc_charlen_type file_len)
1914 {
1915   char *path = fc_strdup (file, file_len);
1916   int res = !(access (path, F_OK));
1917   free (path);
1918   return res;
1919 }
1920 
1921 
1922 /* file_size()-- Returns the size of the file.  */
1923 
1924 GFC_IO_INT
file_size(const char * file,gfc_charlen_type file_len)1925 file_size (const char *file, gfc_charlen_type file_len)
1926 {
1927   char *path = fc_strdup (file, file_len);
1928   struct stat statbuf;
1929   int err;
1930   TEMP_FAILURE_RETRY (err = stat (path, &statbuf));
1931   free (path);
1932   if (err == -1)
1933     return -1;
1934   return (GFC_IO_INT) statbuf.st_size;
1935 }
1936 
1937 static const char yes[] = "YES", no[] = "NO", unknown[] = "UNKNOWN";
1938 
1939 /* inquire_sequential()-- Given a fortran string, determine if the
1940    file is suitable for sequential access.  Returns a C-style
1941    string. */
1942 
1943 const char *
inquire_sequential(const char * string,gfc_charlen_type len)1944 inquire_sequential (const char *string, gfc_charlen_type len)
1945 {
1946   struct stat statbuf;
1947 
1948   if (string == NULL)
1949     return unknown;
1950 
1951   char *path = fc_strdup (string, len);
1952   int err;
1953   TEMP_FAILURE_RETRY (err = stat (path, &statbuf));
1954   free (path);
1955   if (err == -1)
1956     return unknown;
1957 
1958   if (S_ISREG (statbuf.st_mode) ||
1959       S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode))
1960     return unknown;
1961 
1962   if (S_ISDIR (statbuf.st_mode) || S_ISBLK (statbuf.st_mode))
1963     return no;
1964 
1965   return unknown;
1966 }
1967 
1968 
1969 /* inquire_direct()-- Given a fortran string, determine if the file is
1970    suitable for direct access.  Returns a C-style string. */
1971 
1972 const char *
inquire_direct(const char * string,gfc_charlen_type len)1973 inquire_direct (const char *string, gfc_charlen_type len)
1974 {
1975   struct stat statbuf;
1976 
1977   if (string == NULL)
1978     return unknown;
1979 
1980   char *path = fc_strdup (string, len);
1981   int err;
1982   TEMP_FAILURE_RETRY (err = stat (path, &statbuf));
1983   free (path);
1984   if (err == -1)
1985     return unknown;
1986 
1987   if (S_ISREG (statbuf.st_mode) || S_ISBLK (statbuf.st_mode))
1988     return unknown;
1989 
1990   if (S_ISDIR (statbuf.st_mode) ||
1991       S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode))
1992     return no;
1993 
1994   return unknown;
1995 }
1996 
1997 
1998 /* inquire_formatted()-- Given a fortran string, determine if the file
1999    is suitable for formatted form.  Returns a C-style string. */
2000 
2001 const char *
inquire_formatted(const char * string,gfc_charlen_type len)2002 inquire_formatted (const char *string, gfc_charlen_type len)
2003 {
2004   struct stat statbuf;
2005 
2006   if (string == NULL)
2007     return unknown;
2008 
2009   char *path = fc_strdup (string, len);
2010   int err;
2011   TEMP_FAILURE_RETRY (err = stat (path, &statbuf));
2012   free (path);
2013   if (err == -1)
2014     return unknown;
2015 
2016   if (S_ISREG (statbuf.st_mode) ||
2017       S_ISBLK (statbuf.st_mode) ||
2018       S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode))
2019     return unknown;
2020 
2021   if (S_ISDIR (statbuf.st_mode))
2022     return no;
2023 
2024   return unknown;
2025 }
2026 
2027 
2028 /* inquire_unformatted()-- Given a fortran string, determine if the file
2029    is suitable for unformatted form.  Returns a C-style string. */
2030 
2031 const char *
inquire_unformatted(const char * string,gfc_charlen_type len)2032 inquire_unformatted (const char *string, gfc_charlen_type len)
2033 {
2034   return inquire_formatted (string, len);
2035 }
2036 
2037 
2038 /* inquire_access()-- Given a fortran string, determine if the file is
2039    suitable for access. */
2040 
2041 static const char *
inquire_access(const char * string,gfc_charlen_type len,int mode)2042 inquire_access (const char *string, gfc_charlen_type len, int mode)
2043 {
2044   if (string == NULL)
2045     return no;
2046   char *path = fc_strdup (string, len);
2047   int res = access (path, mode);
2048   free (path);
2049   if (res == -1)
2050     return no;
2051 
2052   return yes;
2053 }
2054 
2055 
2056 /* inquire_read()-- Given a fortran string, determine if the file is
2057    suitable for READ access. */
2058 
2059 const char *
inquire_read(const char * string,gfc_charlen_type len)2060 inquire_read (const char *string, gfc_charlen_type len)
2061 {
2062   return inquire_access (string, len, R_OK);
2063 }
2064 
2065 
2066 /* inquire_write()-- Given a fortran string, determine if the file is
2067    suitable for READ access. */
2068 
2069 const char *
inquire_write(const char * string,gfc_charlen_type len)2070 inquire_write (const char *string, gfc_charlen_type len)
2071 {
2072   return inquire_access (string, len, W_OK);
2073 }
2074 
2075 
2076 /* inquire_readwrite()-- Given a fortran string, determine if the file is
2077    suitable for read and write access. */
2078 
2079 const char *
inquire_readwrite(const char * string,gfc_charlen_type len)2080 inquire_readwrite (const char *string, gfc_charlen_type len)
2081 {
2082   return inquire_access (string, len, R_OK | W_OK);
2083 }
2084 
2085 
2086 int
stream_isatty(stream * s)2087 stream_isatty (stream *s)
2088 {
2089   return isatty (((unix_stream *) s)->fd);
2090 }
2091 
2092 int
stream_ttyname(stream * s,char * buf,size_t buflen)2093 stream_ttyname (stream *s  __attribute__ ((unused)),
2094 		char *buf  __attribute__ ((unused)),
2095 		size_t buflen  __attribute__ ((unused)))
2096 {
2097 #ifdef HAVE_TTYNAME_R
2098   return ttyname_r (((unix_stream *)s)->fd, buf, buflen);
2099 #elif defined HAVE_TTYNAME
2100   char *p;
2101   size_t plen;
2102   p = ttyname (((unix_stream *)s)->fd);
2103   if (!p)
2104     return errno;
2105   plen = strlen (p);
2106   if (buflen < plen)
2107     plen = buflen;
2108   memcpy (buf, p, plen);
2109   return 0;
2110 #else
2111   return ENOSYS;
2112 #endif
2113 }
2114 
2115 
2116 
2117 
2118 /* How files are stored:  This is an operating-system specific issue,
2119    and therefore belongs here.  There are three cases to consider.
2120 
2121    Direct Access:
2122       Records are written as block of bytes corresponding to the record
2123       length of the file.  This goes for both formatted and unformatted
2124       records.  Positioning is done explicitly for each data transfer,
2125       so positioning is not much of an issue.
2126 
2127    Sequential Formatted:
2128       Records are separated by newline characters.  The newline character
2129       is prohibited from appearing in a string.  If it does, this will be
2130       messed up on the next read.  End of file is also the end of a record.
2131 
2132    Sequential Unformatted:
2133       In this case, we are merely copying bytes to and from main storage,
2134       yet we need to keep track of varying record lengths.  We adopt
2135       the solution used by f2c.  Each record contains a pair of length
2136       markers:
2137 
2138 	Length of record n in bytes
2139 	Data of record n
2140 	Length of record n in bytes
2141 
2142 	Length of record n+1 in bytes
2143 	Data of record n+1
2144 	Length of record n+1 in bytes
2145 
2146      The length is stored at the end of a record to allow backspacing to the
2147      previous record.  Between data transfer statements, the file pointer
2148      is left pointing to the first length of the current record.
2149 
2150      ENDFILE records are never explicitly stored.
2151 
2152 */
2153