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