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