summaryrefslogtreecommitdiffstats
path: root/Modules/_io
diff options
context:
space:
mode:
authorSteve Dower <steve.dower@microsoft.com>2015-02-21 16:44:05 (GMT)
committerSteve Dower <steve.dower@microsoft.com>2015-02-21 16:44:05 (GMT)
commitf2f373f5931be48efc3f6fa2c2faa1cca79dce75 (patch)
tree87facdec6423b6282ad5c4e2cf30e124d4a5de40 /Modules/_io
parent18d1924987d75ef43a429fe4b6f05df2c308ec2a (diff)
downloadcpython-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.c46
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)