-
-
Notifications
You must be signed in to change notification settings - Fork 34.5k
gh-120754: Ensure _stat_atopen is cleared on fd change #125166
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 10 commits
d57abd0
d2cb365
854ae91
c6da86e
0f64483
e2eebb0
5299a04
d749709
b429587
f08defa
e153d97
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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); | ||
|
|
@@ -178,6 +180,8 @@ _io_FileIO_close_impl(fileio *self, PyTypeObject *cls) | |
| PyErr_Clear(); | ||
| } | ||
| } | ||
| PyMem_Free(self->stat_atopen); | ||
| self->stat_atopen = NULL; | ||
| rc = internal_close(self); | ||
| if (res == NULL) { | ||
| _PyErr_ChainExceptions1(exc); | ||
|
|
@@ -266,10 +270,13 @@ _io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode, | |
| assert(PyFileIO_Check(state, self)); | ||
| #endif | ||
| if (self->fd >= 0) { | ||
| PyMem_Free(self->stat_atopen); | ||
| self->stat_atopen = NULL; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. internal_close() already does the same, so it's redundant, no?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Moderately, in the |
||
| 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; | ||
|
|
@@ -455,7 +462,9 @@ _io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode, | |
| #endif | ||
| } | ||
|
|
||
| PyMem_Free(self->stat_atopen); | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure which is preferred here. The Free + New back to back feels weird, but version with the conditional feels like "extra work/code that should never be executed" (but that the compiler / tools that run currently won't validate...).
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Moved to that, dropped comment and simplified / back to always calling PyMem_New |
||
| if (self->stat_atopen != NULL) { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. PyMem_Free(NULL) is well defined: it does nothing, so you might omit the |
||
| PyMem_Free(self->stat_atopen); | ||
| } | ||
| self->stat_atopen = PyMem_New(struct _Py_stat_struct, 1); | ||
| if (self->stat_atopen == NULL) { | ||
| PyErr_NoMemory(); | ||
|
|
@@ -523,10 +532,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; | ||
|
vstinner marked this conversation as resolved.
|
||
|
|
||
| done: | ||
| #ifdef MS_WINDOWS | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
internal_close() already does the same, so it's redundant, no?
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tradeoff for matching what
_pyiodoes which doesos.close()in these cases vs aninternal_closethat does the OS close + other cleanup. Happy to drop though / definitely feels redundant to me in these two cases.