mirror of
https://github.com/python/cpython.git
synced 2024-11-23 09:54:58 +08:00
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:
|
if self._fd >= 0:
|
||||||
# Have to close the existing file first.
|
# Have to close the existing file first.
|
||||||
|
self._stat_atopen = None
|
||||||
try:
|
try:
|
||||||
if self._closefd:
|
if self._closefd:
|
||||||
os.close(self._fd)
|
os.close(self._fd)
|
||||||
@ -1583,6 +1584,7 @@ class FileIO(RawIOBase):
|
|||||||
if e.errno != errno.ESPIPE:
|
if e.errno != errno.ESPIPE:
|
||||||
raise
|
raise
|
||||||
except:
|
except:
|
||||||
|
self._stat_atopen = None
|
||||||
if owned_fd is not None:
|
if owned_fd is not None:
|
||||||
os.close(owned_fd)
|
os.close(owned_fd)
|
||||||
raise
|
raise
|
||||||
@ -1756,6 +1758,7 @@ class FileIO(RawIOBase):
|
|||||||
called more than once without error.
|
called more than once without error.
|
||||||
"""
|
"""
|
||||||
if not self.closed:
|
if not self.closed:
|
||||||
|
self._stat_atopen = None
|
||||||
try:
|
try:
|
||||||
if self._closefd:
|
if self._closefd:
|
||||||
os.close(self._fd)
|
os.close(self._fd)
|
||||||
|
@ -131,6 +131,8 @@ internal_close(fileio *self)
|
|||||||
_Py_END_SUPPRESS_IPH
|
_Py_END_SUPPRESS_IPH
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
}
|
}
|
||||||
|
PyMem_Free(self->stat_atopen);
|
||||||
|
self->stat_atopen = NULL;
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
errno = save_errno;
|
errno = save_errno;
|
||||||
PyErr_SetFromErrno(PyExc_OSError);
|
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->fd >= 0) {
|
||||||
if (self->closefd) {
|
if (self->closefd) {
|
||||||
/* Have to close the existing file first. */
|
/* Have to close the existing file first. */
|
||||||
if (internal_close(self) < 0)
|
if (internal_close(self) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
self->fd = -1;
|
self->fd = -1;
|
||||||
@ -523,10 +526,8 @@ _io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode,
|
|||||||
internal_close(self);
|
internal_close(self);
|
||||||
_PyErr_ChainExceptions1(exc);
|
_PyErr_ChainExceptions1(exc);
|
||||||
}
|
}
|
||||||
if (self->stat_atopen != NULL) {
|
PyMem_Free(self->stat_atopen);
|
||||||
PyMem_Free(self->stat_atopen);
|
self->stat_atopen = NULL;
|
||||||
self->stat_atopen = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
done:
|
done:
|
||||||
#ifdef MS_WINDOWS
|
#ifdef MS_WINDOWS
|
||||||
|
Loading…
Reference in New Issue
Block a user