17db96d56Sopenharmony_ci/* Author: Daniel Stutzbach */ 27db96d56Sopenharmony_ci 37db96d56Sopenharmony_ci#define PY_SSIZE_T_CLEAN 47db96d56Sopenharmony_ci#include "Python.h" 57db96d56Sopenharmony_ci#include "pycore_fileutils.h" // _Py_BEGIN_SUPPRESS_IPH 67db96d56Sopenharmony_ci#include "pycore_object.h" // _PyObject_GC_UNTRACK() 77db96d56Sopenharmony_ci#include "structmember.h" // PyMemberDef 87db96d56Sopenharmony_ci#include <stdbool.h> 97db96d56Sopenharmony_ci#ifdef HAVE_SYS_TYPES_H 107db96d56Sopenharmony_ci#include <sys/types.h> 117db96d56Sopenharmony_ci#endif 127db96d56Sopenharmony_ci#ifdef HAVE_SYS_STAT_H 137db96d56Sopenharmony_ci#include <sys/stat.h> 147db96d56Sopenharmony_ci#endif 157db96d56Sopenharmony_ci#ifdef HAVE_IO_H 167db96d56Sopenharmony_ci#include <io.h> 177db96d56Sopenharmony_ci#endif 187db96d56Sopenharmony_ci#ifdef HAVE_FCNTL_H 197db96d56Sopenharmony_ci#include <fcntl.h> 207db96d56Sopenharmony_ci#endif 217db96d56Sopenharmony_ci#include <stddef.h> /* For offsetof */ 227db96d56Sopenharmony_ci#include "_iomodule.h" 237db96d56Sopenharmony_ci 247db96d56Sopenharmony_ci/* 257db96d56Sopenharmony_ci * Known likely problems: 267db96d56Sopenharmony_ci * 277db96d56Sopenharmony_ci * - Files larger then 2**32-1 287db96d56Sopenharmony_ci * - Files with unicode filenames 297db96d56Sopenharmony_ci * - Passing numbers greater than 2**32-1 when an integer is expected 307db96d56Sopenharmony_ci * - Making it work on Windows and other oddball platforms 317db96d56Sopenharmony_ci * 327db96d56Sopenharmony_ci * To Do: 337db96d56Sopenharmony_ci * 347db96d56Sopenharmony_ci * - autoconfify header file inclusion 357db96d56Sopenharmony_ci */ 367db96d56Sopenharmony_ci 377db96d56Sopenharmony_ci#ifdef MS_WINDOWS 387db96d56Sopenharmony_ci/* can simulate truncate with Win32 API functions; see file_truncate */ 397db96d56Sopenharmony_ci#define HAVE_FTRUNCATE 407db96d56Sopenharmony_ci#define WIN32_LEAN_AND_MEAN 417db96d56Sopenharmony_ci#include <windows.h> 427db96d56Sopenharmony_ci#endif 437db96d56Sopenharmony_ci 447db96d56Sopenharmony_ci#if BUFSIZ < (8*1024) 457db96d56Sopenharmony_ci#define SMALLCHUNK (8*1024) 467db96d56Sopenharmony_ci#elif (BUFSIZ >= (2 << 25)) 477db96d56Sopenharmony_ci#error "unreasonable BUFSIZ > 64 MiB defined" 487db96d56Sopenharmony_ci#else 497db96d56Sopenharmony_ci#define SMALLCHUNK BUFSIZ 507db96d56Sopenharmony_ci#endif 517db96d56Sopenharmony_ci 527db96d56Sopenharmony_ci/*[clinic input] 537db96d56Sopenharmony_cimodule _io 547db96d56Sopenharmony_ciclass _io.FileIO "fileio *" "&PyFileIO_Type" 557db96d56Sopenharmony_ci[clinic start generated code]*/ 567db96d56Sopenharmony_ci/*[clinic end generated code: output=da39a3ee5e6b4b0d input=1c77708b41fda70c]*/ 577db96d56Sopenharmony_ci 587db96d56Sopenharmony_citypedef struct { 597db96d56Sopenharmony_ci PyObject_HEAD 607db96d56Sopenharmony_ci int fd; 617db96d56Sopenharmony_ci unsigned int created : 1; 627db96d56Sopenharmony_ci unsigned int readable : 1; 637db96d56Sopenharmony_ci unsigned int writable : 1; 647db96d56Sopenharmony_ci unsigned int appending : 1; 657db96d56Sopenharmony_ci signed int seekable : 2; /* -1 means unknown */ 667db96d56Sopenharmony_ci unsigned int closefd : 1; 677db96d56Sopenharmony_ci char finalizing; 687db96d56Sopenharmony_ci unsigned int blksize; 697db96d56Sopenharmony_ci PyObject *weakreflist; 707db96d56Sopenharmony_ci PyObject *dict; 717db96d56Sopenharmony_ci} fileio; 727db96d56Sopenharmony_ci 737db96d56Sopenharmony_ciPyTypeObject PyFileIO_Type; 747db96d56Sopenharmony_ci 757db96d56Sopenharmony_ci#define PyFileIO_Check(op) (PyObject_TypeCheck((op), &PyFileIO_Type)) 767db96d56Sopenharmony_ci 777db96d56Sopenharmony_ci/* Forward declarations */ 787db96d56Sopenharmony_cistatic PyObject* portable_lseek(fileio *self, PyObject *posobj, int whence, bool suppress_pipe_error); 797db96d56Sopenharmony_ci 807db96d56Sopenharmony_ciint 817db96d56Sopenharmony_ci_PyFileIO_closed(PyObject *self) 827db96d56Sopenharmony_ci{ 837db96d56Sopenharmony_ci return ((fileio *)self)->fd < 0; 847db96d56Sopenharmony_ci} 857db96d56Sopenharmony_ci 867db96d56Sopenharmony_ci/* Because this can call arbitrary code, it shouldn't be called when 877db96d56Sopenharmony_ci the refcount is 0 (that is, not directly from tp_dealloc unless 887db96d56Sopenharmony_ci the refcount has been temporarily re-incremented). */ 897db96d56Sopenharmony_cistatic PyObject * 907db96d56Sopenharmony_cifileio_dealloc_warn(fileio *self, PyObject *source) 917db96d56Sopenharmony_ci{ 927db96d56Sopenharmony_ci if (self->fd >= 0 && self->closefd) { 937db96d56Sopenharmony_ci PyObject *exc, *val, *tb; 947db96d56Sopenharmony_ci PyErr_Fetch(&exc, &val, &tb); 957db96d56Sopenharmony_ci if (PyErr_ResourceWarning(source, 1, "unclosed file %R", source)) { 967db96d56Sopenharmony_ci /* Spurious errors can appear at shutdown */ 977db96d56Sopenharmony_ci if (PyErr_ExceptionMatches(PyExc_Warning)) 987db96d56Sopenharmony_ci PyErr_WriteUnraisable((PyObject *) self); 997db96d56Sopenharmony_ci } 1007db96d56Sopenharmony_ci PyErr_Restore(exc, val, tb); 1017db96d56Sopenharmony_ci } 1027db96d56Sopenharmony_ci Py_RETURN_NONE; 1037db96d56Sopenharmony_ci} 1047db96d56Sopenharmony_ci 1057db96d56Sopenharmony_ci/* Returns 0 on success, -1 with exception set on failure. */ 1067db96d56Sopenharmony_cistatic int 1077db96d56Sopenharmony_ciinternal_close(fileio *self) 1087db96d56Sopenharmony_ci{ 1097db96d56Sopenharmony_ci int err = 0; 1107db96d56Sopenharmony_ci int save_errno = 0; 1117db96d56Sopenharmony_ci if (self->fd >= 0) { 1127db96d56Sopenharmony_ci int fd = self->fd; 1137db96d56Sopenharmony_ci self->fd = -1; 1147db96d56Sopenharmony_ci /* fd is accessible and someone else may have closed it */ 1157db96d56Sopenharmony_ci Py_BEGIN_ALLOW_THREADS 1167db96d56Sopenharmony_ci _Py_BEGIN_SUPPRESS_IPH 1177db96d56Sopenharmony_ci err = close(fd); 1187db96d56Sopenharmony_ci if (err < 0) 1197db96d56Sopenharmony_ci save_errno = errno; 1207db96d56Sopenharmony_ci _Py_END_SUPPRESS_IPH 1217db96d56Sopenharmony_ci Py_END_ALLOW_THREADS 1227db96d56Sopenharmony_ci } 1237db96d56Sopenharmony_ci if (err < 0) { 1247db96d56Sopenharmony_ci errno = save_errno; 1257db96d56Sopenharmony_ci PyErr_SetFromErrno(PyExc_OSError); 1267db96d56Sopenharmony_ci return -1; 1277db96d56Sopenharmony_ci } 1287db96d56Sopenharmony_ci return 0; 1297db96d56Sopenharmony_ci} 1307db96d56Sopenharmony_ci 1317db96d56Sopenharmony_ci/*[clinic input] 1327db96d56Sopenharmony_ci_io.FileIO.close 1337db96d56Sopenharmony_ci 1347db96d56Sopenharmony_ciClose the file. 1357db96d56Sopenharmony_ci 1367db96d56Sopenharmony_ciA closed file cannot be used for further I/O operations. close() may be 1377db96d56Sopenharmony_cicalled more than once without error. 1387db96d56Sopenharmony_ci[clinic start generated code]*/ 1397db96d56Sopenharmony_ci 1407db96d56Sopenharmony_cistatic PyObject * 1417db96d56Sopenharmony_ci_io_FileIO_close_impl(fileio *self) 1427db96d56Sopenharmony_ci/*[clinic end generated code: output=7737a319ef3bad0b input=f35231760d54a522]*/ 1437db96d56Sopenharmony_ci{ 1447db96d56Sopenharmony_ci PyObject *res; 1457db96d56Sopenharmony_ci PyObject *exc, *val, *tb; 1467db96d56Sopenharmony_ci int rc; 1477db96d56Sopenharmony_ci res = PyObject_CallMethodOneArg((PyObject*)&PyRawIOBase_Type, 1487db96d56Sopenharmony_ci &_Py_ID(close), (PyObject *)self); 1497db96d56Sopenharmony_ci if (!self->closefd) { 1507db96d56Sopenharmony_ci self->fd = -1; 1517db96d56Sopenharmony_ci return res; 1527db96d56Sopenharmony_ci } 1537db96d56Sopenharmony_ci if (res == NULL) 1547db96d56Sopenharmony_ci PyErr_Fetch(&exc, &val, &tb); 1557db96d56Sopenharmony_ci if (self->finalizing) { 1567db96d56Sopenharmony_ci PyObject *r = fileio_dealloc_warn(self, (PyObject *) self); 1577db96d56Sopenharmony_ci if (r) 1587db96d56Sopenharmony_ci Py_DECREF(r); 1597db96d56Sopenharmony_ci else 1607db96d56Sopenharmony_ci PyErr_Clear(); 1617db96d56Sopenharmony_ci } 1627db96d56Sopenharmony_ci rc = internal_close(self); 1637db96d56Sopenharmony_ci if (res == NULL) 1647db96d56Sopenharmony_ci _PyErr_ChainExceptions(exc, val, tb); 1657db96d56Sopenharmony_ci if (rc < 0) 1667db96d56Sopenharmony_ci Py_CLEAR(res); 1677db96d56Sopenharmony_ci return res; 1687db96d56Sopenharmony_ci} 1697db96d56Sopenharmony_ci 1707db96d56Sopenharmony_cistatic PyObject * 1717db96d56Sopenharmony_cifileio_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 1727db96d56Sopenharmony_ci{ 1737db96d56Sopenharmony_ci fileio *self; 1747db96d56Sopenharmony_ci 1757db96d56Sopenharmony_ci assert(type != NULL && type->tp_alloc != NULL); 1767db96d56Sopenharmony_ci 1777db96d56Sopenharmony_ci self = (fileio *) type->tp_alloc(type, 0); 1787db96d56Sopenharmony_ci if (self != NULL) { 1797db96d56Sopenharmony_ci self->fd = -1; 1807db96d56Sopenharmony_ci self->created = 0; 1817db96d56Sopenharmony_ci self->readable = 0; 1827db96d56Sopenharmony_ci self->writable = 0; 1837db96d56Sopenharmony_ci self->appending = 0; 1847db96d56Sopenharmony_ci self->seekable = -1; 1857db96d56Sopenharmony_ci self->blksize = 0; 1867db96d56Sopenharmony_ci self->closefd = 1; 1877db96d56Sopenharmony_ci self->weakreflist = NULL; 1887db96d56Sopenharmony_ci } 1897db96d56Sopenharmony_ci 1907db96d56Sopenharmony_ci return (PyObject *) self; 1917db96d56Sopenharmony_ci} 1927db96d56Sopenharmony_ci 1937db96d56Sopenharmony_ci#ifdef O_CLOEXEC 1947db96d56Sopenharmony_ciextern int _Py_open_cloexec_works; 1957db96d56Sopenharmony_ci#endif 1967db96d56Sopenharmony_ci 1977db96d56Sopenharmony_ci/*[clinic input] 1987db96d56Sopenharmony_ci_io.FileIO.__init__ 1997db96d56Sopenharmony_ci file as nameobj: object 2007db96d56Sopenharmony_ci mode: str = "r" 2017db96d56Sopenharmony_ci closefd: bool(accept={int}) = True 2027db96d56Sopenharmony_ci opener: object = None 2037db96d56Sopenharmony_ci 2047db96d56Sopenharmony_ciOpen a file. 2057db96d56Sopenharmony_ci 2067db96d56Sopenharmony_ciThe mode can be 'r' (default), 'w', 'x' or 'a' for reading, 2077db96d56Sopenharmony_ciwriting, exclusive creation or appending. The file will be created if it 2087db96d56Sopenharmony_cidoesn't exist when opened for writing or appending; it will be truncated 2097db96d56Sopenharmony_ciwhen opened for writing. A FileExistsError will be raised if it already 2107db96d56Sopenharmony_ciexists when opened for creating. Opening a file for creating implies 2117db96d56Sopenharmony_ciwriting so this mode behaves in a similar way to 'w'.Add a '+' to the mode 2127db96d56Sopenharmony_cito allow simultaneous reading and writing. A custom opener can be used by 2137db96d56Sopenharmony_cipassing a callable as *opener*. The underlying file descriptor for the file 2147db96d56Sopenharmony_ciobject is then obtained by calling opener with (*name*, *flags*). 2157db96d56Sopenharmony_ci*opener* must return an open file descriptor (passing os.open as *opener* 2167db96d56Sopenharmony_ciresults in functionality similar to passing None). 2177db96d56Sopenharmony_ci[clinic start generated code]*/ 2187db96d56Sopenharmony_ci 2197db96d56Sopenharmony_cistatic int 2207db96d56Sopenharmony_ci_io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode, 2217db96d56Sopenharmony_ci int closefd, PyObject *opener) 2227db96d56Sopenharmony_ci/*[clinic end generated code: output=23413f68e6484bbd input=1596c9157a042a39]*/ 2237db96d56Sopenharmony_ci{ 2247db96d56Sopenharmony_ci#ifdef MS_WINDOWS 2257db96d56Sopenharmony_ci Py_UNICODE *widename = NULL; 2267db96d56Sopenharmony_ci#else 2277db96d56Sopenharmony_ci const char *name = NULL; 2287db96d56Sopenharmony_ci#endif 2297db96d56Sopenharmony_ci PyObject *stringobj = NULL; 2307db96d56Sopenharmony_ci const char *s; 2317db96d56Sopenharmony_ci int ret = 0; 2327db96d56Sopenharmony_ci int rwa = 0, plus = 0; 2337db96d56Sopenharmony_ci int flags = 0; 2347db96d56Sopenharmony_ci int fd = -1; 2357db96d56Sopenharmony_ci int fd_is_own = 0; 2367db96d56Sopenharmony_ci#ifdef O_CLOEXEC 2377db96d56Sopenharmony_ci int *atomic_flag_works = &_Py_open_cloexec_works; 2387db96d56Sopenharmony_ci#elif !defined(MS_WINDOWS) 2397db96d56Sopenharmony_ci int *atomic_flag_works = NULL; 2407db96d56Sopenharmony_ci#endif 2417db96d56Sopenharmony_ci struct _Py_stat_struct fdfstat; 2427db96d56Sopenharmony_ci int fstat_result; 2437db96d56Sopenharmony_ci int async_err = 0; 2447db96d56Sopenharmony_ci 2457db96d56Sopenharmony_ci assert(PyFileIO_Check(self)); 2467db96d56Sopenharmony_ci if (self->fd >= 0) { 2477db96d56Sopenharmony_ci if (self->closefd) { 2487db96d56Sopenharmony_ci /* Have to close the existing file first. */ 2497db96d56Sopenharmony_ci if (internal_close(self) < 0) 2507db96d56Sopenharmony_ci return -1; 2517db96d56Sopenharmony_ci } 2527db96d56Sopenharmony_ci else 2537db96d56Sopenharmony_ci self->fd = -1; 2547db96d56Sopenharmony_ci } 2557db96d56Sopenharmony_ci 2567db96d56Sopenharmony_ci fd = _PyLong_AsInt(nameobj); 2577db96d56Sopenharmony_ci if (fd < 0) { 2587db96d56Sopenharmony_ci if (!PyErr_Occurred()) { 2597db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, 2607db96d56Sopenharmony_ci "negative file descriptor"); 2617db96d56Sopenharmony_ci return -1; 2627db96d56Sopenharmony_ci } 2637db96d56Sopenharmony_ci PyErr_Clear(); 2647db96d56Sopenharmony_ci } 2657db96d56Sopenharmony_ci 2667db96d56Sopenharmony_ci if (fd < 0) { 2677db96d56Sopenharmony_ci#ifdef MS_WINDOWS 2687db96d56Sopenharmony_ci if (!PyUnicode_FSDecoder(nameobj, &stringobj)) { 2697db96d56Sopenharmony_ci return -1; 2707db96d56Sopenharmony_ci } 2717db96d56Sopenharmony_ci#if USE_UNICODE_WCHAR_CACHE 2727db96d56Sopenharmony_ci_Py_COMP_DIAG_PUSH 2737db96d56Sopenharmony_ci_Py_COMP_DIAG_IGNORE_DEPR_DECLS 2747db96d56Sopenharmony_ci widename = PyUnicode_AsUnicode(stringobj); 2757db96d56Sopenharmony_ci_Py_COMP_DIAG_POP 2767db96d56Sopenharmony_ci#else /* USE_UNICODE_WCHAR_CACHE */ 2777db96d56Sopenharmony_ci widename = PyUnicode_AsWideCharString(stringobj, NULL); 2787db96d56Sopenharmony_ci#endif /* USE_UNICODE_WCHAR_CACHE */ 2797db96d56Sopenharmony_ci if (widename == NULL) 2807db96d56Sopenharmony_ci return -1; 2817db96d56Sopenharmony_ci#else 2827db96d56Sopenharmony_ci if (!PyUnicode_FSConverter(nameobj, &stringobj)) { 2837db96d56Sopenharmony_ci return -1; 2847db96d56Sopenharmony_ci } 2857db96d56Sopenharmony_ci name = PyBytes_AS_STRING(stringobj); 2867db96d56Sopenharmony_ci#endif 2877db96d56Sopenharmony_ci } 2887db96d56Sopenharmony_ci 2897db96d56Sopenharmony_ci s = mode; 2907db96d56Sopenharmony_ci while (*s) { 2917db96d56Sopenharmony_ci switch (*s++) { 2927db96d56Sopenharmony_ci case 'x': 2937db96d56Sopenharmony_ci if (rwa) { 2947db96d56Sopenharmony_ci bad_mode: 2957db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, 2967db96d56Sopenharmony_ci "Must have exactly one of create/read/write/append " 2977db96d56Sopenharmony_ci "mode and at most one plus"); 2987db96d56Sopenharmony_ci goto error; 2997db96d56Sopenharmony_ci } 3007db96d56Sopenharmony_ci rwa = 1; 3017db96d56Sopenharmony_ci self->created = 1; 3027db96d56Sopenharmony_ci self->writable = 1; 3037db96d56Sopenharmony_ci flags |= O_EXCL | O_CREAT; 3047db96d56Sopenharmony_ci break; 3057db96d56Sopenharmony_ci case 'r': 3067db96d56Sopenharmony_ci if (rwa) 3077db96d56Sopenharmony_ci goto bad_mode; 3087db96d56Sopenharmony_ci rwa = 1; 3097db96d56Sopenharmony_ci self->readable = 1; 3107db96d56Sopenharmony_ci break; 3117db96d56Sopenharmony_ci case 'w': 3127db96d56Sopenharmony_ci if (rwa) 3137db96d56Sopenharmony_ci goto bad_mode; 3147db96d56Sopenharmony_ci rwa = 1; 3157db96d56Sopenharmony_ci self->writable = 1; 3167db96d56Sopenharmony_ci flags |= O_CREAT | O_TRUNC; 3177db96d56Sopenharmony_ci break; 3187db96d56Sopenharmony_ci case 'a': 3197db96d56Sopenharmony_ci if (rwa) 3207db96d56Sopenharmony_ci goto bad_mode; 3217db96d56Sopenharmony_ci rwa = 1; 3227db96d56Sopenharmony_ci self->writable = 1; 3237db96d56Sopenharmony_ci self->appending = 1; 3247db96d56Sopenharmony_ci flags |= O_APPEND | O_CREAT; 3257db96d56Sopenharmony_ci break; 3267db96d56Sopenharmony_ci case 'b': 3277db96d56Sopenharmony_ci break; 3287db96d56Sopenharmony_ci case '+': 3297db96d56Sopenharmony_ci if (plus) 3307db96d56Sopenharmony_ci goto bad_mode; 3317db96d56Sopenharmony_ci self->readable = self->writable = 1; 3327db96d56Sopenharmony_ci plus = 1; 3337db96d56Sopenharmony_ci break; 3347db96d56Sopenharmony_ci default: 3357db96d56Sopenharmony_ci PyErr_Format(PyExc_ValueError, 3367db96d56Sopenharmony_ci "invalid mode: %.200s", mode); 3377db96d56Sopenharmony_ci goto error; 3387db96d56Sopenharmony_ci } 3397db96d56Sopenharmony_ci } 3407db96d56Sopenharmony_ci 3417db96d56Sopenharmony_ci if (!rwa) 3427db96d56Sopenharmony_ci goto bad_mode; 3437db96d56Sopenharmony_ci 3447db96d56Sopenharmony_ci if (self->readable && self->writable) 3457db96d56Sopenharmony_ci flags |= O_RDWR; 3467db96d56Sopenharmony_ci else if (self->readable) 3477db96d56Sopenharmony_ci flags |= O_RDONLY; 3487db96d56Sopenharmony_ci else 3497db96d56Sopenharmony_ci flags |= O_WRONLY; 3507db96d56Sopenharmony_ci 3517db96d56Sopenharmony_ci#ifdef O_BINARY 3527db96d56Sopenharmony_ci flags |= O_BINARY; 3537db96d56Sopenharmony_ci#endif 3547db96d56Sopenharmony_ci 3557db96d56Sopenharmony_ci#ifdef MS_WINDOWS 3567db96d56Sopenharmony_ci flags |= O_NOINHERIT; 3577db96d56Sopenharmony_ci#elif defined(O_CLOEXEC) 3587db96d56Sopenharmony_ci flags |= O_CLOEXEC; 3597db96d56Sopenharmony_ci#endif 3607db96d56Sopenharmony_ci 3617db96d56Sopenharmony_ci if (PySys_Audit("open", "Osi", nameobj, mode, flags) < 0) { 3627db96d56Sopenharmony_ci goto error; 3637db96d56Sopenharmony_ci } 3647db96d56Sopenharmony_ci 3657db96d56Sopenharmony_ci if (fd >= 0) { 3667db96d56Sopenharmony_ci self->fd = fd; 3677db96d56Sopenharmony_ci self->closefd = closefd; 3687db96d56Sopenharmony_ci } 3697db96d56Sopenharmony_ci else { 3707db96d56Sopenharmony_ci self->closefd = 1; 3717db96d56Sopenharmony_ci if (!closefd) { 3727db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, 3737db96d56Sopenharmony_ci "Cannot use closefd=False with file name"); 3747db96d56Sopenharmony_ci goto error; 3757db96d56Sopenharmony_ci } 3767db96d56Sopenharmony_ci 3777db96d56Sopenharmony_ci errno = 0; 3787db96d56Sopenharmony_ci if (opener == Py_None) { 3797db96d56Sopenharmony_ci do { 3807db96d56Sopenharmony_ci Py_BEGIN_ALLOW_THREADS 3817db96d56Sopenharmony_ci#ifdef MS_WINDOWS 3827db96d56Sopenharmony_ci self->fd = _wopen(widename, flags, 0666); 3837db96d56Sopenharmony_ci#else 3847db96d56Sopenharmony_ci self->fd = open(name, flags, 0666); 3857db96d56Sopenharmony_ci#endif 3867db96d56Sopenharmony_ci Py_END_ALLOW_THREADS 3877db96d56Sopenharmony_ci } while (self->fd < 0 && errno == EINTR && 3887db96d56Sopenharmony_ci !(async_err = PyErr_CheckSignals())); 3897db96d56Sopenharmony_ci 3907db96d56Sopenharmony_ci if (async_err) 3917db96d56Sopenharmony_ci goto error; 3927db96d56Sopenharmony_ci } 3937db96d56Sopenharmony_ci else { 3947db96d56Sopenharmony_ci PyObject *fdobj; 3957db96d56Sopenharmony_ci 3967db96d56Sopenharmony_ci#ifndef MS_WINDOWS 3977db96d56Sopenharmony_ci /* the opener may clear the atomic flag */ 3987db96d56Sopenharmony_ci atomic_flag_works = NULL; 3997db96d56Sopenharmony_ci#endif 4007db96d56Sopenharmony_ci 4017db96d56Sopenharmony_ci fdobj = PyObject_CallFunction(opener, "Oi", nameobj, flags); 4027db96d56Sopenharmony_ci if (fdobj == NULL) 4037db96d56Sopenharmony_ci goto error; 4047db96d56Sopenharmony_ci if (!PyLong_Check(fdobj)) { 4057db96d56Sopenharmony_ci Py_DECREF(fdobj); 4067db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, 4077db96d56Sopenharmony_ci "expected integer from opener"); 4087db96d56Sopenharmony_ci goto error; 4097db96d56Sopenharmony_ci } 4107db96d56Sopenharmony_ci 4117db96d56Sopenharmony_ci self->fd = _PyLong_AsInt(fdobj); 4127db96d56Sopenharmony_ci Py_DECREF(fdobj); 4137db96d56Sopenharmony_ci if (self->fd < 0) { 4147db96d56Sopenharmony_ci if (!PyErr_Occurred()) { 4157db96d56Sopenharmony_ci /* The opener returned a negative but didn't set an 4167db96d56Sopenharmony_ci exception. See issue #27066 */ 4177db96d56Sopenharmony_ci PyErr_Format(PyExc_ValueError, 4187db96d56Sopenharmony_ci "opener returned %d", self->fd); 4197db96d56Sopenharmony_ci } 4207db96d56Sopenharmony_ci goto error; 4217db96d56Sopenharmony_ci } 4227db96d56Sopenharmony_ci } 4237db96d56Sopenharmony_ci 4247db96d56Sopenharmony_ci fd_is_own = 1; 4257db96d56Sopenharmony_ci if (self->fd < 0) { 4267db96d56Sopenharmony_ci PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, nameobj); 4277db96d56Sopenharmony_ci goto error; 4287db96d56Sopenharmony_ci } 4297db96d56Sopenharmony_ci 4307db96d56Sopenharmony_ci#ifndef MS_WINDOWS 4317db96d56Sopenharmony_ci if (_Py_set_inheritable(self->fd, 0, atomic_flag_works) < 0) 4327db96d56Sopenharmony_ci goto error; 4337db96d56Sopenharmony_ci#endif 4347db96d56Sopenharmony_ci } 4357db96d56Sopenharmony_ci 4367db96d56Sopenharmony_ci self->blksize = DEFAULT_BUFFER_SIZE; 4377db96d56Sopenharmony_ci Py_BEGIN_ALLOW_THREADS 4387db96d56Sopenharmony_ci fstat_result = _Py_fstat_noraise(self->fd, &fdfstat); 4397db96d56Sopenharmony_ci Py_END_ALLOW_THREADS 4407db96d56Sopenharmony_ci if (fstat_result < 0) { 4417db96d56Sopenharmony_ci /* Tolerate fstat() errors other than EBADF. See Issue #25717, where 4427db96d56Sopenharmony_ci an anonymous file on a Virtual Box shared folder filesystem would 4437db96d56Sopenharmony_ci raise ENOENT. */ 4447db96d56Sopenharmony_ci#ifdef MS_WINDOWS 4457db96d56Sopenharmony_ci if (GetLastError() == ERROR_INVALID_HANDLE) { 4467db96d56Sopenharmony_ci PyErr_SetFromWindowsErr(0); 4477db96d56Sopenharmony_ci#else 4487db96d56Sopenharmony_ci if (errno == EBADF) { 4497db96d56Sopenharmony_ci PyErr_SetFromErrno(PyExc_OSError); 4507db96d56Sopenharmony_ci#endif 4517db96d56Sopenharmony_ci goto error; 4527db96d56Sopenharmony_ci } 4537db96d56Sopenharmony_ci } 4547db96d56Sopenharmony_ci else { 4557db96d56Sopenharmony_ci#if defined(S_ISDIR) && defined(EISDIR) 4567db96d56Sopenharmony_ci /* On Unix, open will succeed for directories. 4577db96d56Sopenharmony_ci In Python, there should be no file objects referring to 4587db96d56Sopenharmony_ci directories, so we need a check. */ 4597db96d56Sopenharmony_ci if (S_ISDIR(fdfstat.st_mode)) { 4607db96d56Sopenharmony_ci errno = EISDIR; 4617db96d56Sopenharmony_ci PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, nameobj); 4627db96d56Sopenharmony_ci goto error; 4637db96d56Sopenharmony_ci } 4647db96d56Sopenharmony_ci#endif /* defined(S_ISDIR) */ 4657db96d56Sopenharmony_ci#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE 4667db96d56Sopenharmony_ci if (fdfstat.st_blksize > 1) 4677db96d56Sopenharmony_ci self->blksize = fdfstat.st_blksize; 4687db96d56Sopenharmony_ci#endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */ 4697db96d56Sopenharmony_ci } 4707db96d56Sopenharmony_ci 4717db96d56Sopenharmony_ci#if defined(MS_WINDOWS) || defined(__CYGWIN__) 4727db96d56Sopenharmony_ci /* don't translate newlines (\r\n <=> \n) */ 4737db96d56Sopenharmony_ci _setmode(self->fd, O_BINARY); 4747db96d56Sopenharmony_ci#endif 4757db96d56Sopenharmony_ci 4767db96d56Sopenharmony_ci if (PyObject_SetAttr((PyObject *)self, &_Py_ID(name), nameobj) < 0) 4777db96d56Sopenharmony_ci goto error; 4787db96d56Sopenharmony_ci 4797db96d56Sopenharmony_ci if (self->appending) { 4807db96d56Sopenharmony_ci /* For consistent behaviour, we explicitly seek to the 4817db96d56Sopenharmony_ci end of file (otherwise, it might be done only on the 4827db96d56Sopenharmony_ci first write()). */ 4837db96d56Sopenharmony_ci PyObject *pos = portable_lseek(self, NULL, 2, true); 4847db96d56Sopenharmony_ci if (pos == NULL) 4857db96d56Sopenharmony_ci goto error; 4867db96d56Sopenharmony_ci Py_DECREF(pos); 4877db96d56Sopenharmony_ci } 4887db96d56Sopenharmony_ci 4897db96d56Sopenharmony_ci goto done; 4907db96d56Sopenharmony_ci 4917db96d56Sopenharmony_ci error: 4927db96d56Sopenharmony_ci ret = -1; 4937db96d56Sopenharmony_ci if (!fd_is_own) 4947db96d56Sopenharmony_ci self->fd = -1; 4957db96d56Sopenharmony_ci if (self->fd >= 0) { 4967db96d56Sopenharmony_ci PyObject *exc, *val, *tb; 4977db96d56Sopenharmony_ci PyErr_Fetch(&exc, &val, &tb); 4987db96d56Sopenharmony_ci internal_close(self); 4997db96d56Sopenharmony_ci _PyErr_ChainExceptions(exc, val, tb); 5007db96d56Sopenharmony_ci } 5017db96d56Sopenharmony_ci 5027db96d56Sopenharmony_ci done: 5037db96d56Sopenharmony_ci#ifdef MS_WINDOWS 5047db96d56Sopenharmony_ci#if !USE_UNICODE_WCHAR_CACHE 5057db96d56Sopenharmony_ci PyMem_Free(widename); 5067db96d56Sopenharmony_ci#endif /* USE_UNICODE_WCHAR_CACHE */ 5077db96d56Sopenharmony_ci#endif 5087db96d56Sopenharmony_ci Py_CLEAR(stringobj); 5097db96d56Sopenharmony_ci return ret; 5107db96d56Sopenharmony_ci} 5117db96d56Sopenharmony_ci 5127db96d56Sopenharmony_cistatic int 5137db96d56Sopenharmony_cifileio_traverse(fileio *self, visitproc visit, void *arg) 5147db96d56Sopenharmony_ci{ 5157db96d56Sopenharmony_ci Py_VISIT(self->dict); 5167db96d56Sopenharmony_ci return 0; 5177db96d56Sopenharmony_ci} 5187db96d56Sopenharmony_ci 5197db96d56Sopenharmony_cistatic int 5207db96d56Sopenharmony_cifileio_clear(fileio *self) 5217db96d56Sopenharmony_ci{ 5227db96d56Sopenharmony_ci Py_CLEAR(self->dict); 5237db96d56Sopenharmony_ci return 0; 5247db96d56Sopenharmony_ci} 5257db96d56Sopenharmony_ci 5267db96d56Sopenharmony_cistatic void 5277db96d56Sopenharmony_cifileio_dealloc(fileio *self) 5287db96d56Sopenharmony_ci{ 5297db96d56Sopenharmony_ci self->finalizing = 1; 5307db96d56Sopenharmony_ci if (_PyIOBase_finalize((PyObject *) self) < 0) 5317db96d56Sopenharmony_ci return; 5327db96d56Sopenharmony_ci _PyObject_GC_UNTRACK(self); 5337db96d56Sopenharmony_ci if (self->weakreflist != NULL) 5347db96d56Sopenharmony_ci PyObject_ClearWeakRefs((PyObject *) self); 5357db96d56Sopenharmony_ci Py_CLEAR(self->dict); 5367db96d56Sopenharmony_ci Py_TYPE(self)->tp_free((PyObject *)self); 5377db96d56Sopenharmony_ci} 5387db96d56Sopenharmony_ci 5397db96d56Sopenharmony_cistatic PyObject * 5407db96d56Sopenharmony_cierr_closed(void) 5417db96d56Sopenharmony_ci{ 5427db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, "I/O operation on closed file"); 5437db96d56Sopenharmony_ci return NULL; 5447db96d56Sopenharmony_ci} 5457db96d56Sopenharmony_ci 5467db96d56Sopenharmony_cistatic PyObject * 5477db96d56Sopenharmony_cierr_mode(const char *action) 5487db96d56Sopenharmony_ci{ 5497db96d56Sopenharmony_ci _PyIO_State *state = IO_STATE(); 5507db96d56Sopenharmony_ci if (state != NULL) 5517db96d56Sopenharmony_ci PyErr_Format(state->unsupported_operation, 5527db96d56Sopenharmony_ci "File not open for %s", action); 5537db96d56Sopenharmony_ci return NULL; 5547db96d56Sopenharmony_ci} 5557db96d56Sopenharmony_ci 5567db96d56Sopenharmony_ci/*[clinic input] 5577db96d56Sopenharmony_ci_io.FileIO.fileno 5587db96d56Sopenharmony_ci 5597db96d56Sopenharmony_ciReturn the underlying file descriptor (an integer). 5607db96d56Sopenharmony_ci[clinic start generated code]*/ 5617db96d56Sopenharmony_ci 5627db96d56Sopenharmony_cistatic PyObject * 5637db96d56Sopenharmony_ci_io_FileIO_fileno_impl(fileio *self) 5647db96d56Sopenharmony_ci/*[clinic end generated code: output=a9626ce5398ece90 input=0b9b2de67335ada3]*/ 5657db96d56Sopenharmony_ci{ 5667db96d56Sopenharmony_ci if (self->fd < 0) 5677db96d56Sopenharmony_ci return err_closed(); 5687db96d56Sopenharmony_ci return PyLong_FromLong((long) self->fd); 5697db96d56Sopenharmony_ci} 5707db96d56Sopenharmony_ci 5717db96d56Sopenharmony_ci/*[clinic input] 5727db96d56Sopenharmony_ci_io.FileIO.readable 5737db96d56Sopenharmony_ci 5747db96d56Sopenharmony_ciTrue if file was opened in a read mode. 5757db96d56Sopenharmony_ci[clinic start generated code]*/ 5767db96d56Sopenharmony_ci 5777db96d56Sopenharmony_cistatic PyObject * 5787db96d56Sopenharmony_ci_io_FileIO_readable_impl(fileio *self) 5797db96d56Sopenharmony_ci/*[clinic end generated code: output=640744a6150fe9ba input=a3fdfed6eea721c5]*/ 5807db96d56Sopenharmony_ci{ 5817db96d56Sopenharmony_ci if (self->fd < 0) 5827db96d56Sopenharmony_ci return err_closed(); 5837db96d56Sopenharmony_ci return PyBool_FromLong((long) self->readable); 5847db96d56Sopenharmony_ci} 5857db96d56Sopenharmony_ci 5867db96d56Sopenharmony_ci/*[clinic input] 5877db96d56Sopenharmony_ci_io.FileIO.writable 5887db96d56Sopenharmony_ci 5897db96d56Sopenharmony_ciTrue if file was opened in a write mode. 5907db96d56Sopenharmony_ci[clinic start generated code]*/ 5917db96d56Sopenharmony_ci 5927db96d56Sopenharmony_cistatic PyObject * 5937db96d56Sopenharmony_ci_io_FileIO_writable_impl(fileio *self) 5947db96d56Sopenharmony_ci/*[clinic end generated code: output=96cefc5446e89977 input=c204a808ca2e1748]*/ 5957db96d56Sopenharmony_ci{ 5967db96d56Sopenharmony_ci if (self->fd < 0) 5977db96d56Sopenharmony_ci return err_closed(); 5987db96d56Sopenharmony_ci return PyBool_FromLong((long) self->writable); 5997db96d56Sopenharmony_ci} 6007db96d56Sopenharmony_ci 6017db96d56Sopenharmony_ci/*[clinic input] 6027db96d56Sopenharmony_ci_io.FileIO.seekable 6037db96d56Sopenharmony_ci 6047db96d56Sopenharmony_ciTrue if file supports random-access. 6057db96d56Sopenharmony_ci[clinic start generated code]*/ 6067db96d56Sopenharmony_ci 6077db96d56Sopenharmony_cistatic PyObject * 6087db96d56Sopenharmony_ci_io_FileIO_seekable_impl(fileio *self) 6097db96d56Sopenharmony_ci/*[clinic end generated code: output=47909ca0a42e9287 input=c8e5554d2fd63c7f]*/ 6107db96d56Sopenharmony_ci{ 6117db96d56Sopenharmony_ci if (self->fd < 0) 6127db96d56Sopenharmony_ci return err_closed(); 6137db96d56Sopenharmony_ci if (self->seekable < 0) { 6147db96d56Sopenharmony_ci /* portable_lseek() sets the seekable attribute */ 6157db96d56Sopenharmony_ci PyObject *pos = portable_lseek(self, NULL, SEEK_CUR, false); 6167db96d56Sopenharmony_ci assert(self->seekable >= 0); 6177db96d56Sopenharmony_ci if (pos == NULL) { 6187db96d56Sopenharmony_ci PyErr_Clear(); 6197db96d56Sopenharmony_ci } 6207db96d56Sopenharmony_ci else { 6217db96d56Sopenharmony_ci Py_DECREF(pos); 6227db96d56Sopenharmony_ci } 6237db96d56Sopenharmony_ci } 6247db96d56Sopenharmony_ci return PyBool_FromLong((long) self->seekable); 6257db96d56Sopenharmony_ci} 6267db96d56Sopenharmony_ci 6277db96d56Sopenharmony_ci/*[clinic input] 6287db96d56Sopenharmony_ci_io.FileIO.readinto 6297db96d56Sopenharmony_ci buffer: Py_buffer(accept={rwbuffer}) 6307db96d56Sopenharmony_ci / 6317db96d56Sopenharmony_ci 6327db96d56Sopenharmony_ciSame as RawIOBase.readinto(). 6337db96d56Sopenharmony_ci[clinic start generated code]*/ 6347db96d56Sopenharmony_ci 6357db96d56Sopenharmony_cistatic PyObject * 6367db96d56Sopenharmony_ci_io_FileIO_readinto_impl(fileio *self, Py_buffer *buffer) 6377db96d56Sopenharmony_ci/*[clinic end generated code: output=b01a5a22c8415cb4 input=4721d7b68b154eaf]*/ 6387db96d56Sopenharmony_ci{ 6397db96d56Sopenharmony_ci Py_ssize_t n; 6407db96d56Sopenharmony_ci int err; 6417db96d56Sopenharmony_ci 6427db96d56Sopenharmony_ci if (self->fd < 0) 6437db96d56Sopenharmony_ci return err_closed(); 6447db96d56Sopenharmony_ci if (!self->readable) 6457db96d56Sopenharmony_ci return err_mode("reading"); 6467db96d56Sopenharmony_ci 6477db96d56Sopenharmony_ci n = _Py_read(self->fd, buffer->buf, buffer->len); 6487db96d56Sopenharmony_ci /* copy errno because PyBuffer_Release() can indirectly modify it */ 6497db96d56Sopenharmony_ci err = errno; 6507db96d56Sopenharmony_ci 6517db96d56Sopenharmony_ci if (n == -1) { 6527db96d56Sopenharmony_ci if (err == EAGAIN) { 6537db96d56Sopenharmony_ci PyErr_Clear(); 6547db96d56Sopenharmony_ci Py_RETURN_NONE; 6557db96d56Sopenharmony_ci } 6567db96d56Sopenharmony_ci return NULL; 6577db96d56Sopenharmony_ci } 6587db96d56Sopenharmony_ci 6597db96d56Sopenharmony_ci return PyLong_FromSsize_t(n); 6607db96d56Sopenharmony_ci} 6617db96d56Sopenharmony_ci 6627db96d56Sopenharmony_cistatic size_t 6637db96d56Sopenharmony_cinew_buffersize(fileio *self, size_t currentsize) 6647db96d56Sopenharmony_ci{ 6657db96d56Sopenharmony_ci size_t addend; 6667db96d56Sopenharmony_ci 6677db96d56Sopenharmony_ci /* Expand the buffer by an amount proportional to the current size, 6687db96d56Sopenharmony_ci giving us amortized linear-time behavior. For bigger sizes, use a 6697db96d56Sopenharmony_ci less-than-double growth factor to avoid excessive allocation. */ 6707db96d56Sopenharmony_ci assert(currentsize <= PY_SSIZE_T_MAX); 6717db96d56Sopenharmony_ci if (currentsize > 65536) 6727db96d56Sopenharmony_ci addend = currentsize >> 3; 6737db96d56Sopenharmony_ci else 6747db96d56Sopenharmony_ci addend = 256 + currentsize; 6757db96d56Sopenharmony_ci if (addend < SMALLCHUNK) 6767db96d56Sopenharmony_ci /* Avoid tiny read() calls. */ 6777db96d56Sopenharmony_ci addend = SMALLCHUNK; 6787db96d56Sopenharmony_ci return addend + currentsize; 6797db96d56Sopenharmony_ci} 6807db96d56Sopenharmony_ci 6817db96d56Sopenharmony_ci/*[clinic input] 6827db96d56Sopenharmony_ci_io.FileIO.readall 6837db96d56Sopenharmony_ci 6847db96d56Sopenharmony_ciRead all data from the file, returned as bytes. 6857db96d56Sopenharmony_ci 6867db96d56Sopenharmony_ciIn non-blocking mode, returns as much as is immediately available, 6877db96d56Sopenharmony_cior None if no data is available. Return an empty bytes object at EOF. 6887db96d56Sopenharmony_ci[clinic start generated code]*/ 6897db96d56Sopenharmony_ci 6907db96d56Sopenharmony_cistatic PyObject * 6917db96d56Sopenharmony_ci_io_FileIO_readall_impl(fileio *self) 6927db96d56Sopenharmony_ci/*[clinic end generated code: output=faa0292b213b4022 input=dbdc137f55602834]*/ 6937db96d56Sopenharmony_ci{ 6947db96d56Sopenharmony_ci struct _Py_stat_struct status; 6957db96d56Sopenharmony_ci Py_off_t pos, end; 6967db96d56Sopenharmony_ci PyObject *result; 6977db96d56Sopenharmony_ci Py_ssize_t bytes_read = 0; 6987db96d56Sopenharmony_ci Py_ssize_t n; 6997db96d56Sopenharmony_ci size_t bufsize; 7007db96d56Sopenharmony_ci int fstat_result; 7017db96d56Sopenharmony_ci 7027db96d56Sopenharmony_ci if (self->fd < 0) 7037db96d56Sopenharmony_ci return err_closed(); 7047db96d56Sopenharmony_ci 7057db96d56Sopenharmony_ci Py_BEGIN_ALLOW_THREADS 7067db96d56Sopenharmony_ci _Py_BEGIN_SUPPRESS_IPH 7077db96d56Sopenharmony_ci#ifdef MS_WINDOWS 7087db96d56Sopenharmony_ci pos = _lseeki64(self->fd, 0L, SEEK_CUR); 7097db96d56Sopenharmony_ci#else 7107db96d56Sopenharmony_ci pos = lseek(self->fd, 0L, SEEK_CUR); 7117db96d56Sopenharmony_ci#endif 7127db96d56Sopenharmony_ci _Py_END_SUPPRESS_IPH 7137db96d56Sopenharmony_ci fstat_result = _Py_fstat_noraise(self->fd, &status); 7147db96d56Sopenharmony_ci Py_END_ALLOW_THREADS 7157db96d56Sopenharmony_ci 7167db96d56Sopenharmony_ci if (fstat_result == 0) 7177db96d56Sopenharmony_ci end = status.st_size; 7187db96d56Sopenharmony_ci else 7197db96d56Sopenharmony_ci end = (Py_off_t)-1; 7207db96d56Sopenharmony_ci 7217db96d56Sopenharmony_ci if (end > 0 && end >= pos && pos >= 0 && end - pos < PY_SSIZE_T_MAX) { 7227db96d56Sopenharmony_ci /* This is probably a real file, so we try to allocate a 7237db96d56Sopenharmony_ci buffer one byte larger than the rest of the file. If the 7247db96d56Sopenharmony_ci calculation is right then we should get EOF without having 7257db96d56Sopenharmony_ci to enlarge the buffer. */ 7267db96d56Sopenharmony_ci bufsize = (size_t)(end - pos + 1); 7277db96d56Sopenharmony_ci } else { 7287db96d56Sopenharmony_ci bufsize = SMALLCHUNK; 7297db96d56Sopenharmony_ci } 7307db96d56Sopenharmony_ci 7317db96d56Sopenharmony_ci result = PyBytes_FromStringAndSize(NULL, bufsize); 7327db96d56Sopenharmony_ci if (result == NULL) 7337db96d56Sopenharmony_ci return NULL; 7347db96d56Sopenharmony_ci 7357db96d56Sopenharmony_ci while (1) { 7367db96d56Sopenharmony_ci if (bytes_read >= (Py_ssize_t)bufsize) { 7377db96d56Sopenharmony_ci bufsize = new_buffersize(self, bytes_read); 7387db96d56Sopenharmony_ci if (bufsize > PY_SSIZE_T_MAX || bufsize <= 0) { 7397db96d56Sopenharmony_ci PyErr_SetString(PyExc_OverflowError, 7407db96d56Sopenharmony_ci "unbounded read returned more bytes " 7417db96d56Sopenharmony_ci "than a Python bytes object can hold"); 7427db96d56Sopenharmony_ci Py_DECREF(result); 7437db96d56Sopenharmony_ci return NULL; 7447db96d56Sopenharmony_ci } 7457db96d56Sopenharmony_ci 7467db96d56Sopenharmony_ci if (PyBytes_GET_SIZE(result) < (Py_ssize_t)bufsize) { 7477db96d56Sopenharmony_ci if (_PyBytes_Resize(&result, bufsize) < 0) 7487db96d56Sopenharmony_ci return NULL; 7497db96d56Sopenharmony_ci } 7507db96d56Sopenharmony_ci } 7517db96d56Sopenharmony_ci 7527db96d56Sopenharmony_ci n = _Py_read(self->fd, 7537db96d56Sopenharmony_ci PyBytes_AS_STRING(result) + bytes_read, 7547db96d56Sopenharmony_ci bufsize - bytes_read); 7557db96d56Sopenharmony_ci 7567db96d56Sopenharmony_ci if (n == 0) 7577db96d56Sopenharmony_ci break; 7587db96d56Sopenharmony_ci if (n == -1) { 7597db96d56Sopenharmony_ci if (errno == EAGAIN) { 7607db96d56Sopenharmony_ci PyErr_Clear(); 7617db96d56Sopenharmony_ci if (bytes_read > 0) 7627db96d56Sopenharmony_ci break; 7637db96d56Sopenharmony_ci Py_DECREF(result); 7647db96d56Sopenharmony_ci Py_RETURN_NONE; 7657db96d56Sopenharmony_ci } 7667db96d56Sopenharmony_ci Py_DECREF(result); 7677db96d56Sopenharmony_ci return NULL; 7687db96d56Sopenharmony_ci } 7697db96d56Sopenharmony_ci bytes_read += n; 7707db96d56Sopenharmony_ci pos += n; 7717db96d56Sopenharmony_ci } 7727db96d56Sopenharmony_ci 7737db96d56Sopenharmony_ci if (PyBytes_GET_SIZE(result) > bytes_read) { 7747db96d56Sopenharmony_ci if (_PyBytes_Resize(&result, bytes_read) < 0) 7757db96d56Sopenharmony_ci return NULL; 7767db96d56Sopenharmony_ci } 7777db96d56Sopenharmony_ci return result; 7787db96d56Sopenharmony_ci} 7797db96d56Sopenharmony_ci 7807db96d56Sopenharmony_ci/*[clinic input] 7817db96d56Sopenharmony_ci_io.FileIO.read 7827db96d56Sopenharmony_ci size: Py_ssize_t(accept={int, NoneType}) = -1 7837db96d56Sopenharmony_ci / 7847db96d56Sopenharmony_ci 7857db96d56Sopenharmony_ciRead at most size bytes, returned as bytes. 7867db96d56Sopenharmony_ci 7877db96d56Sopenharmony_ciOnly makes one system call, so less data may be returned than requested. 7887db96d56Sopenharmony_ciIn non-blocking mode, returns None if no data is available. 7897db96d56Sopenharmony_ciReturn an empty bytes object at EOF. 7907db96d56Sopenharmony_ci[clinic start generated code]*/ 7917db96d56Sopenharmony_ci 7927db96d56Sopenharmony_cistatic PyObject * 7937db96d56Sopenharmony_ci_io_FileIO_read_impl(fileio *self, Py_ssize_t size) 7947db96d56Sopenharmony_ci/*[clinic end generated code: output=42528d39dd0ca641 input=bec9a2c704ddcbc9]*/ 7957db96d56Sopenharmony_ci{ 7967db96d56Sopenharmony_ci char *ptr; 7977db96d56Sopenharmony_ci Py_ssize_t n; 7987db96d56Sopenharmony_ci PyObject *bytes; 7997db96d56Sopenharmony_ci 8007db96d56Sopenharmony_ci if (self->fd < 0) 8017db96d56Sopenharmony_ci return err_closed(); 8027db96d56Sopenharmony_ci if (!self->readable) 8037db96d56Sopenharmony_ci return err_mode("reading"); 8047db96d56Sopenharmony_ci 8057db96d56Sopenharmony_ci if (size < 0) 8067db96d56Sopenharmony_ci return _io_FileIO_readall_impl(self); 8077db96d56Sopenharmony_ci 8087db96d56Sopenharmony_ci if (size > _PY_READ_MAX) { 8097db96d56Sopenharmony_ci size = _PY_READ_MAX; 8107db96d56Sopenharmony_ci } 8117db96d56Sopenharmony_ci 8127db96d56Sopenharmony_ci bytes = PyBytes_FromStringAndSize(NULL, size); 8137db96d56Sopenharmony_ci if (bytes == NULL) 8147db96d56Sopenharmony_ci return NULL; 8157db96d56Sopenharmony_ci ptr = PyBytes_AS_STRING(bytes); 8167db96d56Sopenharmony_ci 8177db96d56Sopenharmony_ci n = _Py_read(self->fd, ptr, size); 8187db96d56Sopenharmony_ci if (n == -1) { 8197db96d56Sopenharmony_ci /* copy errno because Py_DECREF() can indirectly modify it */ 8207db96d56Sopenharmony_ci int err = errno; 8217db96d56Sopenharmony_ci Py_DECREF(bytes); 8227db96d56Sopenharmony_ci if (err == EAGAIN) { 8237db96d56Sopenharmony_ci PyErr_Clear(); 8247db96d56Sopenharmony_ci Py_RETURN_NONE; 8257db96d56Sopenharmony_ci } 8267db96d56Sopenharmony_ci return NULL; 8277db96d56Sopenharmony_ci } 8287db96d56Sopenharmony_ci 8297db96d56Sopenharmony_ci if (n != size) { 8307db96d56Sopenharmony_ci if (_PyBytes_Resize(&bytes, n) < 0) { 8317db96d56Sopenharmony_ci Py_CLEAR(bytes); 8327db96d56Sopenharmony_ci return NULL; 8337db96d56Sopenharmony_ci } 8347db96d56Sopenharmony_ci } 8357db96d56Sopenharmony_ci 8367db96d56Sopenharmony_ci return (PyObject *) bytes; 8377db96d56Sopenharmony_ci} 8387db96d56Sopenharmony_ci 8397db96d56Sopenharmony_ci/*[clinic input] 8407db96d56Sopenharmony_ci_io.FileIO.write 8417db96d56Sopenharmony_ci b: Py_buffer 8427db96d56Sopenharmony_ci / 8437db96d56Sopenharmony_ci 8447db96d56Sopenharmony_ciWrite buffer b to file, return number of bytes written. 8457db96d56Sopenharmony_ci 8467db96d56Sopenharmony_ciOnly makes one system call, so not all of the data may be written. 8477db96d56Sopenharmony_ciThe number of bytes actually written is returned. In non-blocking mode, 8487db96d56Sopenharmony_cireturns None if the write would block. 8497db96d56Sopenharmony_ci[clinic start generated code]*/ 8507db96d56Sopenharmony_ci 8517db96d56Sopenharmony_cistatic PyObject * 8527db96d56Sopenharmony_ci_io_FileIO_write_impl(fileio *self, Py_buffer *b) 8537db96d56Sopenharmony_ci/*[clinic end generated code: output=b4059db3d363a2f7 input=6e7908b36f0ce74f]*/ 8547db96d56Sopenharmony_ci{ 8557db96d56Sopenharmony_ci Py_ssize_t n; 8567db96d56Sopenharmony_ci int err; 8577db96d56Sopenharmony_ci 8587db96d56Sopenharmony_ci if (self->fd < 0) 8597db96d56Sopenharmony_ci return err_closed(); 8607db96d56Sopenharmony_ci if (!self->writable) 8617db96d56Sopenharmony_ci return err_mode("writing"); 8627db96d56Sopenharmony_ci 8637db96d56Sopenharmony_ci n = _Py_write(self->fd, b->buf, b->len); 8647db96d56Sopenharmony_ci /* copy errno because PyBuffer_Release() can indirectly modify it */ 8657db96d56Sopenharmony_ci err = errno; 8667db96d56Sopenharmony_ci 8677db96d56Sopenharmony_ci if (n < 0) { 8687db96d56Sopenharmony_ci if (err == EAGAIN) { 8697db96d56Sopenharmony_ci PyErr_Clear(); 8707db96d56Sopenharmony_ci Py_RETURN_NONE; 8717db96d56Sopenharmony_ci } 8727db96d56Sopenharmony_ci return NULL; 8737db96d56Sopenharmony_ci } 8747db96d56Sopenharmony_ci 8757db96d56Sopenharmony_ci return PyLong_FromSsize_t(n); 8767db96d56Sopenharmony_ci} 8777db96d56Sopenharmony_ci 8787db96d56Sopenharmony_ci/* XXX Windows support below is likely incomplete */ 8797db96d56Sopenharmony_ci 8807db96d56Sopenharmony_ci/* Cribbed from posix_lseek() */ 8817db96d56Sopenharmony_cistatic PyObject * 8827db96d56Sopenharmony_ciportable_lseek(fileio *self, PyObject *posobj, int whence, bool suppress_pipe_error) 8837db96d56Sopenharmony_ci{ 8847db96d56Sopenharmony_ci Py_off_t pos, res; 8857db96d56Sopenharmony_ci int fd = self->fd; 8867db96d56Sopenharmony_ci 8877db96d56Sopenharmony_ci#ifdef SEEK_SET 8887db96d56Sopenharmony_ci /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */ 8897db96d56Sopenharmony_ci switch (whence) { 8907db96d56Sopenharmony_ci#if SEEK_SET != 0 8917db96d56Sopenharmony_ci case 0: whence = SEEK_SET; break; 8927db96d56Sopenharmony_ci#endif 8937db96d56Sopenharmony_ci#if SEEK_CUR != 1 8947db96d56Sopenharmony_ci case 1: whence = SEEK_CUR; break; 8957db96d56Sopenharmony_ci#endif 8967db96d56Sopenharmony_ci#if SEEK_END != 2 8977db96d56Sopenharmony_ci case 2: whence = SEEK_END; break; 8987db96d56Sopenharmony_ci#endif 8997db96d56Sopenharmony_ci } 9007db96d56Sopenharmony_ci#endif /* SEEK_SET */ 9017db96d56Sopenharmony_ci 9027db96d56Sopenharmony_ci if (posobj == NULL) { 9037db96d56Sopenharmony_ci pos = 0; 9047db96d56Sopenharmony_ci } 9057db96d56Sopenharmony_ci else { 9067db96d56Sopenharmony_ci#if defined(HAVE_LARGEFILE_SUPPORT) 9077db96d56Sopenharmony_ci pos = PyLong_AsLongLong(posobj); 9087db96d56Sopenharmony_ci#else 9097db96d56Sopenharmony_ci pos = PyLong_AsLong(posobj); 9107db96d56Sopenharmony_ci#endif 9117db96d56Sopenharmony_ci if (PyErr_Occurred()) 9127db96d56Sopenharmony_ci return NULL; 9137db96d56Sopenharmony_ci } 9147db96d56Sopenharmony_ci 9157db96d56Sopenharmony_ci Py_BEGIN_ALLOW_THREADS 9167db96d56Sopenharmony_ci _Py_BEGIN_SUPPRESS_IPH 9177db96d56Sopenharmony_ci#ifdef MS_WINDOWS 9187db96d56Sopenharmony_ci res = _lseeki64(fd, pos, whence); 9197db96d56Sopenharmony_ci#else 9207db96d56Sopenharmony_ci res = lseek(fd, pos, whence); 9217db96d56Sopenharmony_ci#endif 9227db96d56Sopenharmony_ci _Py_END_SUPPRESS_IPH 9237db96d56Sopenharmony_ci Py_END_ALLOW_THREADS 9247db96d56Sopenharmony_ci 9257db96d56Sopenharmony_ci if (self->seekable < 0) { 9267db96d56Sopenharmony_ci self->seekable = (res >= 0); 9277db96d56Sopenharmony_ci } 9287db96d56Sopenharmony_ci 9297db96d56Sopenharmony_ci if (res < 0) { 9307db96d56Sopenharmony_ci if (suppress_pipe_error && errno == ESPIPE) { 9317db96d56Sopenharmony_ci res = 0; 9327db96d56Sopenharmony_ci } else { 9337db96d56Sopenharmony_ci return PyErr_SetFromErrno(PyExc_OSError); 9347db96d56Sopenharmony_ci } 9357db96d56Sopenharmony_ci } 9367db96d56Sopenharmony_ci 9377db96d56Sopenharmony_ci#if defined(HAVE_LARGEFILE_SUPPORT) 9387db96d56Sopenharmony_ci return PyLong_FromLongLong(res); 9397db96d56Sopenharmony_ci#else 9407db96d56Sopenharmony_ci return PyLong_FromLong(res); 9417db96d56Sopenharmony_ci#endif 9427db96d56Sopenharmony_ci} 9437db96d56Sopenharmony_ci 9447db96d56Sopenharmony_ci/*[clinic input] 9457db96d56Sopenharmony_ci_io.FileIO.seek 9467db96d56Sopenharmony_ci pos: object 9477db96d56Sopenharmony_ci whence: int = 0 9487db96d56Sopenharmony_ci / 9497db96d56Sopenharmony_ci 9507db96d56Sopenharmony_ciMove to new file position and return the file position. 9517db96d56Sopenharmony_ci 9527db96d56Sopenharmony_ciArgument offset is a byte count. Optional argument whence defaults to 9537db96d56Sopenharmony_ciSEEK_SET or 0 (offset from start of file, offset should be >= 0); other values 9547db96d56Sopenharmony_ciare SEEK_CUR or 1 (move relative to current position, positive or negative), 9557db96d56Sopenharmony_ciand SEEK_END or 2 (move relative to end of file, usually negative, although 9567db96d56Sopenharmony_cimany platforms allow seeking beyond the end of a file). 9577db96d56Sopenharmony_ci 9587db96d56Sopenharmony_ciNote that not all file objects are seekable. 9597db96d56Sopenharmony_ci[clinic start generated code]*/ 9607db96d56Sopenharmony_ci 9617db96d56Sopenharmony_cistatic PyObject * 9627db96d56Sopenharmony_ci_io_FileIO_seek_impl(fileio *self, PyObject *pos, int whence) 9637db96d56Sopenharmony_ci/*[clinic end generated code: output=c976acdf054e6655 input=0439194b0774d454]*/ 9647db96d56Sopenharmony_ci{ 9657db96d56Sopenharmony_ci if (self->fd < 0) 9667db96d56Sopenharmony_ci return err_closed(); 9677db96d56Sopenharmony_ci 9687db96d56Sopenharmony_ci return portable_lseek(self, pos, whence, false); 9697db96d56Sopenharmony_ci} 9707db96d56Sopenharmony_ci 9717db96d56Sopenharmony_ci/*[clinic input] 9727db96d56Sopenharmony_ci_io.FileIO.tell 9737db96d56Sopenharmony_ci 9747db96d56Sopenharmony_ciCurrent file position. 9757db96d56Sopenharmony_ci 9767db96d56Sopenharmony_ciCan raise OSError for non seekable files. 9777db96d56Sopenharmony_ci[clinic start generated code]*/ 9787db96d56Sopenharmony_ci 9797db96d56Sopenharmony_cistatic PyObject * 9807db96d56Sopenharmony_ci_io_FileIO_tell_impl(fileio *self) 9817db96d56Sopenharmony_ci/*[clinic end generated code: output=ffe2147058809d0b input=807e24ead4cec2f9]*/ 9827db96d56Sopenharmony_ci{ 9837db96d56Sopenharmony_ci if (self->fd < 0) 9847db96d56Sopenharmony_ci return err_closed(); 9857db96d56Sopenharmony_ci 9867db96d56Sopenharmony_ci return portable_lseek(self, NULL, 1, false); 9877db96d56Sopenharmony_ci} 9887db96d56Sopenharmony_ci 9897db96d56Sopenharmony_ci#ifdef HAVE_FTRUNCATE 9907db96d56Sopenharmony_ci/*[clinic input] 9917db96d56Sopenharmony_ci_io.FileIO.truncate 9927db96d56Sopenharmony_ci size as posobj: object = None 9937db96d56Sopenharmony_ci / 9947db96d56Sopenharmony_ci 9957db96d56Sopenharmony_ciTruncate the file to at most size bytes and return the truncated size. 9967db96d56Sopenharmony_ci 9977db96d56Sopenharmony_ciSize defaults to the current file position, as returned by tell(). 9987db96d56Sopenharmony_ciThe current file position is changed to the value of size. 9997db96d56Sopenharmony_ci[clinic start generated code]*/ 10007db96d56Sopenharmony_ci 10017db96d56Sopenharmony_cistatic PyObject * 10027db96d56Sopenharmony_ci_io_FileIO_truncate_impl(fileio *self, PyObject *posobj) 10037db96d56Sopenharmony_ci/*[clinic end generated code: output=e49ca7a916c176fa input=b0ac133939823875]*/ 10047db96d56Sopenharmony_ci{ 10057db96d56Sopenharmony_ci Py_off_t pos; 10067db96d56Sopenharmony_ci int ret; 10077db96d56Sopenharmony_ci int fd; 10087db96d56Sopenharmony_ci 10097db96d56Sopenharmony_ci fd = self->fd; 10107db96d56Sopenharmony_ci if (fd < 0) 10117db96d56Sopenharmony_ci return err_closed(); 10127db96d56Sopenharmony_ci if (!self->writable) 10137db96d56Sopenharmony_ci return err_mode("writing"); 10147db96d56Sopenharmony_ci 10157db96d56Sopenharmony_ci if (posobj == Py_None) { 10167db96d56Sopenharmony_ci /* Get the current position. */ 10177db96d56Sopenharmony_ci posobj = portable_lseek(self, NULL, 1, false); 10187db96d56Sopenharmony_ci if (posobj == NULL) 10197db96d56Sopenharmony_ci return NULL; 10207db96d56Sopenharmony_ci } 10217db96d56Sopenharmony_ci else { 10227db96d56Sopenharmony_ci Py_INCREF(posobj); 10237db96d56Sopenharmony_ci } 10247db96d56Sopenharmony_ci 10257db96d56Sopenharmony_ci#if defined(HAVE_LARGEFILE_SUPPORT) 10267db96d56Sopenharmony_ci pos = PyLong_AsLongLong(posobj); 10277db96d56Sopenharmony_ci#else 10287db96d56Sopenharmony_ci pos = PyLong_AsLong(posobj); 10297db96d56Sopenharmony_ci#endif 10307db96d56Sopenharmony_ci if (PyErr_Occurred()){ 10317db96d56Sopenharmony_ci Py_DECREF(posobj); 10327db96d56Sopenharmony_ci return NULL; 10337db96d56Sopenharmony_ci } 10347db96d56Sopenharmony_ci 10357db96d56Sopenharmony_ci Py_BEGIN_ALLOW_THREADS 10367db96d56Sopenharmony_ci _Py_BEGIN_SUPPRESS_IPH 10377db96d56Sopenharmony_ci errno = 0; 10387db96d56Sopenharmony_ci#ifdef MS_WINDOWS 10397db96d56Sopenharmony_ci ret = _chsize_s(fd, pos); 10407db96d56Sopenharmony_ci#else 10417db96d56Sopenharmony_ci ret = ftruncate(fd, pos); 10427db96d56Sopenharmony_ci#endif 10437db96d56Sopenharmony_ci _Py_END_SUPPRESS_IPH 10447db96d56Sopenharmony_ci Py_END_ALLOW_THREADS 10457db96d56Sopenharmony_ci 10467db96d56Sopenharmony_ci if (ret != 0) { 10477db96d56Sopenharmony_ci Py_DECREF(posobj); 10487db96d56Sopenharmony_ci PyErr_SetFromErrno(PyExc_OSError); 10497db96d56Sopenharmony_ci return NULL; 10507db96d56Sopenharmony_ci } 10517db96d56Sopenharmony_ci 10527db96d56Sopenharmony_ci return posobj; 10537db96d56Sopenharmony_ci} 10547db96d56Sopenharmony_ci#endif /* HAVE_FTRUNCATE */ 10557db96d56Sopenharmony_ci 10567db96d56Sopenharmony_cistatic const char * 10577db96d56Sopenharmony_cimode_string(fileio *self) 10587db96d56Sopenharmony_ci{ 10597db96d56Sopenharmony_ci if (self->created) { 10607db96d56Sopenharmony_ci if (self->readable) 10617db96d56Sopenharmony_ci return "xb+"; 10627db96d56Sopenharmony_ci else 10637db96d56Sopenharmony_ci return "xb"; 10647db96d56Sopenharmony_ci } 10657db96d56Sopenharmony_ci if (self->appending) { 10667db96d56Sopenharmony_ci if (self->readable) 10677db96d56Sopenharmony_ci return "ab+"; 10687db96d56Sopenharmony_ci else 10697db96d56Sopenharmony_ci return "ab"; 10707db96d56Sopenharmony_ci } 10717db96d56Sopenharmony_ci else if (self->readable) { 10727db96d56Sopenharmony_ci if (self->writable) 10737db96d56Sopenharmony_ci return "rb+"; 10747db96d56Sopenharmony_ci else 10757db96d56Sopenharmony_ci return "rb"; 10767db96d56Sopenharmony_ci } 10777db96d56Sopenharmony_ci else 10787db96d56Sopenharmony_ci return "wb"; 10797db96d56Sopenharmony_ci} 10807db96d56Sopenharmony_ci 10817db96d56Sopenharmony_cistatic PyObject * 10827db96d56Sopenharmony_cifileio_repr(fileio *self) 10837db96d56Sopenharmony_ci{ 10847db96d56Sopenharmony_ci PyObject *nameobj, *res; 10857db96d56Sopenharmony_ci 10867db96d56Sopenharmony_ci if (self->fd < 0) 10877db96d56Sopenharmony_ci return PyUnicode_FromFormat("<_io.FileIO [closed]>"); 10887db96d56Sopenharmony_ci 10897db96d56Sopenharmony_ci if (_PyObject_LookupAttr((PyObject *) self, &_Py_ID(name), &nameobj) < 0) { 10907db96d56Sopenharmony_ci return NULL; 10917db96d56Sopenharmony_ci } 10927db96d56Sopenharmony_ci if (nameobj == NULL) { 10937db96d56Sopenharmony_ci res = PyUnicode_FromFormat( 10947db96d56Sopenharmony_ci "<_io.FileIO fd=%d mode='%s' closefd=%s>", 10957db96d56Sopenharmony_ci self->fd, mode_string(self), self->closefd ? "True" : "False"); 10967db96d56Sopenharmony_ci } 10977db96d56Sopenharmony_ci else { 10987db96d56Sopenharmony_ci int status = Py_ReprEnter((PyObject *)self); 10997db96d56Sopenharmony_ci res = NULL; 11007db96d56Sopenharmony_ci if (status == 0) { 11017db96d56Sopenharmony_ci res = PyUnicode_FromFormat( 11027db96d56Sopenharmony_ci "<_io.FileIO name=%R mode='%s' closefd=%s>", 11037db96d56Sopenharmony_ci nameobj, mode_string(self), self->closefd ? "True" : "False"); 11047db96d56Sopenharmony_ci Py_ReprLeave((PyObject *)self); 11057db96d56Sopenharmony_ci } 11067db96d56Sopenharmony_ci else if (status > 0) { 11077db96d56Sopenharmony_ci PyErr_Format(PyExc_RuntimeError, 11087db96d56Sopenharmony_ci "reentrant call inside %s.__repr__", 11097db96d56Sopenharmony_ci Py_TYPE(self)->tp_name); 11107db96d56Sopenharmony_ci } 11117db96d56Sopenharmony_ci Py_DECREF(nameobj); 11127db96d56Sopenharmony_ci } 11137db96d56Sopenharmony_ci return res; 11147db96d56Sopenharmony_ci} 11157db96d56Sopenharmony_ci 11167db96d56Sopenharmony_ci/*[clinic input] 11177db96d56Sopenharmony_ci_io.FileIO.isatty 11187db96d56Sopenharmony_ci 11197db96d56Sopenharmony_ciTrue if the file is connected to a TTY device. 11207db96d56Sopenharmony_ci[clinic start generated code]*/ 11217db96d56Sopenharmony_ci 11227db96d56Sopenharmony_cistatic PyObject * 11237db96d56Sopenharmony_ci_io_FileIO_isatty_impl(fileio *self) 11247db96d56Sopenharmony_ci/*[clinic end generated code: output=932c39924e9a8070 input=cd94ca1f5e95e843]*/ 11257db96d56Sopenharmony_ci{ 11267db96d56Sopenharmony_ci long res; 11277db96d56Sopenharmony_ci 11287db96d56Sopenharmony_ci if (self->fd < 0) 11297db96d56Sopenharmony_ci return err_closed(); 11307db96d56Sopenharmony_ci Py_BEGIN_ALLOW_THREADS 11317db96d56Sopenharmony_ci _Py_BEGIN_SUPPRESS_IPH 11327db96d56Sopenharmony_ci res = isatty(self->fd); 11337db96d56Sopenharmony_ci _Py_END_SUPPRESS_IPH 11347db96d56Sopenharmony_ci Py_END_ALLOW_THREADS 11357db96d56Sopenharmony_ci return PyBool_FromLong(res); 11367db96d56Sopenharmony_ci} 11377db96d56Sopenharmony_ci 11387db96d56Sopenharmony_ci#include "clinic/fileio.c.h" 11397db96d56Sopenharmony_ci 11407db96d56Sopenharmony_cistatic PyMethodDef fileio_methods[] = { 11417db96d56Sopenharmony_ci _IO_FILEIO_READ_METHODDEF 11427db96d56Sopenharmony_ci _IO_FILEIO_READALL_METHODDEF 11437db96d56Sopenharmony_ci _IO_FILEIO_READINTO_METHODDEF 11447db96d56Sopenharmony_ci _IO_FILEIO_WRITE_METHODDEF 11457db96d56Sopenharmony_ci _IO_FILEIO_SEEK_METHODDEF 11467db96d56Sopenharmony_ci _IO_FILEIO_TELL_METHODDEF 11477db96d56Sopenharmony_ci _IO_FILEIO_TRUNCATE_METHODDEF 11487db96d56Sopenharmony_ci _IO_FILEIO_CLOSE_METHODDEF 11497db96d56Sopenharmony_ci _IO_FILEIO_SEEKABLE_METHODDEF 11507db96d56Sopenharmony_ci _IO_FILEIO_READABLE_METHODDEF 11517db96d56Sopenharmony_ci _IO_FILEIO_WRITABLE_METHODDEF 11527db96d56Sopenharmony_ci _IO_FILEIO_FILENO_METHODDEF 11537db96d56Sopenharmony_ci _IO_FILEIO_ISATTY_METHODDEF 11547db96d56Sopenharmony_ci {"_dealloc_warn", (PyCFunction)fileio_dealloc_warn, METH_O, NULL}, 11557db96d56Sopenharmony_ci {NULL, NULL} /* sentinel */ 11567db96d56Sopenharmony_ci}; 11577db96d56Sopenharmony_ci 11587db96d56Sopenharmony_ci/* 'closed' and 'mode' are attributes for backwards compatibility reasons. */ 11597db96d56Sopenharmony_ci 11607db96d56Sopenharmony_cistatic PyObject * 11617db96d56Sopenharmony_ciget_closed(fileio *self, void *closure) 11627db96d56Sopenharmony_ci{ 11637db96d56Sopenharmony_ci return PyBool_FromLong((long)(self->fd < 0)); 11647db96d56Sopenharmony_ci} 11657db96d56Sopenharmony_ci 11667db96d56Sopenharmony_cistatic PyObject * 11677db96d56Sopenharmony_ciget_closefd(fileio *self, void *closure) 11687db96d56Sopenharmony_ci{ 11697db96d56Sopenharmony_ci return PyBool_FromLong((long)(self->closefd)); 11707db96d56Sopenharmony_ci} 11717db96d56Sopenharmony_ci 11727db96d56Sopenharmony_cistatic PyObject * 11737db96d56Sopenharmony_ciget_mode(fileio *self, void *closure) 11747db96d56Sopenharmony_ci{ 11757db96d56Sopenharmony_ci return PyUnicode_FromString(mode_string(self)); 11767db96d56Sopenharmony_ci} 11777db96d56Sopenharmony_ci 11787db96d56Sopenharmony_cistatic PyGetSetDef fileio_getsetlist[] = { 11797db96d56Sopenharmony_ci {"closed", (getter)get_closed, NULL, "True if the file is closed"}, 11807db96d56Sopenharmony_ci {"closefd", (getter)get_closefd, NULL, 11817db96d56Sopenharmony_ci "True if the file descriptor will be closed by close()."}, 11827db96d56Sopenharmony_ci {"mode", (getter)get_mode, NULL, "String giving the file mode"}, 11837db96d56Sopenharmony_ci {NULL}, 11847db96d56Sopenharmony_ci}; 11857db96d56Sopenharmony_ci 11867db96d56Sopenharmony_cistatic PyMemberDef fileio_members[] = { 11877db96d56Sopenharmony_ci {"_blksize", T_UINT, offsetof(fileio, blksize), 0}, 11887db96d56Sopenharmony_ci {"_finalizing", T_BOOL, offsetof(fileio, finalizing), 0}, 11897db96d56Sopenharmony_ci {NULL} 11907db96d56Sopenharmony_ci}; 11917db96d56Sopenharmony_ci 11927db96d56Sopenharmony_ciPyTypeObject PyFileIO_Type = { 11937db96d56Sopenharmony_ci PyVarObject_HEAD_INIT(NULL, 0) 11947db96d56Sopenharmony_ci "_io.FileIO", 11957db96d56Sopenharmony_ci sizeof(fileio), 11967db96d56Sopenharmony_ci 0, 11977db96d56Sopenharmony_ci (destructor)fileio_dealloc, /* tp_dealloc */ 11987db96d56Sopenharmony_ci 0, /* tp_vectorcall_offset */ 11997db96d56Sopenharmony_ci 0, /* tp_getattr */ 12007db96d56Sopenharmony_ci 0, /* tp_setattr */ 12017db96d56Sopenharmony_ci 0, /* tp_as_async */ 12027db96d56Sopenharmony_ci (reprfunc)fileio_repr, /* tp_repr */ 12037db96d56Sopenharmony_ci 0, /* tp_as_number */ 12047db96d56Sopenharmony_ci 0, /* tp_as_sequence */ 12057db96d56Sopenharmony_ci 0, /* tp_as_mapping */ 12067db96d56Sopenharmony_ci 0, /* tp_hash */ 12077db96d56Sopenharmony_ci 0, /* tp_call */ 12087db96d56Sopenharmony_ci 0, /* tp_str */ 12097db96d56Sopenharmony_ci PyObject_GenericGetAttr, /* tp_getattro */ 12107db96d56Sopenharmony_ci 0, /* tp_setattro */ 12117db96d56Sopenharmony_ci 0, /* tp_as_buffer */ 12127db96d56Sopenharmony_ci Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE 12137db96d56Sopenharmony_ci | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 12147db96d56Sopenharmony_ci _io_FileIO___init____doc__, /* tp_doc */ 12157db96d56Sopenharmony_ci (traverseproc)fileio_traverse, /* tp_traverse */ 12167db96d56Sopenharmony_ci (inquiry)fileio_clear, /* tp_clear */ 12177db96d56Sopenharmony_ci 0, /* tp_richcompare */ 12187db96d56Sopenharmony_ci offsetof(fileio, weakreflist), /* tp_weaklistoffset */ 12197db96d56Sopenharmony_ci 0, /* tp_iter */ 12207db96d56Sopenharmony_ci 0, /* tp_iternext */ 12217db96d56Sopenharmony_ci fileio_methods, /* tp_methods */ 12227db96d56Sopenharmony_ci fileio_members, /* tp_members */ 12237db96d56Sopenharmony_ci fileio_getsetlist, /* tp_getset */ 12247db96d56Sopenharmony_ci 0, /* tp_base */ 12257db96d56Sopenharmony_ci 0, /* tp_dict */ 12267db96d56Sopenharmony_ci 0, /* tp_descr_get */ 12277db96d56Sopenharmony_ci 0, /* tp_descr_set */ 12287db96d56Sopenharmony_ci offsetof(fileio, dict), /* tp_dictoffset */ 12297db96d56Sopenharmony_ci _io_FileIO___init__, /* tp_init */ 12307db96d56Sopenharmony_ci PyType_GenericAlloc, /* tp_alloc */ 12317db96d56Sopenharmony_ci fileio_new, /* tp_new */ 12327db96d56Sopenharmony_ci PyObject_GC_Del, /* tp_free */ 12337db96d56Sopenharmony_ci 0, /* tp_is_gc */ 12347db96d56Sopenharmony_ci 0, /* tp_bases */ 12357db96d56Sopenharmony_ci 0, /* tp_mro */ 12367db96d56Sopenharmony_ci 0, /* tp_cache */ 12377db96d56Sopenharmony_ci 0, /* tp_subclasses */ 12387db96d56Sopenharmony_ci 0, /* tp_weaklist */ 12397db96d56Sopenharmony_ci 0, /* tp_del */ 12407db96d56Sopenharmony_ci 0, /* tp_version_tag */ 12417db96d56Sopenharmony_ci 0, /* tp_finalize */ 12427db96d56Sopenharmony_ci}; 1243