1 /* Author: Daniel Stutzbach */ 2 3 #define PY_SSIZE_T_CLEAN 4 #include "Python.h" 5 #include "structmember.h" 6 #ifdef HAVE_SYS_TYPES_H 7 #include <sys/types.h> 8 #endif 9 #ifdef HAVE_SYS_STAT_H 10 #include <sys/stat.h> 11 #endif 12 #ifdef HAVE_IO_H 13 #include <io.h> 14 #endif 15 #ifdef HAVE_FCNTL_H 16 #include <fcntl.h> 17 #endif 18 #include <stddef.h> /* For offsetof */ 19 #include "_iomodule.h" 20 21 /* 22 * Known likely problems: 23 * 24 * - Files larger then 2**32-1 25 * - Files with unicode filenames 26 * - Passing numbers greater than 2**32-1 when an integer is expected 27 * - Making it work on Windows and other oddball platforms 28 * 29 * To Do: 30 * 31 * - autoconfify header file inclusion 32 */ 33 34 #ifdef MS_WINDOWS 35 /* can simulate truncate with Win32 API functions; see file_truncate */ 36 #define HAVE_FTRUNCATE 37 #define WIN32_LEAN_AND_MEAN 38 #include <windows.h> 39 #endif 40 41 #if BUFSIZ < (8*1024) 42 #define SMALLCHUNK (8*1024) 43 #elif (BUFSIZ >= (2 << 25)) 44 #error "unreasonable BUFSIZ > 64MB defined" 45 #else 46 #define SMALLCHUNK BUFSIZ 47 #endif 48 49 /*[clinic input] 50 module _io 51 class _io.FileIO "fileio *" "&PyFileIO_Type" 52 [clinic start generated code]*/ 53 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=1c77708b41fda70c]*/ 54 55 /*[python input] 56 class io_ssize_t_converter(CConverter): 57 type = 'Py_ssize_t' 58 converter = '_PyIO_ConvertSsize_t' 59 [python start generated code]*/ 60 /*[python end generated code: output=da39a3ee5e6b4b0d input=d0a811d3cbfd1b33]*/ 61 62 typedef struct { 63 PyObject_HEAD 64 int fd; 65 unsigned int created : 1; 66 unsigned int readable : 1; 67 unsigned int writable : 1; 68 unsigned int appending : 1; 69 signed int seekable : 2; /* -1 means unknown */ 70 unsigned int closefd : 1; 71 char finalizing; 72 unsigned int blksize; 73 PyObject *weakreflist; 74 PyObject *dict; 75 } fileio; 76 77 PyTypeObject PyFileIO_Type; 78 79 _Py_IDENTIFIER(name); 80 81 #define PyFileIO_Check(op) (PyObject_TypeCheck((op), &PyFileIO_Type)) 82 83 int 84 _PyFileIO_closed(PyObject *self) 85 { 86 return ((fileio *)self)->fd < 0; 87 } 88 89 /* Because this can call arbitrary code, it shouldn't be called when 90 the refcount is 0 (that is, not directly from tp_dealloc unless 91 the refcount has been temporarily re-incremented). */ 92 static PyObject * 93 fileio_dealloc_warn(fileio *self, PyObject *source) 94 { 95 if (self->fd >= 0 && self->closefd) { 96 PyObject *exc, *val, *tb; 97 PyErr_Fetch(&exc, &val, &tb); 98 if (PyErr_ResourceWarning(source, 1, "unclosed file %R", source)) { 99 /* Spurious errors can appear at shutdown */ 100 if (PyErr_ExceptionMatches(PyExc_Warning)) 101 PyErr_WriteUnraisable((PyObject *) self); 102 } 103 PyErr_Restore(exc, val, tb); 104 } 105 Py_RETURN_NONE; 106 } 107 108 static PyObject * 109 portable_lseek(int fd, PyObject *posobj, int whence); 110 111 static PyObject *portable_lseek(int fd, PyObject *posobj, int whence); 112 113 /* Returns 0 on success, -1 with exception set on failure. */ 114 static int 115 internal_close(fileio *self) 116 { 117 int err = 0; 118 int save_errno = 0; 119 if (self->fd >= 0) { 120 int fd = self->fd; 121 self->fd = -1; 122 /* fd is accessible and someone else may have closed it */ 123 Py_BEGIN_ALLOW_THREADS 124 _Py_BEGIN_SUPPRESS_IPH 125 err = close(fd); 126 if (err < 0) 127 save_errno = errno; 128 _Py_END_SUPPRESS_IPH 129 Py_END_ALLOW_THREADS 130 } 131 if (err < 0) { 132 errno = save_errno; 133 PyErr_SetFromErrno(PyExc_IOError); 134 return -1; 135 } 136 return 0; 137 } 138 139 /*[clinic input] 140 _io.FileIO.close 141 142 Close the file. 143 144 A closed file cannot be used for further I/O operations. close() may be 145 called more than once without error. 146 [clinic start generated code]*/ 147 148 static PyObject * 149 _io_FileIO_close_impl(fileio *self) 150 /*[clinic end generated code: output=7737a319ef3bad0b input=f35231760d54a522]*/ 151 { 152 PyObject *res; 153 PyObject *exc, *val, *tb; 154 int rc; 155 _Py_IDENTIFIER(close); 156 res = _PyObject_CallMethodId((PyObject*)&PyRawIOBase_Type, 157 &PyId_close, "O", self); 158 if (!self->closefd) { 159 self->fd = -1; 160 return res; 161 } 162 if (res == NULL) 163 PyErr_Fetch(&exc, &val, &tb); 164 if (self->finalizing) { 165 PyObject *r = fileio_dealloc_warn(self, (PyObject *) self); 166 if (r) 167 Py_DECREF(r); 168 else 169 PyErr_Clear(); 170 } 171 rc = internal_close(self); 172 if (res == NULL) 173 _PyErr_ChainExceptions(exc, val, tb); 174 if (rc < 0) 175 Py_CLEAR(res); 176 return res; 177 } 178 179 static PyObject * 180 fileio_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 181 { 182 fileio *self; 183 184 assert(type != NULL && type->tp_alloc != NULL); 185 186 self = (fileio *) type->tp_alloc(type, 0); 187 if (self != NULL) { 188 self->fd = -1; 189 self->created = 0; 190 self->readable = 0; 191 self->writable = 0; 192 self->appending = 0; 193 self->seekable = -1; 194 self->blksize = 0; 195 self->closefd = 1; 196 self->weakreflist = NULL; 197 } 198 199 return (PyObject *) self; 200 } 201 202 #ifdef O_CLOEXEC 203 extern int _Py_open_cloexec_works; 204 #endif 205 206 /*[clinic input] 207 _io.FileIO.__init__ 208 file as nameobj: object 209 mode: str = "r" 210 closefd: int(c_default="1") = True 211 opener: object = None 212 213 Open a file. 214 215 The mode can be 'r' (default), 'w', 'x' or 'a' for reading, 216 writing, exclusive creation or appending. The file will be created if it 217 doesn't exist when opened for writing or appending; it will be truncated 218 when opened for writing. A FileExistsError will be raised if it already 219 exists when opened for creating. Opening a file for creating implies 220 writing so this mode behaves in a similar way to 'w'.Add a '+' to the mode 221 to allow simultaneous reading and writing. A custom opener can be used by 222 passing a callable as *opener*. The underlying file descriptor for the file 223 object is then obtained by calling opener with (*name*, *flags*). 224 *opener* must return an open file descriptor (passing os.open as *opener* 225 results in functionality similar to passing None). 226 [clinic start generated code]*/ 227 228 static int 229 _io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode, 230 int closefd, PyObject *opener) 231 /*[clinic end generated code: output=23413f68e6484bbd input=193164e293d6c097]*/ 232 { 233 #ifdef MS_WINDOWS 234 Py_UNICODE *widename = NULL; 235 #else 236 const char *name = NULL; 237 #endif 238 PyObject *stringobj = NULL; 239 const char *s; 240 int ret = 0; 241 int rwa = 0, plus = 0; 242 int flags = 0; 243 int fd = -1; 244 int fd_is_own = 0; 245 #ifdef O_CLOEXEC 246 int *atomic_flag_works = &_Py_open_cloexec_works; 247 #elif !defined(MS_WINDOWS) 248 int *atomic_flag_works = NULL; 249 #endif 250 struct _Py_stat_struct fdfstat; 251 int fstat_result; 252 int async_err = 0; 253 254 assert(PyFileIO_Check(self)); 255 if (self->fd >= 0) { 256 if (self->closefd) { 257 /* Have to close the existing file first. */ 258 if (internal_close(self) < 0) 259 return -1; 260 } 261 else 262 self->fd = -1; 263 } 264 265 if (PyFloat_Check(nameobj)) { 266 PyErr_SetString(PyExc_TypeError, 267 "integer argument expected, got float"); 268 return -1; 269 } 270 271 fd = _PyLong_AsInt(nameobj); 272 if (fd < 0) { 273 if (!PyErr_Occurred()) { 274 PyErr_SetString(PyExc_ValueError, 275 "negative file descriptor"); 276 return -1; 277 } 278 PyErr_Clear(); 279 } 280 281 if (fd < 0) { 282 #ifdef MS_WINDOWS 283 Py_ssize_t length; 284 if (!PyUnicode_FSDecoder(nameobj, &stringobj)) { 285 return -1; 286 } 287 widename = PyUnicode_AsUnicodeAndSize(stringobj, &length); 288 if (widename == NULL) 289 return -1; 290 #else 291 if (!PyUnicode_FSConverter(nameobj, &stringobj)) { 292 return -1; 293 } 294 name = PyBytes_AS_STRING(stringobj); 295 #endif 296 } 297 298 s = mode; 299 while (*s) { 300 switch (*s++) { 301 case 'x': 302 if (rwa) { 303 bad_mode: 304 PyErr_SetString(PyExc_ValueError, 305 "Must have exactly one of create/read/write/append " 306 "mode and at most one plus"); 307 goto error; 308 } 309 rwa = 1; 310 self->created = 1; 311 self->writable = 1; 312 flags |= O_EXCL | O_CREAT; 313 break; 314 case 'r': 315 if (rwa) 316 goto bad_mode; 317 rwa = 1; 318 self->readable = 1; 319 break; 320 case 'w': 321 if (rwa) 322 goto bad_mode; 323 rwa = 1; 324 self->writable = 1; 325 flags |= O_CREAT | O_TRUNC; 326 break; 327 case 'a': 328 if (rwa) 329 goto bad_mode; 330 rwa = 1; 331 self->writable = 1; 332 self->appending = 1; 333 flags |= O_APPEND | O_CREAT; 334 break; 335 case 'b': 336 break; 337 case '+': 338 if (plus) 339 goto bad_mode; 340 self->readable = self->writable = 1; 341 plus = 1; 342 break; 343 default: 344 PyErr_Format(PyExc_ValueError, 345 "invalid mode: %.200s", mode); 346 goto error; 347 } 348 } 349 350 if (!rwa) 351 goto bad_mode; 352 353 if (self->readable && self->writable) 354 flags |= O_RDWR; 355 else if (self->readable) 356 flags |= O_RDONLY; 357 else 358 flags |= O_WRONLY; 359 360 #ifdef O_BINARY 361 flags |= O_BINARY; 362 #endif 363 364 #ifdef MS_WINDOWS 365 flags |= O_NOINHERIT; 366 #elif defined(O_CLOEXEC) 367 flags |= O_CLOEXEC; 368 #endif 369 370 if (fd >= 0) { 371 self->fd = fd; 372 self->closefd = closefd; 373 } 374 else { 375 self->closefd = 1; 376 if (!closefd) { 377 PyErr_SetString(PyExc_ValueError, 378 "Cannot use closefd=False with file name"); 379 goto error; 380 } 381 382 errno = 0; 383 if (opener == Py_None) { 384 do { 385 Py_BEGIN_ALLOW_THREADS 386 #ifdef MS_WINDOWS 387 self->fd = _wopen(widename, flags, 0666); 388 #else 389 self->fd = open(name, flags, 0666); 390 #endif 391 Py_END_ALLOW_THREADS 392 } while (self->fd < 0 && errno == EINTR && 393 !(async_err = PyErr_CheckSignals())); 394 395 if (async_err) 396 goto error; 397 } 398 else { 399 PyObject *fdobj; 400 401 #ifndef MS_WINDOWS 402 /* the opener may clear the atomic flag */ 403 atomic_flag_works = NULL; 404 #endif 405 406 fdobj = PyObject_CallFunction(opener, "Oi", nameobj, flags); 407 if (fdobj == NULL) 408 goto error; 409 if (!PyLong_Check(fdobj)) { 410 Py_DECREF(fdobj); 411 PyErr_SetString(PyExc_TypeError, 412 "expected integer from opener"); 413 goto error; 414 } 415 416 self->fd = _PyLong_AsInt(fdobj); 417 Py_DECREF(fdobj); 418 if (self->fd < 0) { 419 if (!PyErr_Occurred()) { 420 /* The opener returned a negative but didn't set an 421 exception. See issue #27066 */ 422 PyErr_Format(PyExc_ValueError, 423 "opener returned %d", self->fd); 424 } 425 goto error; 426 } 427 } 428 429 fd_is_own = 1; 430 if (self->fd < 0) { 431 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, nameobj); 432 goto error; 433 } 434 435 #ifndef MS_WINDOWS 436 if (_Py_set_inheritable(self->fd, 0, atomic_flag_works) < 0) 437 goto error; 438 #endif 439 } 440 441 self->blksize = DEFAULT_BUFFER_SIZE; 442 Py_BEGIN_ALLOW_THREADS 443 fstat_result = _Py_fstat_noraise(self->fd, &fdfstat); 444 Py_END_ALLOW_THREADS 445 if (fstat_result < 0) { 446 /* Tolerate fstat() errors other than EBADF. See Issue #25717, where 447 an anonymous file on a Virtual Box shared folder filesystem would 448 raise ENOENT. */ 449 #ifdef MS_WINDOWS 450 if (GetLastError() == ERROR_INVALID_HANDLE) { 451 PyErr_SetFromWindowsErr(0); 452 #else 453 if (errno == EBADF) { 454 PyErr_SetFromErrno(PyExc_OSError); 455 #endif 456 goto error; 457 } 458 } 459 else { 460 #if defined(S_ISDIR) && defined(EISDIR) 461 /* On Unix, open will succeed for directories. 462 In Python, there should be no file objects referring to 463 directories, so we need a check. */ 464 if (S_ISDIR(fdfstat.st_mode)) { 465 errno = EISDIR; 466 PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, nameobj); 467 goto error; 468 } 469 #endif /* defined(S_ISDIR) */ 470 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE 471 if (fdfstat.st_blksize > 1) 472 self->blksize = fdfstat.st_blksize; 473 #endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */ 474 } 475 476 #if defined(MS_WINDOWS) || defined(__CYGWIN__) 477 /* don't translate newlines (\r\n <=> \n) */ 478 _setmode(self->fd, O_BINARY); 479 #endif 480 481 if (_PyObject_SetAttrId((PyObject *)self, &PyId_name, nameobj) < 0) 482 goto error; 483 484 if (self->appending) { 485 /* For consistent behaviour, we explicitly seek to the 486 end of file (otherwise, it might be done only on the 487 first write()). */ 488 PyObject *pos = portable_lseek(self->fd, NULL, 2); 489 if (pos == NULL) 490 goto error; 491 Py_DECREF(pos); 492 } 493 494 goto done; 495 496 error: 497 ret = -1; 498 if (!fd_is_own) 499 self->fd = -1; 500 if (self->fd >= 0) 501 internal_close(self); 502 503 done: 504 Py_CLEAR(stringobj); 505 return ret; 506 } 507 508 static int 509 fileio_traverse(fileio *self, visitproc visit, void *arg) 510 { 511 Py_VISIT(self->dict); 512 return 0; 513 } 514 515 static int 516 fileio_clear(fileio *self) 517 { 518 Py_CLEAR(self->dict); 519 return 0; 520 } 521 522 static void 523 fileio_dealloc(fileio *self) 524 { 525 self->finalizing = 1; 526 if (_PyIOBase_finalize((PyObject *) self) < 0) 527 return; 528 _PyObject_GC_UNTRACK(self); 529 if (self->weakreflist != NULL) 530 PyObject_ClearWeakRefs((PyObject *) self); 531 Py_CLEAR(self->dict); 532 Py_TYPE(self)->tp_free((PyObject *)self); 533 } 534 535 static PyObject * 536 err_closed(void) 537 { 538 PyErr_SetString(PyExc_ValueError, "I/O operation on closed file"); 539 return NULL; 540 } 541 542 static PyObject * 543 err_mode(const char *action) 544 { 545 _PyIO_State *state = IO_STATE(); 546 if (state != NULL) 547 PyErr_Format(state->unsupported_operation, 548 "File not open for %s", action); 549 return NULL; 550 } 551 552 /*[clinic input] 553 _io.FileIO.fileno 554 555 Return the underlying file descriptor (an integer). 556 [clinic start generated code]*/ 557 558 static PyObject * 559 _io_FileIO_fileno_impl(fileio *self) 560 /*[clinic end generated code: output=a9626ce5398ece90 input=0b9b2de67335ada3]*/ 561 { 562 if (self->fd < 0) 563 return err_closed(); 564 return PyLong_FromLong((long) self->fd); 565 } 566 567 /*[clinic input] 568 _io.FileIO.readable 569 570 True if file was opened in a read mode. 571 [clinic start generated code]*/ 572 573 static PyObject * 574 _io_FileIO_readable_impl(fileio *self) 575 /*[clinic end generated code: output=640744a6150fe9ba input=a3fdfed6eea721c5]*/ 576 { 577 if (self->fd < 0) 578 return err_closed(); 579 return PyBool_FromLong((long) self->readable); 580 } 581 582 /*[clinic input] 583 _io.FileIO.writable 584 585 True if file was opened in a write mode. 586 [clinic start generated code]*/ 587 588 static PyObject * 589 _io_FileIO_writable_impl(fileio *self) 590 /*[clinic end generated code: output=96cefc5446e89977 input=c204a808ca2e1748]*/ 591 { 592 if (self->fd < 0) 593 return err_closed(); 594 return PyBool_FromLong((long) self->writable); 595 } 596 597 /*[clinic input] 598 _io.FileIO.seekable 599 600 True if file supports random-access. 601 [clinic start generated code]*/ 602 603 static PyObject * 604 _io_FileIO_seekable_impl(fileio *self) 605 /*[clinic end generated code: output=47909ca0a42e9287 input=c8e5554d2fd63c7f]*/ 606 { 607 if (self->fd < 0) 608 return err_closed(); 609 if (self->seekable < 0) { 610 PyObject *pos = portable_lseek(self->fd, NULL, SEEK_CUR); 611 if (pos == NULL) { 612 PyErr_Clear(); 613 self->seekable = 0; 614 } else { 615 Py_DECREF(pos); 616 self->seekable = 1; 617 } 618 } 619 return PyBool_FromLong((long) self->seekable); 620 } 621 622 /*[clinic input] 623 _io.FileIO.readinto 624 buffer: Py_buffer(accept={rwbuffer}) 625 / 626 627 Same as RawIOBase.readinto(). 628 [clinic start generated code]*/ 629 630 static PyObject * 631 _io_FileIO_readinto_impl(fileio *self, Py_buffer *buffer) 632 /*[clinic end generated code: output=b01a5a22c8415cb4 input=4721d7b68b154eaf]*/ 633 { 634 Py_ssize_t n; 635 int err; 636 637 if (self->fd < 0) 638 return err_closed(); 639 if (!self->readable) 640 return err_mode("reading"); 641 642 n = _Py_read(self->fd, buffer->buf, buffer->len); 643 /* copy errno because PyBuffer_Release() can indirectly modify it */ 644 err = errno; 645 646 if (n == -1) { 647 if (err == EAGAIN) { 648 PyErr_Clear(); 649 Py_RETURN_NONE; 650 } 651 return NULL; 652 } 653 654 return PyLong_FromSsize_t(n); 655 } 656 657 static size_t 658 new_buffersize(fileio *self, size_t currentsize) 659 { 660 size_t addend; 661 662 /* Expand the buffer by an amount proportional to the current size, 663 giving us amortized linear-time behavior. For bigger sizes, use a 664 less-than-double growth factor to avoid excessive allocation. */ 665 assert(currentsize <= PY_SSIZE_T_MAX); 666 if (currentsize > 65536) 667 addend = currentsize >> 3; 668 else 669 addend = 256 + currentsize; 670 if (addend < SMALLCHUNK) 671 /* Avoid tiny read() calls. */ 672 addend = SMALLCHUNK; 673 return addend + currentsize; 674 } 675 676 /*[clinic input] 677 _io.FileIO.readall 678 679 Read all data from the file, returned as bytes. 680 681 In non-blocking mode, returns as much as is immediately available, 682 or None if no data is available. Return an empty bytes object at EOF. 683 [clinic start generated code]*/ 684 685 static PyObject * 686 _io_FileIO_readall_impl(fileio *self) 687 /*[clinic end generated code: output=faa0292b213b4022 input=dbdc137f55602834]*/ 688 { 689 struct _Py_stat_struct status; 690 Py_off_t pos, end; 691 PyObject *result; 692 Py_ssize_t bytes_read = 0; 693 Py_ssize_t n; 694 size_t bufsize; 695 696 if (self->fd < 0) 697 return err_closed(); 698 699 _Py_BEGIN_SUPPRESS_IPH 700 #ifdef MS_WINDOWS 701 pos = _lseeki64(self->fd, 0L, SEEK_CUR); 702 #else 703 pos = lseek(self->fd, 0L, SEEK_CUR); 704 #endif 705 _Py_END_SUPPRESS_IPH 706 707 if (_Py_fstat_noraise(self->fd, &status) == 0) 708 end = status.st_size; 709 else 710 end = (Py_off_t)-1; 711 712 if (end > 0 && end >= pos && pos >= 0 && end - pos < PY_SSIZE_T_MAX) { 713 /* This is probably a real file, so we try to allocate a 714 buffer one byte larger than the rest of the file. If the 715 calculation is right then we should get EOF without having 716 to enlarge the buffer. */ 717 bufsize = (size_t)(end - pos + 1); 718 } else { 719 bufsize = SMALLCHUNK; 720 } 721 722 result = PyBytes_FromStringAndSize(NULL, bufsize); 723 if (result == NULL) 724 return NULL; 725 726 while (1) { 727 if (bytes_read >= (Py_ssize_t)bufsize) { 728 bufsize = new_buffersize(self, bytes_read); 729 if (bufsize > PY_SSIZE_T_MAX || bufsize <= 0) { 730 PyErr_SetString(PyExc_OverflowError, 731 "unbounded read returned more bytes " 732 "than a Python bytes object can hold"); 733 Py_DECREF(result); 734 return NULL; 735 } 736 737 if (PyBytes_GET_SIZE(result) < (Py_ssize_t)bufsize) { 738 if (_PyBytes_Resize(&result, bufsize) < 0) 739 return NULL; 740 } 741 } 742 743 n = _Py_read(self->fd, 744 PyBytes_AS_STRING(result) + bytes_read, 745 bufsize - bytes_read); 746 747 if (n == 0) 748 break; 749 if (n == -1) { 750 if (errno == EAGAIN) { 751 PyErr_Clear(); 752 if (bytes_read > 0) 753 break; 754 Py_DECREF(result); 755 Py_RETURN_NONE; 756 } 757 Py_DECREF(result); 758 return NULL; 759 } 760 bytes_read += n; 761 pos += n; 762 } 763 764 if (PyBytes_GET_SIZE(result) > bytes_read) { 765 if (_PyBytes_Resize(&result, bytes_read) < 0) 766 return NULL; 767 } 768 return result; 769 } 770 771 /*[clinic input] 772 _io.FileIO.read 773 size: io_ssize_t = -1 774 / 775 776 Read at most size bytes, returned as bytes. 777 778 Only makes one system call, so less data may be returned than requested. 779 In non-blocking mode, returns None if no data is available. 780 Return an empty bytes object at EOF. 781 [clinic start generated code]*/ 782 783 static PyObject * 784 _io_FileIO_read_impl(fileio *self, Py_ssize_t size) 785 /*[clinic end generated code: output=42528d39dd0ca641 input=5c6caa5490c13a9b]*/ 786 { 787 char *ptr; 788 Py_ssize_t n; 789 PyObject *bytes; 790 791 if (self->fd < 0) 792 return err_closed(); 793 if (!self->readable) 794 return err_mode("reading"); 795 796 if (size < 0) 797 return _io_FileIO_readall_impl(self); 798 799 #ifdef MS_WINDOWS 800 /* On Windows, the count parameter of read() is an int */ 801 if (size > INT_MAX) 802 size = INT_MAX; 803 #endif 804 805 bytes = PyBytes_FromStringAndSize(NULL, size); 806 if (bytes == NULL) 807 return NULL; 808 ptr = PyBytes_AS_STRING(bytes); 809 810 n = _Py_read(self->fd, ptr, size); 811 if (n == -1) { 812 /* copy errno because Py_DECREF() can indirectly modify it */ 813 int err = errno; 814 Py_DECREF(bytes); 815 if (err == EAGAIN) { 816 PyErr_Clear(); 817 Py_RETURN_NONE; 818 } 819 return NULL; 820 } 821 822 if (n != size) { 823 if (_PyBytes_Resize(&bytes, n) < 0) { 824 Py_CLEAR(bytes); 825 return NULL; 826 } 827 } 828 829 return (PyObject *) bytes; 830 } 831 832 /*[clinic input] 833 _io.FileIO.write 834 b: Py_buffer 835 / 836 837 Write buffer b to file, return number of bytes written. 838 839 Only makes one system call, so not all of the data may be written. 840 The number of bytes actually written is returned. In non-blocking mode, 841 returns None if the write would block. 842 [clinic start generated code]*/ 843 844 static PyObject * 845 _io_FileIO_write_impl(fileio *self, Py_buffer *b) 846 /*[clinic end generated code: output=b4059db3d363a2f7 input=6e7908b36f0ce74f]*/ 847 { 848 Py_ssize_t n; 849 int err; 850 851 if (self->fd < 0) 852 return err_closed(); 853 if (!self->writable) 854 return err_mode("writing"); 855 856 n = _Py_write(self->fd, b->buf, b->len); 857 /* copy errno because PyBuffer_Release() can indirectly modify it */ 858 err = errno; 859 860 if (n < 0) { 861 if (err == EAGAIN) { 862 PyErr_Clear(); 863 Py_RETURN_NONE; 864 } 865 return NULL; 866 } 867 868 return PyLong_FromSsize_t(n); 869 } 870 871 /* XXX Windows support below is likely incomplete */ 872 873 /* Cribbed from posix_lseek() */ 874 static PyObject * 875 portable_lseek(int fd, PyObject *posobj, int whence) 876 { 877 Py_off_t pos, res; 878 879 #ifdef SEEK_SET 880 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */ 881 switch (whence) { 882 #if SEEK_SET != 0 883 case 0: whence = SEEK_SET; break; 884 #endif 885 #if SEEK_CUR != 1 886 case 1: whence = SEEK_CUR; break; 887 #endif 888 #if SEEK_END != 2 889 case 2: whence = SEEK_END; break; 890 #endif 891 } 892 #endif /* SEEK_SET */ 893 894 if (posobj == NULL) 895 pos = 0; 896 else { 897 if(PyFloat_Check(posobj)) { 898 PyErr_SetString(PyExc_TypeError, "an integer is required"); 899 return NULL; 900 } 901 #if defined(HAVE_LARGEFILE_SUPPORT) 902 pos = PyLong_AsLongLong(posobj); 903 #else 904 pos = PyLong_AsLong(posobj); 905 #endif 906 if (PyErr_Occurred()) 907 return NULL; 908 } 909 910 Py_BEGIN_ALLOW_THREADS 911 _Py_BEGIN_SUPPRESS_IPH 912 #ifdef MS_WINDOWS 913 res = _lseeki64(fd, pos, whence); 914 #else 915 res = lseek(fd, pos, whence); 916 #endif 917 _Py_END_SUPPRESS_IPH 918 Py_END_ALLOW_THREADS 919 if (res < 0) 920 return PyErr_SetFromErrno(PyExc_IOError); 921 922 #if defined(HAVE_LARGEFILE_SUPPORT) 923 return PyLong_FromLongLong(res); 924 #else 925 return PyLong_FromLong(res); 926 #endif 927 } 928 929 /*[clinic input] 930 _io.FileIO.seek 931 pos: object 932 whence: int = 0 933 / 934 935 Move to new file position and return the file position. 936 937 Argument offset is a byte count. Optional argument whence defaults to 938 SEEK_SET or 0 (offset from start of file, offset should be >= 0); other values 939 are SEEK_CUR or 1 (move relative to current position, positive or negative), 940 and SEEK_END or 2 (move relative to end of file, usually negative, although 941 many platforms allow seeking beyond the end of a file). 942 943 Note that not all file objects are seekable. 944 [clinic start generated code]*/ 945 946 static PyObject * 947 _io_FileIO_seek_impl(fileio *self, PyObject *pos, int whence) 948 /*[clinic end generated code: output=c976acdf054e6655 input=0439194b0774d454]*/ 949 { 950 if (self->fd < 0) 951 return err_closed(); 952 953 return portable_lseek(self->fd, pos, whence); 954 } 955 956 /*[clinic input] 957 _io.FileIO.tell 958 959 Current file position. 960 961 Can raise OSError for non seekable files. 962 [clinic start generated code]*/ 963 964 static PyObject * 965 _io_FileIO_tell_impl(fileio *self) 966 /*[clinic end generated code: output=ffe2147058809d0b input=807e24ead4cec2f9]*/ 967 { 968 if (self->fd < 0) 969 return err_closed(); 970 971 return portable_lseek(self->fd, NULL, 1); 972 } 973 974 #ifdef HAVE_FTRUNCATE 975 /*[clinic input] 976 _io.FileIO.truncate 977 size as posobj: object = NULL 978 / 979 980 Truncate the file to at most size bytes and return the truncated size. 981 982 Size defaults to the current file position, as returned by tell(). 983 The current file position is changed to the value of size. 984 [clinic start generated code]*/ 985 986 static PyObject * 987 _io_FileIO_truncate_impl(fileio *self, PyObject *posobj) 988 /*[clinic end generated code: output=e49ca7a916c176fa input=9026af44686b7318]*/ 989 { 990 Py_off_t pos; 991 int ret; 992 int fd; 993 994 fd = self->fd; 995 if (fd < 0) 996 return err_closed(); 997 if (!self->writable) 998 return err_mode("writing"); 999 1000 if (posobj == Py_None || posobj == NULL) { 1001 /* Get the current position. */ 1002 posobj = portable_lseek(fd, NULL, 1); 1003 if (posobj == NULL) 1004 return NULL; 1005 } 1006 else { 1007 Py_INCREF(posobj); 1008 } 1009 1010 #if defined(HAVE_LARGEFILE_SUPPORT) 1011 pos = PyLong_AsLongLong(posobj); 1012 #else 1013 pos = PyLong_AsLong(posobj); 1014 #endif 1015 if (PyErr_Occurred()){ 1016 Py_DECREF(posobj); 1017 return NULL; 1018 } 1019 1020 Py_BEGIN_ALLOW_THREADS 1021 _Py_BEGIN_SUPPRESS_IPH 1022 errno = 0; 1023 #ifdef MS_WINDOWS 1024 ret = _chsize_s(fd, pos); 1025 #else 1026 ret = ftruncate(fd, pos); 1027 #endif 1028 _Py_END_SUPPRESS_IPH 1029 Py_END_ALLOW_THREADS 1030 1031 if (ret != 0) { 1032 Py_DECREF(posobj); 1033 PyErr_SetFromErrno(PyExc_IOError); 1034 return NULL; 1035 } 1036 1037 return posobj; 1038 } 1039 #endif /* HAVE_FTRUNCATE */ 1040 1041 static const char * 1042 mode_string(fileio *self) 1043 { 1044 if (self->created) { 1045 if (self->readable) 1046 return "xb+"; 1047 else 1048 return "xb"; 1049 } 1050 if (self->appending) { 1051 if (self->readable) 1052 return "ab+"; 1053 else 1054 return "ab"; 1055 } 1056 else if (self->readable) { 1057 if (self->writable) 1058 return "rb+"; 1059 else 1060 return "rb"; 1061 } 1062 else 1063 return "wb"; 1064 } 1065 1066 static PyObject * 1067 fileio_repr(fileio *self) 1068 { 1069 PyObject *nameobj, *res; 1070 1071 if (self->fd < 0) 1072 return PyUnicode_FromFormat("<_io.FileIO [closed]>"); 1073 1074 nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name); 1075 if (nameobj == NULL) { 1076 if (PyErr_ExceptionMatches(PyExc_AttributeError)) 1077 PyErr_Clear(); 1078 else 1079 return NULL; 1080 res = PyUnicode_FromFormat( 1081 "<_io.FileIO fd=%d mode='%s' closefd=%s>", 1082 self->fd, mode_string(self), self->closefd ? "True" : "False"); 1083 } 1084 else { 1085 res = PyUnicode_FromFormat( 1086 "<_io.FileIO name=%R mode='%s' closefd=%s>", 1087 nameobj, mode_string(self), self->closefd ? "True" : "False"); 1088 Py_DECREF(nameobj); 1089 } 1090 return res; 1091 } 1092 1093 /*[clinic input] 1094 _io.FileIO.isatty 1095 1096 True if the file is connected to a TTY device. 1097 [clinic start generated code]*/ 1098 1099 static PyObject * 1100 _io_FileIO_isatty_impl(fileio *self) 1101 /*[clinic end generated code: output=932c39924e9a8070 input=cd94ca1f5e95e843]*/ 1102 { 1103 long res; 1104 1105 if (self->fd < 0) 1106 return err_closed(); 1107 Py_BEGIN_ALLOW_THREADS 1108 _Py_BEGIN_SUPPRESS_IPH 1109 res = isatty(self->fd); 1110 _Py_END_SUPPRESS_IPH 1111 Py_END_ALLOW_THREADS 1112 return PyBool_FromLong(res); 1113 } 1114 1115 static PyObject * 1116 fileio_getstate(fileio *self) 1117 { 1118 PyErr_Format(PyExc_TypeError, 1119 "cannot serialize '%s' object", Py_TYPE(self)->tp_name); 1120 return NULL; 1121 } 1122 1123 #include "clinic/fileio.c.h" 1124 1125 static PyMethodDef fileio_methods[] = { 1126 _IO_FILEIO_READ_METHODDEF 1127 _IO_FILEIO_READALL_METHODDEF 1128 _IO_FILEIO_READINTO_METHODDEF 1129 _IO_FILEIO_WRITE_METHODDEF 1130 _IO_FILEIO_SEEK_METHODDEF 1131 _IO_FILEIO_TELL_METHODDEF 1132 _IO_FILEIO_TRUNCATE_METHODDEF 1133 _IO_FILEIO_CLOSE_METHODDEF 1134 _IO_FILEIO_SEEKABLE_METHODDEF 1135 _IO_FILEIO_READABLE_METHODDEF 1136 _IO_FILEIO_WRITABLE_METHODDEF 1137 _IO_FILEIO_FILENO_METHODDEF 1138 _IO_FILEIO_ISATTY_METHODDEF 1139 {"_dealloc_warn", (PyCFunction)fileio_dealloc_warn, METH_O, NULL}, 1140 {"__getstate__", (PyCFunction)fileio_getstate, METH_NOARGS, NULL}, 1141 {NULL, NULL} /* sentinel */ 1142 }; 1143 1144 /* 'closed' and 'mode' are attributes for backwards compatibility reasons. */ 1145 1146 static PyObject * 1147 get_closed(fileio *self, void *closure) 1148 { 1149 return PyBool_FromLong((long)(self->fd < 0)); 1150 } 1151 1152 static PyObject * 1153 get_closefd(fileio *self, void *closure) 1154 { 1155 return PyBool_FromLong((long)(self->closefd)); 1156 } 1157 1158 static PyObject * 1159 get_mode(fileio *self, void *closure) 1160 { 1161 return PyUnicode_FromString(mode_string(self)); 1162 } 1163 1164 static PyGetSetDef fileio_getsetlist[] = { 1165 {"closed", (getter)get_closed, NULL, "True if the file is closed"}, 1166 {"closefd", (getter)get_closefd, NULL, 1167 "True if the file descriptor will be closed by close()."}, 1168 {"mode", (getter)get_mode, NULL, "String giving the file mode"}, 1169 {NULL}, 1170 }; 1171 1172 static PyMemberDef fileio_members[] = { 1173 {"_blksize", T_UINT, offsetof(fileio, blksize), 0}, 1174 {"_finalizing", T_BOOL, offsetof(fileio, finalizing), 0}, 1175 {NULL} 1176 }; 1177 1178 PyTypeObject PyFileIO_Type = { 1179 PyVarObject_HEAD_INIT(NULL, 0) 1180 "_io.FileIO", 1181 sizeof(fileio), 1182 0, 1183 (destructor)fileio_dealloc, /* tp_dealloc */ 1184 0, /* tp_print */ 1185 0, /* tp_getattr */ 1186 0, /* tp_setattr */ 1187 0, /* tp_reserved */ 1188 (reprfunc)fileio_repr, /* tp_repr */ 1189 0, /* tp_as_number */ 1190 0, /* tp_as_sequence */ 1191 0, /* tp_as_mapping */ 1192 0, /* tp_hash */ 1193 0, /* tp_call */ 1194 0, /* tp_str */ 1195 PyObject_GenericGetAttr, /* tp_getattro */ 1196 0, /* tp_setattro */ 1197 0, /* tp_as_buffer */ 1198 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE 1199 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */ 1200 _io_FileIO___init____doc__, /* tp_doc */ 1201 (traverseproc)fileio_traverse, /* tp_traverse */ 1202 (inquiry)fileio_clear, /* tp_clear */ 1203 0, /* tp_richcompare */ 1204 offsetof(fileio, weakreflist), /* tp_weaklistoffset */ 1205 0, /* tp_iter */ 1206 0, /* tp_iternext */ 1207 fileio_methods, /* tp_methods */ 1208 fileio_members, /* tp_members */ 1209 fileio_getsetlist, /* tp_getset */ 1210 0, /* tp_base */ 1211 0, /* tp_dict */ 1212 0, /* tp_descr_get */ 1213 0, /* tp_descr_set */ 1214 offsetof(fileio, dict), /* tp_dictoffset */ 1215 _io_FileIO___init__, /* tp_init */ 1216 PyType_GenericAlloc, /* tp_alloc */ 1217 fileio_new, /* tp_new */ 1218 PyObject_GC_Del, /* tp_free */ 1219 0, /* tp_is_gc */ 1220 0, /* tp_bases */ 1221 0, /* tp_mro */ 1222 0, /* tp_cache */ 1223 0, /* tp_subclasses */ 1224 0, /* tp_weaklist */ 1225 0, /* tp_del */ 1226 0, /* tp_version_tag */ 1227 0, /* tp_finalize */ 1228 }; 1229