1 1.1.1.4 mrg /* Copyright (C) 2002-2024 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.1.4 mrg free (s); 1032 1.1 mrg return 0; 1033 1.1 mrg } 1034 1.1 mrg 1035 1.1 mrg static const struct stream_vtable mem_vtable = { 1036 1.1 mrg .read = (void *) mem_read, 1037 1.1 mrg .write = (void *) mem_write, 1038 1.1 mrg .seek = (void *) mem_seek, 1039 1.1 mrg .tell = (void *) mem_tell, 1040 1.1 mrg /* buf_size is not a typo, we just reuse an identical 1041 1.1 mrg implementation. */ 1042 1.1 mrg .size = (void *) buf_size, 1043 1.1 mrg .trunc = (void *) mem_truncate, 1044 1.1 mrg .close = (void *) mem_close, 1045 1.1 mrg .flush = (void *) mem_flush, 1046 1.1 mrg .markeor = (void *) raw_markeor 1047 1.1 mrg }; 1048 1.1 mrg 1049 1.1 mrg static const struct stream_vtable mem4_vtable = { 1050 1.1 mrg .read = (void *) mem_read4, 1051 1.1 mrg .write = (void *) mem_write4, 1052 1.1 mrg .seek = (void *) mem_seek, 1053 1.1 mrg .tell = (void *) mem_tell, 1054 1.1 mrg /* buf_size is not a typo, we just reuse an identical 1055 1.1 mrg implementation. */ 1056 1.1 mrg .size = (void *) buf_size, 1057 1.1 mrg .trunc = (void *) mem_truncate, 1058 1.1 mrg .close = (void *) mem_close, 1059 1.1 mrg .flush = (void *) mem_flush, 1060 1.1 mrg .markeor = (void *) raw_markeor 1061 1.1 mrg }; 1062 1.1 mrg 1063 1.1 mrg /********************************************************************* 1064 1.1 mrg Public functions -- A reimplementation of this module needs to 1065 1.1 mrg define functional equivalents of the following. 1066 1.1 mrg *********************************************************************/ 1067 1.1 mrg 1068 1.1 mrg /* open_internal()-- Returns a stream structure from a character(kind=1) 1069 1.1 mrg internal file */ 1070 1.1 mrg 1071 1.1 mrg stream * 1072 1.1 mrg open_internal (char *base, size_t length, gfc_offset offset) 1073 1.1 mrg { 1074 1.1 mrg unix_stream *s; 1075 1.1 mrg 1076 1.1 mrg s = xcalloc (1, sizeof (unix_stream)); 1077 1.1 mrg 1078 1.1 mrg s->buffer = base; 1079 1.1 mrg s->buffer_offset = offset; 1080 1.1 mrg 1081 1.1 mrg s->active = s->file_length = length; 1082 1.1 mrg 1083 1.1 mrg s->st.vptr = &mem_vtable; 1084 1.1 mrg 1085 1.1 mrg return (stream *) s; 1086 1.1 mrg } 1087 1.1 mrg 1088 1.1 mrg /* open_internal4()-- Returns a stream structure from a character(kind=4) 1089 1.1 mrg internal file */ 1090 1.1 mrg 1091 1.1 mrg stream * 1092 1.1 mrg open_internal4 (char *base, size_t length, gfc_offset offset) 1093 1.1 mrg { 1094 1.1 mrg unix_stream *s; 1095 1.1 mrg 1096 1.1 mrg s = xcalloc (1, sizeof (unix_stream)); 1097 1.1 mrg 1098 1.1 mrg s->buffer = base; 1099 1.1 mrg s->buffer_offset = offset; 1100 1.1 mrg 1101 1.1 mrg s->active = s->file_length = length * sizeof (gfc_char4_t); 1102 1.1 mrg 1103 1.1 mrg s->st.vptr = &mem4_vtable; 1104 1.1 mrg 1105 1.1 mrg return (stream *)s; 1106 1.1 mrg } 1107 1.1 mrg 1108 1.1 mrg 1109 1.1 mrg /* fd_to_stream()-- Given an open file descriptor, build a stream 1110 1.1 mrg around it. */ 1111 1.1 mrg 1112 1.1 mrg static stream * 1113 1.1 mrg fd_to_stream (int fd, bool unformatted) 1114 1.1 mrg { 1115 1.1 mrg struct stat statbuf; 1116 1.1 mrg unix_stream *s; 1117 1.1 mrg 1118 1.1 mrg s = xcalloc (1, sizeof (unix_stream)); 1119 1.1 mrg 1120 1.1 mrg s->fd = fd; 1121 1.1 mrg 1122 1.1 mrg /* Get the current length of the file. */ 1123 1.1 mrg 1124 1.1 mrg if (TEMP_FAILURE_RETRY (fstat (fd, &statbuf)) == -1) 1125 1.1 mrg { 1126 1.1 mrg s->st_dev = s->st_ino = -1; 1127 1.1 mrg s->file_length = 0; 1128 1.1 mrg if (errno == EBADF) 1129 1.1 mrg s->fd = -1; 1130 1.1 mrg raw_init (s); 1131 1.1 mrg return (stream *) s; 1132 1.1 mrg } 1133 1.1 mrg 1134 1.1 mrg s->st_dev = statbuf.st_dev; 1135 1.1 mrg s->st_ino = statbuf.st_ino; 1136 1.1 mrg s->file_length = statbuf.st_size; 1137 1.1 mrg 1138 1.1 mrg /* Only use buffered IO for regular files. */ 1139 1.1 mrg if (S_ISREG (statbuf.st_mode) 1140 1.1 mrg && !options.all_unbuffered 1141 1.1 mrg && !(options.unbuffered_preconnected && 1142 1.1 mrg (s->fd == STDIN_FILENO 1143 1.1 mrg || s->fd == STDOUT_FILENO 1144 1.1 mrg || s->fd == STDERR_FILENO))) 1145 1.1 mrg buf_init (s, unformatted); 1146 1.1 mrg else 1147 1.1 mrg { 1148 1.1 mrg if (unformatted) 1149 1.1 mrg { 1150 1.1 mrg s->unbuffered = true; 1151 1.1 mrg buf_init (s, unformatted); 1152 1.1 mrg } 1153 1.1 mrg else 1154 1.1 mrg raw_init (s); 1155 1.1 mrg } 1156 1.1 mrg 1157 1.1 mrg return (stream *) s; 1158 1.1 mrg } 1159 1.1 mrg 1160 1.1 mrg 1161 1.1 mrg /* Given the Fortran unit number, convert it to a C file descriptor. */ 1162 1.1 mrg 1163 1.1 mrg int 1164 1.1 mrg unit_to_fd (int unit) 1165 1.1 mrg { 1166 1.1 mrg gfc_unit *us; 1167 1.1 mrg int fd; 1168 1.1 mrg 1169 1.1 mrg us = find_unit (unit); 1170 1.1 mrg if (us == NULL) 1171 1.1 mrg return -1; 1172 1.1 mrg 1173 1.1 mrg fd = ((unix_stream *) us->s)->fd; 1174 1.1 mrg unlock_unit (us); 1175 1.1 mrg return fd; 1176 1.1 mrg } 1177 1.1 mrg 1178 1.1 mrg 1179 1.1 mrg /* Set the close-on-exec flag for an existing fd, if the system 1180 1.1 mrg supports such. */ 1181 1.1 mrg 1182 1.1 mrg static void __attribute__ ((unused)) 1183 1.1 mrg set_close_on_exec (int fd __attribute__ ((unused))) 1184 1.1 mrg { 1185 1.1 mrg /* Mingw does not define F_SETFD. */ 1186 1.1 mrg #if defined(HAVE_FCNTL) && defined(F_SETFD) && defined(FD_CLOEXEC) 1187 1.1 mrg if (fd >= 0) 1188 1.1 mrg fcntl(fd, F_SETFD, FD_CLOEXEC); 1189 1.1 mrg #endif 1190 1.1 mrg } 1191 1.1 mrg 1192 1.1 mrg 1193 1.1 mrg /* Helper function for tempfile(). Tries to open a temporary file in 1194 1.1 mrg the directory specified by tempdir. If successful, the file name is 1195 1.1 mrg stored in fname and the descriptor returned. Returns -1 on 1196 1.1 mrg failure. */ 1197 1.1 mrg 1198 1.1 mrg static int 1199 1.1 mrg tempfile_open (const char *tempdir, char **fname) 1200 1.1 mrg { 1201 1.1 mrg int fd; 1202 1.1 mrg const char *slash = "/"; 1203 1.1 mrg #if defined(HAVE_UMASK) && defined(HAVE_MKSTEMP) 1204 1.1 mrg mode_t mode_mask; 1205 1.1 mrg #endif 1206 1.1 mrg 1207 1.1 mrg if (!tempdir) 1208 1.1 mrg return -1; 1209 1.1 mrg 1210 1.1 mrg /* Check for the special case that tempdir ends with a slash or 1211 1.1 mrg backslash. */ 1212 1.1 mrg size_t tempdirlen = strlen (tempdir); 1213 1.1 mrg if (*tempdir == 0 || tempdir[tempdirlen - 1] == '/' 1214 1.1 mrg #ifdef __MINGW32__ 1215 1.1 mrg || tempdir[tempdirlen - 1] == '\\' 1216 1.1 mrg #endif 1217 1.1 mrg ) 1218 1.1 mrg slash = ""; 1219 1.1 mrg 1220 1.1 mrg /* Take care that the template is longer in the mktemp() branch. */ 1221 1.1 mrg char *template = xmalloc (tempdirlen + 23); 1222 1.1 mrg 1223 1.1 mrg #ifdef HAVE_MKSTEMP 1224 1.1 mrg snprintf (template, tempdirlen + 23, "%s%sgfortrantmpXXXXXX", 1225 1.1 mrg tempdir, slash); 1226 1.1 mrg 1227 1.1 mrg #ifdef HAVE_UMASK 1228 1.1 mrg /* Temporarily set the umask such that the file has 0600 permissions. */ 1229 1.1 mrg mode_mask = umask (S_IXUSR | S_IRWXG | S_IRWXO); 1230 1.1 mrg #endif 1231 1.1 mrg 1232 1.1 mrg #if defined(HAVE_MKOSTEMP) && defined(O_CLOEXEC) 1233 1.1 mrg TEMP_FAILURE_RETRY (fd = mkostemp (template, O_CLOEXEC)); 1234 1.1 mrg #else 1235 1.1 mrg TEMP_FAILURE_RETRY (fd = mkstemp (template)); 1236 1.1 mrg set_close_on_exec (fd); 1237 1.1 mrg #endif 1238 1.1 mrg 1239 1.1 mrg #ifdef HAVE_UMASK 1240 1.1 mrg (void) umask (mode_mask); 1241 1.1 mrg #endif 1242 1.1 mrg 1243 1.1 mrg #else /* HAVE_MKSTEMP */ 1244 1.1 mrg fd = -1; 1245 1.1 mrg int count = 0; 1246 1.1 mrg size_t slashlen = strlen (slash); 1247 1.1 mrg int flags = O_RDWR | O_CREAT | O_EXCL; 1248 1.1 mrg #if defined(HAVE_CRLF) && defined(O_BINARY) 1249 1.1 mrg flags |= O_BINARY; 1250 1.1 mrg #endif 1251 1.1 mrg #ifdef O_CLOEXEC 1252 1.1 mrg flags |= O_CLOEXEC; 1253 1.1 mrg #endif 1254 1.1 mrg do 1255 1.1 mrg { 1256 1.1 mrg snprintf (template, tempdirlen + 23, "%s%sgfortrantmpaaaXXXXXX", 1257 1.1 mrg tempdir, slash); 1258 1.1 mrg if (count > 0) 1259 1.1 mrg { 1260 1.1 mrg int c = count; 1261 1.1 mrg template[tempdirlen + slashlen + 13] = 'a' + (c% 26); 1262 1.1 mrg c /= 26; 1263 1.1 mrg template[tempdirlen + slashlen + 12] = 'a' + (c % 26); 1264 1.1 mrg c /= 26; 1265 1.1 mrg template[tempdirlen + slashlen + 11] = 'a' + (c % 26); 1266 1.1 mrg if (c >= 26) 1267 1.1 mrg break; 1268 1.1 mrg } 1269 1.1 mrg 1270 1.1 mrg if (!mktemp (template)) 1271 1.1 mrg { 1272 1.1 mrg errno = EEXIST; 1273 1.1 mrg count++; 1274 1.1 mrg continue; 1275 1.1 mrg } 1276 1.1 mrg 1277 1.1 mrg TEMP_FAILURE_RETRY (fd = open (template, flags, S_IRUSR | S_IWUSR)); 1278 1.1 mrg } 1279 1.1 mrg while (fd == -1 && errno == EEXIST); 1280 1.1 mrg #ifndef O_CLOEXEC 1281 1.1 mrg set_close_on_exec (fd); 1282 1.1 mrg #endif 1283 1.1 mrg #endif /* HAVE_MKSTEMP */ 1284 1.1 mrg 1285 1.1 mrg *fname = template; 1286 1.1 mrg return fd; 1287 1.1 mrg } 1288 1.1 mrg 1289 1.1 mrg 1290 1.1 mrg /* tempfile()-- Generate a temporary filename for a scratch file and 1291 1.1 mrg open it. mkstemp() opens the file for reading and writing, but the 1292 1.1 mrg library mode prevents anything that is not allowed. The descriptor 1293 1.1 mrg is returned, which is -1 on error. The template is pointed to by 1294 1.1 mrg opp->file, which is copied into the unit structure 1295 1.1 mrg and freed later. */ 1296 1.1 mrg 1297 1.1 mrg static int 1298 1.1 mrg tempfile (st_parameter_open *opp) 1299 1.1 mrg { 1300 1.1 mrg const char *tempdir; 1301 1.1 mrg char *fname; 1302 1.1 mrg int fd = -1; 1303 1.1 mrg 1304 1.1 mrg tempdir = secure_getenv ("TMPDIR"); 1305 1.1 mrg fd = tempfile_open (tempdir, &fname); 1306 1.1 mrg #ifdef __MINGW32__ 1307 1.1 mrg if (fd == -1) 1308 1.1 mrg { 1309 1.1 mrg char buffer[MAX_PATH + 1]; 1310 1.1 mrg DWORD ret; 1311 1.1 mrg ret = GetTempPath (MAX_PATH, buffer); 1312 1.1 mrg /* If we are not able to get a temp-directory, we use 1313 1.1 mrg current directory. */ 1314 1.1 mrg if (ret > MAX_PATH || !ret) 1315 1.1 mrg buffer[0] = 0; 1316 1.1 mrg else 1317 1.1 mrg buffer[ret] = 0; 1318 1.1 mrg tempdir = strdup (buffer); 1319 1.1 mrg fd = tempfile_open (tempdir, &fname); 1320 1.1 mrg } 1321 1.1 mrg #elif defined(__CYGWIN__) 1322 1.1 mrg if (fd == -1) 1323 1.1 mrg { 1324 1.1 mrg tempdir = secure_getenv ("TMP"); 1325 1.1 mrg fd = tempfile_open (tempdir, &fname); 1326 1.1 mrg } 1327 1.1 mrg if (fd == -1) 1328 1.1 mrg { 1329 1.1 mrg tempdir = secure_getenv ("TEMP"); 1330 1.1 mrg fd = tempfile_open (tempdir, &fname); 1331 1.1 mrg } 1332 1.1 mrg #endif 1333 1.1 mrg if (fd == -1) 1334 1.1 mrg fd = tempfile_open (P_tmpdir, &fname); 1335 1.1 mrg 1336 1.1 mrg opp->file = fname; 1337 1.1 mrg opp->file_len = strlen (fname); /* Don't include trailing nul */ 1338 1.1 mrg 1339 1.1 mrg return fd; 1340 1.1 mrg } 1341 1.1 mrg 1342 1.1 mrg 1343 1.1 mrg /* regular_file2()-- Open a regular file. 1344 1.1 mrg Change flags->action if it is ACTION_UNSPECIFIED on entry, 1345 1.1 mrg unless an error occurs. 1346 1.1 mrg Returns the descriptor, which is less than zero on error. */ 1347 1.1 mrg 1348 1.1 mrg static int 1349 1.1 mrg regular_file2 (const char *path, st_parameter_open *opp, unit_flags *flags) 1350 1.1 mrg { 1351 1.1 mrg int mode; 1352 1.1 mrg int rwflag; 1353 1.1 mrg int crflag, crflag2; 1354 1.1 mrg int fd; 1355 1.1 mrg 1356 1.1 mrg #ifdef __CYGWIN__ 1357 1.1 mrg if (opp->file_len == 7) 1358 1.1 mrg { 1359 1.1 mrg if (strncmp (path, "CONOUT$", 7) == 0 1360 1.1 mrg || strncmp (path, "CONERR$", 7) == 0) 1361 1.1 mrg { 1362 1.1 mrg fd = open ("/dev/conout", O_WRONLY); 1363 1.1 mrg flags->action = ACTION_WRITE; 1364 1.1 mrg return fd; 1365 1.1 mrg } 1366 1.1 mrg } 1367 1.1 mrg 1368 1.1 mrg if (opp->file_len == 6 && strncmp (path, "CONIN$", 6) == 0) 1369 1.1 mrg { 1370 1.1 mrg fd = open ("/dev/conin", O_RDONLY); 1371 1.1 mrg flags->action = ACTION_READ; 1372 1.1 mrg return fd; 1373 1.1 mrg } 1374 1.1 mrg #endif 1375 1.1 mrg 1376 1.1 mrg 1377 1.1 mrg #ifdef __MINGW32__ 1378 1.1 mrg if (opp->file_len == 7) 1379 1.1 mrg { 1380 1.1 mrg if (strncmp (path, "CONOUT$", 7) == 0 1381 1.1 mrg || strncmp (path, "CONERR$", 7) == 0) 1382 1.1 mrg { 1383 1.1 mrg fd = open ("CONOUT$", O_WRONLY); 1384 1.1 mrg flags->action = ACTION_WRITE; 1385 1.1 mrg return fd; 1386 1.1 mrg } 1387 1.1 mrg } 1388 1.1 mrg 1389 1.1 mrg if (opp->file_len == 6 && strncmp (path, "CONIN$", 6) == 0) 1390 1.1 mrg { 1391 1.1 mrg fd = open ("CONIN$", O_RDONLY); 1392 1.1 mrg flags->action = ACTION_READ; 1393 1.1 mrg return fd; 1394 1.1 mrg } 1395 1.1 mrg #endif 1396 1.1 mrg 1397 1.1 mrg switch (flags->action) 1398 1.1 mrg { 1399 1.1 mrg case ACTION_READ: 1400 1.1 mrg rwflag = O_RDONLY; 1401 1.1 mrg break; 1402 1.1 mrg 1403 1.1 mrg case ACTION_WRITE: 1404 1.1 mrg rwflag = O_WRONLY; 1405 1.1 mrg break; 1406 1.1 mrg 1407 1.1 mrg case ACTION_READWRITE: 1408 1.1 mrg case ACTION_UNSPECIFIED: 1409 1.1 mrg rwflag = O_RDWR; 1410 1.1 mrg break; 1411 1.1 mrg 1412 1.1 mrg default: 1413 1.1 mrg internal_error (&opp->common, "regular_file(): Bad action"); 1414 1.1 mrg } 1415 1.1 mrg 1416 1.1 mrg switch (flags->status) 1417 1.1 mrg { 1418 1.1 mrg case STATUS_NEW: 1419 1.1 mrg crflag = O_CREAT | O_EXCL; 1420 1.1 mrg break; 1421 1.1 mrg 1422 1.1 mrg case STATUS_OLD: /* open will fail if the file does not exist*/ 1423 1.1 mrg crflag = 0; 1424 1.1 mrg break; 1425 1.1 mrg 1426 1.1 mrg case STATUS_UNKNOWN: 1427 1.1 mrg if (rwflag == O_RDONLY) 1428 1.1 mrg crflag = 0; 1429 1.1 mrg else 1430 1.1 mrg crflag = O_CREAT; 1431 1.1 mrg break; 1432 1.1 mrg 1433 1.1 mrg case STATUS_REPLACE: 1434 1.1 mrg crflag = O_CREAT | O_TRUNC; 1435 1.1 mrg break; 1436 1.1 mrg 1437 1.1 mrg default: 1438 1.1 mrg /* Note: STATUS_SCRATCH is handled by tempfile () and should 1439 1.1 mrg never be seen here. */ 1440 1.1 mrg internal_error (&opp->common, "regular_file(): Bad status"); 1441 1.1 mrg } 1442 1.1 mrg 1443 1.1 mrg /* rwflag |= O_LARGEFILE; */ 1444 1.1 mrg 1445 1.1 mrg #if defined(HAVE_CRLF) && defined(O_BINARY) 1446 1.1 mrg crflag |= O_BINARY; 1447 1.1 mrg #endif 1448 1.1 mrg 1449 1.1 mrg #ifdef O_CLOEXEC 1450 1.1 mrg crflag |= O_CLOEXEC; 1451 1.1 mrg #endif 1452 1.1 mrg 1453 1.1 mrg mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; 1454 1.1 mrg TEMP_FAILURE_RETRY (fd = open (path, rwflag | crflag, mode)); 1455 1.1 mrg if (flags->action != ACTION_UNSPECIFIED) 1456 1.1 mrg return fd; 1457 1.1 mrg 1458 1.1 mrg if (fd >= 0) 1459 1.1 mrg { 1460 1.1 mrg flags->action = ACTION_READWRITE; 1461 1.1 mrg return fd; 1462 1.1 mrg } 1463 1.1 mrg if (errno != EACCES && errno != EPERM && errno != EROFS) 1464 1.1 mrg return fd; 1465 1.1 mrg 1466 1.1 mrg /* retry for read-only access */ 1467 1.1 mrg rwflag = O_RDONLY; 1468 1.1 mrg if (flags->status == STATUS_UNKNOWN) 1469 1.1 mrg crflag2 = crflag & ~(O_CREAT); 1470 1.1 mrg else 1471 1.1 mrg crflag2 = crflag; 1472 1.1 mrg TEMP_FAILURE_RETRY (fd = open (path, rwflag | crflag2, mode)); 1473 1.1 mrg if (fd >=0) 1474 1.1 mrg { 1475 1.1 mrg flags->action = ACTION_READ; 1476 1.1 mrg return fd; /* success */ 1477 1.1 mrg } 1478 1.1 mrg 1479 1.1 mrg if (errno != EACCES && errno != EPERM && errno != ENOENT) 1480 1.1 mrg return fd; /* failure */ 1481 1.1 mrg 1482 1.1 mrg /* retry for write-only access */ 1483 1.1 mrg rwflag = O_WRONLY; 1484 1.1 mrg TEMP_FAILURE_RETRY (fd = open (path, rwflag | crflag, mode)); 1485 1.1 mrg if (fd >=0) 1486 1.1 mrg { 1487 1.1 mrg flags->action = ACTION_WRITE; 1488 1.1 mrg return fd; /* success */ 1489 1.1 mrg } 1490 1.1 mrg return fd; /* failure */ 1491 1.1 mrg } 1492 1.1 mrg 1493 1.1 mrg 1494 1.1 mrg /* Lock the file, if necessary, based on SHARE flags. */ 1495 1.1 mrg 1496 1.1 mrg #if defined(HAVE_FCNTL) && defined(F_SETLK) && defined(F_UNLCK) 1497 1.1 mrg static int 1498 1.1 mrg open_share (st_parameter_open *opp, int fd, unit_flags *flags) 1499 1.1 mrg { 1500 1.1 mrg int r = 0; 1501 1.1 mrg struct flock f; 1502 1.1 mrg if (fd == STDOUT_FILENO || fd == STDERR_FILENO || fd == STDIN_FILENO) 1503 1.1 mrg return 0; 1504 1.1 mrg 1505 1.1 mrg f.l_start = 0; 1506 1.1 mrg f.l_len = 0; 1507 1.1 mrg f.l_whence = SEEK_SET; 1508 1.1 mrg 1509 1.1 mrg switch (flags->share) 1510 1.1 mrg { 1511 1.1 mrg case SHARE_DENYNONE: 1512 1.1 mrg f.l_type = F_RDLCK; 1513 1.1 mrg r = fcntl (fd, F_SETLK, &f); 1514 1.1 mrg break; 1515 1.1 mrg case SHARE_DENYRW: 1516 1.1 mrg /* Must be writable to hold write lock. */ 1517 1.1 mrg if (flags->action == ACTION_READ) 1518 1.1 mrg { 1519 1.1 mrg generate_error (&opp->common, LIBERROR_BAD_ACTION, 1520 1.1 mrg "Cannot set write lock on file opened for READ"); 1521 1.1 mrg return -1; 1522 1.1 mrg } 1523 1.1 mrg f.l_type = F_WRLCK; 1524 1.1 mrg r = fcntl (fd, F_SETLK, &f); 1525 1.1 mrg break; 1526 1.1 mrg case SHARE_UNSPECIFIED: 1527 1.1 mrg default: 1528 1.1 mrg break; 1529 1.1 mrg } 1530 1.1 mrg 1531 1.1 mrg return r; 1532 1.1 mrg } 1533 1.1 mrg #else 1534 1.1 mrg static int 1535 1.1 mrg open_share (st_parameter_open *opp __attribute__ ((unused)), 1536 1.1 mrg int fd __attribute__ ((unused)), 1537 1.1 mrg unit_flags *flags __attribute__ ((unused))) 1538 1.1 mrg { 1539 1.1 mrg return 0; 1540 1.1 mrg } 1541 1.1 mrg #endif /* defined(HAVE_FCNTL) ... */ 1542 1.1 mrg 1543 1.1 mrg 1544 1.1 mrg /* Wrapper around regular_file2, to make sure we free the path after 1545 1.1 mrg we're done. */ 1546 1.1 mrg 1547 1.1 mrg static int 1548 1.1 mrg regular_file (st_parameter_open *opp, unit_flags *flags) 1549 1.1 mrg { 1550 1.1 mrg char *path = fc_strdup (opp->file, opp->file_len); 1551 1.1 mrg int fd = regular_file2 (path, opp, flags); 1552 1.1 mrg free (path); 1553 1.1 mrg return fd; 1554 1.1 mrg } 1555 1.1 mrg 1556 1.1 mrg /* open_external()-- Open an external file, unix specific version. 1557 1.1 mrg Change flags->action if it is ACTION_UNSPECIFIED on entry. 1558 1.1 mrg Returns NULL on operating system error. */ 1559 1.1 mrg 1560 1.1 mrg stream * 1561 1.1 mrg open_external (st_parameter_open *opp, unit_flags *flags) 1562 1.1 mrg { 1563 1.1 mrg int fd; 1564 1.1 mrg 1565 1.1 mrg if (flags->status == STATUS_SCRATCH) 1566 1.1 mrg { 1567 1.1 mrg fd = tempfile (opp); 1568 1.1 mrg if (flags->action == ACTION_UNSPECIFIED) 1569 1.1 mrg flags->action = flags->readonly ? ACTION_READ : ACTION_READWRITE; 1570 1.1 mrg 1571 1.1 mrg #if HAVE_UNLINK_OPEN_FILE 1572 1.1 mrg /* We can unlink scratch files now and it will go away when closed. */ 1573 1.1 mrg if (fd >= 0) 1574 1.1 mrg unlink (opp->file); 1575 1.1 mrg #endif 1576 1.1 mrg } 1577 1.1 mrg else 1578 1.1 mrg { 1579 1.1 mrg /* regular_file resets flags->action if it is ACTION_UNSPECIFIED and 1580 1.1 mrg if it succeeds */ 1581 1.1 mrg fd = regular_file (opp, flags); 1582 1.1 mrg #ifndef O_CLOEXEC 1583 1.1 mrg set_close_on_exec (fd); 1584 1.1 mrg #endif 1585 1.1 mrg } 1586 1.1 mrg 1587 1.1 mrg if (fd < 0) 1588 1.1 mrg return NULL; 1589 1.1 mrg fd = fix_fd (fd); 1590 1.1 mrg 1591 1.1 mrg if (open_share (opp, fd, flags) < 0) 1592 1.1 mrg return NULL; 1593 1.1 mrg 1594 1.1 mrg return fd_to_stream (fd, flags->form == FORM_UNFORMATTED); 1595 1.1 mrg } 1596 1.1 mrg 1597 1.1 mrg 1598 1.1 mrg /* input_stream()-- Return a stream pointer to the default input stream. 1599 1.1 mrg Called on initialization. */ 1600 1.1 mrg 1601 1.1 mrg stream * 1602 1.1 mrg input_stream (void) 1603 1.1 mrg { 1604 1.1 mrg return fd_to_stream (STDIN_FILENO, false); 1605 1.1 mrg } 1606 1.1 mrg 1607 1.1 mrg 1608 1.1 mrg /* output_stream()-- Return a stream pointer to the default output stream. 1609 1.1 mrg Called on initialization. */ 1610 1.1 mrg 1611 1.1 mrg stream * 1612 1.1 mrg output_stream (void) 1613 1.1 mrg { 1614 1.1 mrg stream *s; 1615 1.1 mrg 1616 1.1 mrg #if defined(HAVE_CRLF) && defined(HAVE_SETMODE) 1617 1.1 mrg setmode (STDOUT_FILENO, O_BINARY); 1618 1.1 mrg #endif 1619 1.1 mrg 1620 1.1 mrg s = fd_to_stream (STDOUT_FILENO, false); 1621 1.1 mrg return s; 1622 1.1 mrg } 1623 1.1 mrg 1624 1.1 mrg 1625 1.1 mrg /* error_stream()-- Return a stream pointer to the default error stream. 1626 1.1 mrg Called on initialization. */ 1627 1.1 mrg 1628 1.1 mrg stream * 1629 1.1 mrg error_stream (void) 1630 1.1 mrg { 1631 1.1 mrg stream *s; 1632 1.1 mrg 1633 1.1 mrg #if defined(HAVE_CRLF) && defined(HAVE_SETMODE) 1634 1.1 mrg setmode (STDERR_FILENO, O_BINARY); 1635 1.1 mrg #endif 1636 1.1 mrg 1637 1.1 mrg s = fd_to_stream (STDERR_FILENO, false); 1638 1.1 mrg return s; 1639 1.1 mrg } 1640 1.1 mrg 1641 1.1 mrg 1642 1.1 mrg /* compare_file_filename()-- Given an open stream and a fortran string 1643 1.1 mrg that is a filename, figure out if the file is the same as the 1644 1.1 mrg filename. */ 1645 1.1 mrg 1646 1.1 mrg int 1647 1.1 mrg compare_file_filename (gfc_unit *u, const char *name, gfc_charlen_type len) 1648 1.1 mrg { 1649 1.1 mrg struct stat st; 1650 1.1 mrg int ret; 1651 1.1 mrg #ifdef HAVE_WORKING_STAT 1652 1.1 mrg unix_stream *s; 1653 1.1 mrg #else 1654 1.1 mrg # ifdef __MINGW32__ 1655 1.1 mrg uint64_t id1, id2; 1656 1.1 mrg # endif 1657 1.1 mrg #endif 1658 1.1 mrg 1659 1.1 mrg char *path = fc_strdup (name, len); 1660 1.1 mrg 1661 1.1 mrg /* If the filename doesn't exist, then there is no match with the 1662 1.1 mrg existing file. */ 1663 1.1 mrg 1664 1.1 mrg if (TEMP_FAILURE_RETRY (stat (path, &st)) < 0) 1665 1.1 mrg { 1666 1.1 mrg ret = 0; 1667 1.1 mrg goto done; 1668 1.1 mrg } 1669 1.1 mrg 1670 1.1 mrg #ifdef HAVE_WORKING_STAT 1671 1.1 mrg s = (unix_stream *) (u->s); 1672 1.1 mrg ret = (st.st_dev == s->st_dev) && (st.st_ino == s->st_ino); 1673 1.1 mrg goto done; 1674 1.1 mrg #else 1675 1.1 mrg 1676 1.1 mrg # ifdef __MINGW32__ 1677 1.1 mrg /* We try to match files by a unique ID. On some filesystems (network 1678 1.1 mrg fs and FAT), we can't generate this unique ID, and will simply compare 1679 1.1 mrg filenames. */ 1680 1.1 mrg id1 = id_from_path (path); 1681 1.1 mrg id2 = id_from_fd (((unix_stream *) (u->s))->fd); 1682 1.1 mrg if (id1 || id2) 1683 1.1 mrg { 1684 1.1 mrg ret = (id1 == id2); 1685 1.1 mrg goto done; 1686 1.1 mrg } 1687 1.1 mrg # endif 1688 1.1 mrg if (u->filename) 1689 1.1 mrg ret = (strcmp(path, u->filename) == 0); 1690 1.1 mrg else 1691 1.1 mrg ret = 0; 1692 1.1 mrg #endif 1693 1.1 mrg done: 1694 1.1 mrg free (path); 1695 1.1 mrg return ret; 1696 1.1 mrg } 1697 1.1 mrg 1698 1.1 mrg 1699 1.1 mrg #ifdef HAVE_WORKING_STAT 1700 1.1 mrg # define FIND_FILE0_DECL struct stat *st 1701 1.1 mrg # define FIND_FILE0_ARGS st 1702 1.1 mrg #else 1703 1.1 mrg # define FIND_FILE0_DECL uint64_t id, const char *path 1704 1.1 mrg # define FIND_FILE0_ARGS id, path 1705 1.1 mrg #endif 1706 1.1 mrg 1707 1.1 mrg /* find_file0()-- Recursive work function for find_file() */ 1708 1.1 mrg 1709 1.1 mrg static gfc_unit * 1710 1.1 mrg find_file0 (gfc_unit *u, FIND_FILE0_DECL) 1711 1.1 mrg { 1712 1.1 mrg gfc_unit *v; 1713 1.1 mrg #if defined(__MINGW32__) && !HAVE_WORKING_STAT 1714 1.1 mrg uint64_t id1; 1715 1.1 mrg #endif 1716 1.1 mrg 1717 1.1 mrg if (u == NULL) 1718 1.1 mrg return NULL; 1719 1.1 mrg 1720 1.1 mrg #ifdef HAVE_WORKING_STAT 1721 1.1 mrg if (u->s != NULL) 1722 1.1 mrg { 1723 1.1 mrg unix_stream *s = (unix_stream *) (u->s); 1724 1.1 mrg if (st[0].st_dev == s->st_dev && st[0].st_ino == s->st_ino) 1725 1.1 mrg return u; 1726 1.1 mrg } 1727 1.1 mrg #else 1728 1.1 mrg # ifdef __MINGW32__ 1729 1.1 mrg if (u->s && ((id1 = id_from_fd (((unix_stream *) u->s)->fd)) || id1)) 1730 1.1 mrg { 1731 1.1 mrg if (id == id1) 1732 1.1 mrg return u; 1733 1.1 mrg } 1734 1.1 mrg else 1735 1.1 mrg # endif 1736 1.1 mrg if (u->filename && strcmp (u->filename, path) == 0) 1737 1.1 mrg return u; 1738 1.1 mrg #endif 1739 1.1 mrg 1740 1.1 mrg v = find_file0 (u->left, FIND_FILE0_ARGS); 1741 1.1 mrg if (v != NULL) 1742 1.1 mrg return v; 1743 1.1 mrg 1744 1.1 mrg v = find_file0 (u->right, FIND_FILE0_ARGS); 1745 1.1 mrg if (v != NULL) 1746 1.1 mrg return v; 1747 1.1 mrg 1748 1.1 mrg return NULL; 1749 1.1 mrg } 1750 1.1 mrg 1751 1.1 mrg 1752 1.1 mrg /* find_file()-- Take the current filename and see if there is a unit 1753 1.1 mrg that has the file already open. Returns a pointer to the unit if so. */ 1754 1.1 mrg 1755 1.1 mrg gfc_unit * 1756 1.1 mrg find_file (const char *file, gfc_charlen_type file_len) 1757 1.1 mrg { 1758 1.1 mrg struct stat st[1]; 1759 1.1 mrg gfc_unit *u; 1760 1.1 mrg #if defined(__MINGW32__) && !HAVE_WORKING_STAT 1761 1.1 mrg uint64_t id = 0ULL; 1762 1.1 mrg #endif 1763 1.1 mrg 1764 1.1 mrg char *path = fc_strdup (file, file_len); 1765 1.1 mrg 1766 1.1 mrg if (TEMP_FAILURE_RETRY (stat (path, &st[0])) < 0) 1767 1.1 mrg { 1768 1.1 mrg u = NULL; 1769 1.1 mrg goto done; 1770 1.1 mrg } 1771 1.1 mrg 1772 1.1 mrg #if defined(__MINGW32__) && !HAVE_WORKING_STAT 1773 1.1 mrg id = id_from_path (path); 1774 1.1 mrg #endif 1775 1.1 mrg 1776 1.1.1.4 mrg RDLOCK (&unit_rwlock); 1777 1.1 mrg retry: 1778 1.1 mrg u = find_file0 (unit_root, FIND_FILE0_ARGS); 1779 1.1 mrg if (u != NULL) 1780 1.1 mrg { 1781 1.1 mrg /* Fast path. */ 1782 1.1 mrg if (! __gthread_mutex_trylock (&u->lock)) 1783 1.1 mrg { 1784 1.1 mrg /* assert (u->closed == 0); */ 1785 1.1.1.4 mrg RWUNLOCK (&unit_rwlock); 1786 1.1 mrg goto done; 1787 1.1 mrg } 1788 1.1 mrg 1789 1.1 mrg inc_waiting_locked (u); 1790 1.1 mrg } 1791 1.1.1.4 mrg RWUNLOCK (&unit_rwlock); 1792 1.1 mrg if (u != NULL) 1793 1.1 mrg { 1794 1.1 mrg LOCK (&u->lock); 1795 1.1 mrg if (u->closed) 1796 1.1 mrg { 1797 1.1.1.4 mrg RDLOCK (&unit_rwlock); 1798 1.1 mrg UNLOCK (&u->lock); 1799 1.1 mrg if (predec_waiting_locked (u) == 0) 1800 1.1 mrg free (u); 1801 1.1 mrg goto retry; 1802 1.1 mrg } 1803 1.1 mrg 1804 1.1 mrg dec_waiting_unlocked (u); 1805 1.1 mrg } 1806 1.1 mrg done: 1807 1.1 mrg free (path); 1808 1.1 mrg return u; 1809 1.1 mrg } 1810 1.1 mrg 1811 1.1 mrg static gfc_unit * 1812 1.1 mrg flush_all_units_1 (gfc_unit *u, int min_unit) 1813 1.1 mrg { 1814 1.1 mrg while (u != NULL) 1815 1.1 mrg { 1816 1.1 mrg if (u->unit_number > min_unit) 1817 1.1 mrg { 1818 1.1 mrg gfc_unit *r = flush_all_units_1 (u->left, min_unit); 1819 1.1 mrg if (r != NULL) 1820 1.1 mrg return r; 1821 1.1 mrg } 1822 1.1 mrg if (u->unit_number >= min_unit) 1823 1.1 mrg { 1824 1.1 mrg if (__gthread_mutex_trylock (&u->lock)) 1825 1.1 mrg return u; 1826 1.1 mrg if (u->s) 1827 1.1 mrg sflush (u->s); 1828 1.1 mrg UNLOCK (&u->lock); 1829 1.1 mrg } 1830 1.1 mrg u = u->right; 1831 1.1 mrg } 1832 1.1 mrg return NULL; 1833 1.1 mrg } 1834 1.1 mrg 1835 1.1 mrg void 1836 1.1 mrg flush_all_units (void) 1837 1.1 mrg { 1838 1.1 mrg gfc_unit *u; 1839 1.1 mrg int min_unit = 0; 1840 1.1 mrg 1841 1.1.1.4 mrg WRLOCK (&unit_rwlock); 1842 1.1 mrg do 1843 1.1 mrg { 1844 1.1 mrg u = flush_all_units_1 (unit_root, min_unit); 1845 1.1 mrg if (u != NULL) 1846 1.1 mrg inc_waiting_locked (u); 1847 1.1.1.4 mrg RWUNLOCK (&unit_rwlock); 1848 1.1 mrg if (u == NULL) 1849 1.1 mrg return; 1850 1.1 mrg 1851 1.1 mrg LOCK (&u->lock); 1852 1.1 mrg 1853 1.1 mrg min_unit = u->unit_number + 1; 1854 1.1 mrg 1855 1.1 mrg if (u->closed == 0) 1856 1.1 mrg { 1857 1.1 mrg sflush (u->s); 1858 1.1.1.4 mrg WRLOCK (&unit_rwlock); 1859 1.1 mrg UNLOCK (&u->lock); 1860 1.1 mrg (void) predec_waiting_locked (u); 1861 1.1 mrg } 1862 1.1 mrg else 1863 1.1 mrg { 1864 1.1.1.4 mrg WRLOCK (&unit_rwlock); 1865 1.1 mrg UNLOCK (&u->lock); 1866 1.1 mrg if (predec_waiting_locked (u) == 0) 1867 1.1 mrg free (u); 1868 1.1 mrg } 1869 1.1 mrg } 1870 1.1 mrg while (1); 1871 1.1 mrg } 1872 1.1 mrg 1873 1.1 mrg 1874 1.1 mrg /* Unlock the unit if necessary, based on SHARE flags. */ 1875 1.1 mrg 1876 1.1 mrg int 1877 1.1 mrg close_share (gfc_unit *u __attribute__ ((unused))) 1878 1.1 mrg { 1879 1.1 mrg int r = 0; 1880 1.1 mrg #if defined(HAVE_FCNTL) && defined(F_SETLK) && defined(F_UNLCK) 1881 1.1 mrg unix_stream *s = (unix_stream *) u->s; 1882 1.1 mrg int fd = s->fd; 1883 1.1 mrg struct flock f; 1884 1.1 mrg 1885 1.1 mrg switch (u->flags.share) 1886 1.1 mrg { 1887 1.1 mrg case SHARE_DENYRW: 1888 1.1 mrg case SHARE_DENYNONE: 1889 1.1 mrg if (fd != STDOUT_FILENO && fd != STDERR_FILENO && fd != STDIN_FILENO) 1890 1.1 mrg { 1891 1.1 mrg f.l_start = 0; 1892 1.1 mrg f.l_len = 0; 1893 1.1 mrg f.l_whence = SEEK_SET; 1894 1.1 mrg f.l_type = F_UNLCK; 1895 1.1 mrg r = fcntl (fd, F_SETLK, &f); 1896 1.1 mrg } 1897 1.1 mrg break; 1898 1.1 mrg case SHARE_UNSPECIFIED: 1899 1.1 mrg default: 1900 1.1 mrg break; 1901 1.1 mrg } 1902 1.1 mrg 1903 1.1 mrg #endif 1904 1.1 mrg return r; 1905 1.1 mrg } 1906 1.1 mrg 1907 1.1 mrg 1908 1.1 mrg /* file_exists()-- Returns nonzero if the current filename exists on 1909 1.1 mrg the system */ 1910 1.1 mrg 1911 1.1 mrg int 1912 1.1 mrg file_exists (const char *file, gfc_charlen_type file_len) 1913 1.1 mrg { 1914 1.1 mrg char *path = fc_strdup (file, file_len); 1915 1.1 mrg int res = !(access (path, F_OK)); 1916 1.1 mrg free (path); 1917 1.1 mrg return res; 1918 1.1 mrg } 1919 1.1 mrg 1920 1.1 mrg 1921 1.1 mrg /* file_size()-- Returns the size of the file. */ 1922 1.1 mrg 1923 1.1 mrg GFC_IO_INT 1924 1.1 mrg file_size (const char *file, gfc_charlen_type file_len) 1925 1.1 mrg { 1926 1.1 mrg char *path = fc_strdup (file, file_len); 1927 1.1 mrg struct stat statbuf; 1928 1.1 mrg int err; 1929 1.1 mrg TEMP_FAILURE_RETRY (err = stat (path, &statbuf)); 1930 1.1 mrg free (path); 1931 1.1 mrg if (err == -1) 1932 1.1 mrg return -1; 1933 1.1 mrg return (GFC_IO_INT) statbuf.st_size; 1934 1.1 mrg } 1935 1.1 mrg 1936 1.1 mrg static const char yes[] = "YES", no[] = "NO", unknown[] = "UNKNOWN"; 1937 1.1 mrg 1938 1.1 mrg /* inquire_sequential()-- Given a fortran string, determine if the 1939 1.1 mrg file is suitable for sequential access. Returns a C-style 1940 1.1 mrg string. */ 1941 1.1 mrg 1942 1.1 mrg const char * 1943 1.1 mrg inquire_sequential (const char *string, gfc_charlen_type len) 1944 1.1 mrg { 1945 1.1 mrg struct stat statbuf; 1946 1.1 mrg 1947 1.1 mrg if (string == NULL) 1948 1.1 mrg return unknown; 1949 1.1 mrg 1950 1.1 mrg char *path = fc_strdup (string, len); 1951 1.1 mrg int err; 1952 1.1 mrg TEMP_FAILURE_RETRY (err = stat (path, &statbuf)); 1953 1.1 mrg free (path); 1954 1.1 mrg if (err == -1) 1955 1.1 mrg return unknown; 1956 1.1 mrg 1957 1.1 mrg if (S_ISREG (statbuf.st_mode) || 1958 1.1 mrg S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode)) 1959 1.1 mrg return unknown; 1960 1.1 mrg 1961 1.1 mrg if (S_ISDIR (statbuf.st_mode) || S_ISBLK (statbuf.st_mode)) 1962 1.1 mrg return no; 1963 1.1 mrg 1964 1.1 mrg return unknown; 1965 1.1 mrg } 1966 1.1 mrg 1967 1.1 mrg 1968 1.1 mrg /* inquire_direct()-- Given a fortran string, determine if the file is 1969 1.1 mrg suitable for direct access. Returns a C-style string. */ 1970 1.1 mrg 1971 1.1 mrg const char * 1972 1.1 mrg inquire_direct (const char *string, gfc_charlen_type len) 1973 1.1 mrg { 1974 1.1 mrg struct stat statbuf; 1975 1.1 mrg 1976 1.1 mrg if (string == NULL) 1977 1.1 mrg return unknown; 1978 1.1 mrg 1979 1.1 mrg char *path = fc_strdup (string, len); 1980 1.1 mrg int err; 1981 1.1 mrg TEMP_FAILURE_RETRY (err = stat (path, &statbuf)); 1982 1.1 mrg free (path); 1983 1.1 mrg if (err == -1) 1984 1.1 mrg return unknown; 1985 1.1 mrg 1986 1.1 mrg if (S_ISREG (statbuf.st_mode) || S_ISBLK (statbuf.st_mode)) 1987 1.1 mrg return unknown; 1988 1.1 mrg 1989 1.1 mrg if (S_ISDIR (statbuf.st_mode) || 1990 1.1 mrg S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode)) 1991 1.1 mrg return no; 1992 1.1 mrg 1993 1.1 mrg return unknown; 1994 1.1 mrg } 1995 1.1 mrg 1996 1.1 mrg 1997 1.1 mrg /* inquire_formatted()-- Given a fortran string, determine if the file 1998 1.1 mrg is suitable for formatted form. Returns a C-style string. */ 1999 1.1 mrg 2000 1.1 mrg const char * 2001 1.1 mrg inquire_formatted (const char *string, gfc_charlen_type len) 2002 1.1 mrg { 2003 1.1 mrg struct stat statbuf; 2004 1.1 mrg 2005 1.1 mrg if (string == NULL) 2006 1.1 mrg return unknown; 2007 1.1 mrg 2008 1.1 mrg char *path = fc_strdup (string, len); 2009 1.1 mrg int err; 2010 1.1 mrg TEMP_FAILURE_RETRY (err = stat (path, &statbuf)); 2011 1.1 mrg free (path); 2012 1.1 mrg if (err == -1) 2013 1.1 mrg return unknown; 2014 1.1 mrg 2015 1.1 mrg if (S_ISREG (statbuf.st_mode) || 2016 1.1 mrg S_ISBLK (statbuf.st_mode) || 2017 1.1 mrg S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode)) 2018 1.1 mrg return unknown; 2019 1.1 mrg 2020 1.1 mrg if (S_ISDIR (statbuf.st_mode)) 2021 1.1 mrg return no; 2022 1.1 mrg 2023 1.1 mrg return unknown; 2024 1.1 mrg } 2025 1.1 mrg 2026 1.1 mrg 2027 1.1 mrg /* inquire_unformatted()-- Given a fortran string, determine if the file 2028 1.1 mrg is suitable for unformatted form. Returns a C-style string. */ 2029 1.1 mrg 2030 1.1 mrg const char * 2031 1.1 mrg inquire_unformatted (const char *string, gfc_charlen_type len) 2032 1.1 mrg { 2033 1.1 mrg return inquire_formatted (string, len); 2034 1.1 mrg } 2035 1.1 mrg 2036 1.1 mrg 2037 1.1 mrg /* inquire_access()-- Given a fortran string, determine if the file is 2038 1.1 mrg suitable for access. */ 2039 1.1 mrg 2040 1.1 mrg static const char * 2041 1.1 mrg inquire_access (const char *string, gfc_charlen_type len, int mode) 2042 1.1 mrg { 2043 1.1 mrg if (string == NULL) 2044 1.1 mrg return no; 2045 1.1 mrg char *path = fc_strdup (string, len); 2046 1.1 mrg int res = access (path, mode); 2047 1.1 mrg free (path); 2048 1.1 mrg if (res == -1) 2049 1.1 mrg return no; 2050 1.1 mrg 2051 1.1 mrg return yes; 2052 1.1 mrg } 2053 1.1 mrg 2054 1.1 mrg 2055 1.1 mrg /* inquire_read()-- Given a fortran string, determine if the file is 2056 1.1 mrg suitable for READ access. */ 2057 1.1 mrg 2058 1.1 mrg const char * 2059 1.1 mrg inquire_read (const char *string, gfc_charlen_type len) 2060 1.1 mrg { 2061 1.1 mrg return inquire_access (string, len, R_OK); 2062 1.1 mrg } 2063 1.1 mrg 2064 1.1 mrg 2065 1.1 mrg /* inquire_write()-- Given a fortran string, determine if the file is 2066 1.1 mrg suitable for READ access. */ 2067 1.1 mrg 2068 1.1 mrg const char * 2069 1.1 mrg inquire_write (const char *string, gfc_charlen_type len) 2070 1.1 mrg { 2071 1.1 mrg return inquire_access (string, len, W_OK); 2072 1.1 mrg } 2073 1.1 mrg 2074 1.1 mrg 2075 1.1 mrg /* inquire_readwrite()-- Given a fortran string, determine if the file is 2076 1.1 mrg suitable for read and write access. */ 2077 1.1 mrg 2078 1.1 mrg const char * 2079 1.1 mrg inquire_readwrite (const char *string, gfc_charlen_type len) 2080 1.1 mrg { 2081 1.1 mrg return inquire_access (string, len, R_OK | W_OK); 2082 1.1 mrg } 2083 1.1 mrg 2084 1.1 mrg 2085 1.1 mrg int 2086 1.1 mrg stream_isatty (stream *s) 2087 1.1 mrg { 2088 1.1 mrg return isatty (((unix_stream *) s)->fd); 2089 1.1 mrg } 2090 1.1 mrg 2091 1.1 mrg int 2092 1.1 mrg stream_ttyname (stream *s __attribute__ ((unused)), 2093 1.1 mrg char *buf __attribute__ ((unused)), 2094 1.1 mrg size_t buflen __attribute__ ((unused))) 2095 1.1 mrg { 2096 1.1 mrg #ifdef HAVE_TTYNAME_R 2097 1.1 mrg return ttyname_r (((unix_stream *)s)->fd, buf, buflen); 2098 1.1 mrg #elif defined HAVE_TTYNAME 2099 1.1 mrg char *p; 2100 1.1 mrg size_t plen; 2101 1.1 mrg p = ttyname (((unix_stream *)s)->fd); 2102 1.1 mrg if (!p) 2103 1.1 mrg return errno; 2104 1.1 mrg plen = strlen (p); 2105 1.1 mrg if (buflen < plen) 2106 1.1 mrg plen = buflen; 2107 1.1 mrg memcpy (buf, p, plen); 2108 1.1 mrg return 0; 2109 1.1 mrg #else 2110 1.1 mrg return ENOSYS; 2111 1.1 mrg #endif 2112 1.1 mrg } 2113 1.1 mrg 2114 1.1 mrg 2115 1.1 mrg 2116 1.1 mrg 2117 1.1 mrg /* How files are stored: This is an operating-system specific issue, 2118 1.1 mrg and therefore belongs here. There are three cases to consider. 2119 1.1 mrg 2120 1.1 mrg Direct Access: 2121 1.1 mrg Records are written as block of bytes corresponding to the record 2122 1.1 mrg length of the file. This goes for both formatted and unformatted 2123 1.1 mrg records. Positioning is done explicitly for each data transfer, 2124 1.1 mrg so positioning is not much of an issue. 2125 1.1 mrg 2126 1.1 mrg Sequential Formatted: 2127 1.1 mrg Records are separated by newline characters. The newline character 2128 1.1 mrg is prohibited from appearing in a string. If it does, this will be 2129 1.1 mrg messed up on the next read. End of file is also the end of a record. 2130 1.1 mrg 2131 1.1 mrg Sequential Unformatted: 2132 1.1 mrg In this case, we are merely copying bytes to and from main storage, 2133 1.1 mrg yet we need to keep track of varying record lengths. We adopt 2134 1.1 mrg the solution used by f2c. Each record contains a pair of length 2135 1.1 mrg markers: 2136 1.1 mrg 2137 1.1 mrg Length of record n in bytes 2138 1.1 mrg Data of record n 2139 1.1 mrg Length of record n in bytes 2140 1.1 mrg 2141 1.1 mrg Length of record n+1 in bytes 2142 1.1 mrg Data of record n+1 2143 1.1 mrg Length of record n+1 in bytes 2144 1.1 mrg 2145 1.1 mrg The length is stored at the end of a record to allow backspacing to the 2146 1.1 mrg previous record. Between data transfer statements, the file pointer 2147 1.1 mrg is left pointing to the first length of the current record. 2148 1.1 mrg 2149 1.1 mrg ENDFILE records are never explicitly stored. 2150 1.1 mrg 2151 1.1 mrg */ 2152