mirror of https://github.com/python/cpython
gh-120754: _io Ensure stat cache is cleared on fd change (#125166)
Performed an audit of `fileio.c` and `_pyio` and made sure anytime the fd changes the stat result, if set, is also cleared/changed. There's one case where it's not cleared, if code would clear it in __init__, keep the memory allocated and just do another fstat with the existing memory.
This commit is contained in:
parent
c84a136511
commit
72dd4714f9
|
@ -1480,6 +1480,7 @@ class FileIO(RawIOBase):
|
|||
"""
|
||||
if self._fd >= 0:
|
||||
# Have to close the existing file first.
|
||||
self._stat_atopen = None
|
||||
try:
|
||||
if self._closefd:
|
||||
os.close(self._fd)
|
||||
|
@ -1583,6 +1584,7 @@ class FileIO(RawIOBase):
|
|||
if e.errno != errno.ESPIPE:
|
||||
raise
|
||||
except:
|
||||
self._stat_atopen = None
|
||||
if owned_fd is not None:
|
||||
os.close(owned_fd)
|
||||
raise
|
||||
|
@ -1756,6 +1758,7 @@ class FileIO(RawIOBase):
|
|||
called more than once without error.
|
||||
"""
|
||||
if not self.closed:
|
||||
self._stat_atopen = None
|
||||
try:
|
||||
if self._closefd:
|
||||
os.close(self._fd)
|
||||
|
|
|
@ -131,6 +131,8 @@ internal_close(fileio *self)
|
|||
_Py_END_SUPPRESS_IPH
|
||||
Py_END_ALLOW_THREADS
|
||||
}
|
||||
PyMem_Free(self->stat_atopen);
|
||||
self->stat_atopen = NULL;
|
||||
if (err < 0) {
|
||||
errno = save_errno;
|
||||
PyErr_SetFromErrno(PyExc_OSError);
|
||||
|
@ -268,8 +270,9 @@ _io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode,
|
|||
if (self->fd >= 0) {
|
||||
if (self->closefd) {
|
||||
/* Have to close the existing file first. */
|
||||
if (internal_close(self) < 0)
|
||||
if (internal_close(self) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
self->fd = -1;
|
||||
|
@ -523,10 +526,8 @@ _io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode,
|
|||
internal_close(self);
|
||||
_PyErr_ChainExceptions1(exc);
|
||||
}
|
||||
if (self->stat_atopen != NULL) {
|
||||
PyMem_Free(self->stat_atopen);
|
||||
self->stat_atopen = NULL;
|
||||
}
|
||||
PyMem_Free(self->stat_atopen);
|
||||
self->stat_atopen = NULL;
|
||||
|
||||
done:
|
||||
#ifdef MS_WINDOWS
|
||||
|
|
Loading…
Reference in New Issue