diff options
author | Steve Dower <steve.dower@microsoft.com> | 2015-02-21 16:44:05 (GMT) |
---|---|---|
committer | Steve Dower <steve.dower@microsoft.com> | 2015-02-21 16:44:05 (GMT) |
commit | f2f373f5931be48efc3f6fa2c2faa1cca79dce75 (patch) | |
tree | 87facdec6423b6282ad5c4e2cf30e124d4a5de40 /Modules/_io | |
parent | 18d1924987d75ef43a429fe4b6f05df2c308ec2a (diff) | |
download | cpython-f2f373f5931be48efc3f6fa2c2faa1cca79dce75.zip cpython-f2f373f5931be48efc3f6fa2c2faa1cca79dce75.tar.gz cpython-f2f373f5931be48efc3f6fa2c2faa1cca79dce75.tar.bz2 |
Issue #23152: Implement _Py_fstat() to support files larger than 2 GB on Windows.
fstat() may fail with EOVERFLOW on files larger than 2 GB because the file size type is an signed 32-bit integer.
Diffstat (limited to 'Modules/_io')
-rw-r--r-- | Modules/_io/fileio.c | 46 |
1 files changed, 24 insertions, 22 deletions
diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c index 9c67394..ff88e40 100644 --- a/Modules/_io/fileio.c +++ b/Modules/_io/fileio.c @@ -180,9 +180,9 @@ fileio_new(PyTypeObject *type, PyObject *args, PyObject *kwds) static int check_fd(int fd) { -#if defined(HAVE_FSTAT) - struct stat buf; - if (!_PyVerify_fd(fd) || (fstat(fd, &buf) < 0 && errno == EBADF)) { +#if defined(HAVE_FSTAT) || defined(MS_WINDOWS) + struct _Py_stat_struct buf; + if (!_PyVerify_fd(fd) || (_Py_fstat(fd, &buf) < 0 && errno == EBADF)) { PyObject *exc; char *msg = strerror(EBADF); exc = PyObject_CallFunction(PyExc_OSError, "(is)", @@ -222,8 +222,8 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds) #elif !defined(MS_WINDOWS) int *atomic_flag_works = NULL; #endif -#ifdef HAVE_FSTAT - struct stat fdfstat; +#if defined(HAVE_FSTAT) || defined(MS_WINDOWS) + struct _Py_stat_struct fdfstat; #endif int async_err = 0; @@ -420,9 +420,11 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds) } self->blksize = DEFAULT_BUFFER_SIZE; -#ifdef HAVE_FSTAT - if (fstat(self->fd, &fdfstat) < 0) +#if defined(HAVE_FSTAT) || defined(MS_WINDOWS) + if (_Py_fstat(self->fd, &fdfstat) < 0) { + PyErr_SetFromErrno(PyExc_OSError); goto error; + } #if defined(S_ISDIR) && defined(EISDIR) /* On Unix, open will succeed for directories. In Python, there should be no file objects referring to @@ -437,7 +439,7 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds) if (fdfstat.st_blksize > 1) self->blksize = fdfstat.st_blksize; #endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */ -#endif /* HAVE_FSTAT */ +#endif /* HAVE_FSTAT || MS_WINDOWS */ #if defined(MS_WINDOWS) || defined(__CYGWIN__) /* don't translate newlines (\r\n <=> \n) */ @@ -603,17 +605,7 @@ fileio_readinto(fileio *self, PyObject *args) return PyLong_FromSsize_t(n); } -#ifndef HAVE_FSTAT - -static PyObject * -fileio_readall(fileio *self) -{ - _Py_IDENTIFIER(readall); - return _PyObject_CallMethodId((PyObject*)&PyRawIOBase_Type, - &PyId_readall, "O", self); -} - -#else +#if defined(HAVE_FSTAT) || defined(MS_WINDOWS) static size_t new_buffersize(fileio *self, size_t currentsize) @@ -637,7 +629,7 @@ new_buffersize(fileio *self, size_t currentsize) static PyObject * fileio_readall(fileio *self) { - struct stat st; + struct _Py_stat_struct st; Py_off_t pos, end; PyObject *result; Py_ssize_t bytes_read = 0; @@ -655,7 +647,7 @@ fileio_readall(fileio *self) #else pos = lseek(self->fd, 0L, SEEK_CUR); #endif - if (fstat(self->fd, &st) == 0) + if (_Py_fstat(self->fd, &st) == 0) end = st.st_size; else end = (Py_off_t)-1; @@ -729,7 +721,17 @@ fileio_readall(fileio *self) return result; } -#endif /* HAVE_FSTAT */ +#else + +static PyObject * +fileio_readall(fileio *self) +{ + _Py_IDENTIFIER(readall); + return _PyObject_CallMethodId((PyObject*)&PyRawIOBase_Type, + &PyId_readall, "O", self); +} + +#endif /* HAVE_FSTAT || MS_WINDOWS */ static PyObject * fileio_read(fileio *self, PyObject *args) |