]> git.ipfire.org Git - thirdparty/gcc.git/blob - libgfortran/io/unix.c
Update copyright years.
[thirdparty/gcc.git] / libgfortran / io / unix.c
1 /* Copyright (C) 2002-2022 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
724 buf_tell (unix_stream *s)
725 {
726 return buf_seek (s, 0, SEEK_CUR);
727 }
728
729 static gfc_offset
730 buf_size (unix_stream *s)
731 {
732 return s->file_length;
733 }
734
735 static int
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
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
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 *
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 *
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 *
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 *
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
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
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
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
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
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
1007 mem_tell (stream *s)
1008 {
1009 return ((unix_stream *)s)->logical_offset;
1010 }
1011
1012
1013 static int
1014 mem_truncate (unix_stream *s __attribute__ ((unused)),
1015 gfc_offset length __attribute__ ((unused)))
1016 {
1017 return 0;
1018 }
1019
1020
1021 static int
1022 mem_flush (unix_stream *s __attribute__ ((unused)))
1023 {
1024 return 0;
1025 }
1026
1027
1028 static int
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 *
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 *
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 *
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
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))
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
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
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
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
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
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
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 *
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 *
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 *
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 *
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
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 *
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 *
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 *
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
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
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
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
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 *
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 *
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 *
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 *
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 *
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 *
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 *
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 *
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
2087 stream_isatty (stream *s)
2088 {
2089 return isatty (((unix_stream *) s)->fd);
2090 }
2091
2092 int
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 */