Commit fd625c39 authored by Serhiy Storchaka's avatar Serhiy Storchaka

Issue #26117: The os.scandir() iterator now closes file descriptor not only

when the iteration is finished, but when it was failed with error.
parents d2962f14 988b9bcd
...@@ -170,6 +170,9 @@ Core and Builtins ...@@ -170,6 +170,9 @@ Core and Builtins
Library Library
------- -------
- Issue #26117: The os.scandir() iterator now closes file descriptor not only
when the iteration is finished, but when it was failed with error.
- Issue #25949: __dict__ for an OrderedDict instance is now created only when - Issue #25949: __dict__ for an OrderedDict instance is now created only when
needed. needed.
......
...@@ -11954,12 +11954,11 @@ ScandirIterator_iternext(ScandirIterator *iterator) ...@@ -11954,12 +11954,11 @@ ScandirIterator_iternext(ScandirIterator *iterator)
{ {
WIN32_FIND_DATAW *file_data = &iterator->file_data; WIN32_FIND_DATAW *file_data = &iterator->file_data;
BOOL success; BOOL success;
PyObject *entry;
/* Happens if the iterator is iterated twice */ /* Happens if the iterator is iterated twice */
if (iterator->handle == INVALID_HANDLE_VALUE) { if (iterator->handle == INVALID_HANDLE_VALUE)
PyErr_SetNone(PyExc_StopIteration);
return NULL; return NULL;
}
while (1) { while (1) {
if (!iterator->first_time) { if (!iterator->first_time) {
...@@ -11967,9 +11966,9 @@ ScandirIterator_iternext(ScandirIterator *iterator) ...@@ -11967,9 +11966,9 @@ ScandirIterator_iternext(ScandirIterator *iterator)
success = FindNextFileW(iterator->handle, file_data); success = FindNextFileW(iterator->handle, file_data);
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
if (!success) { if (!success) {
/* Error or no more files */
if (GetLastError() != ERROR_NO_MORE_FILES) if (GetLastError() != ERROR_NO_MORE_FILES)
return path_error(&iterator->path); path_error(&iterator->path);
/* No more files found in directory, stop iterating */
break; break;
} }
} }
...@@ -11977,15 +11976,18 @@ ScandirIterator_iternext(ScandirIterator *iterator) ...@@ -11977,15 +11976,18 @@ ScandirIterator_iternext(ScandirIterator *iterator)
/* Skip over . and .. */ /* Skip over . and .. */
if (wcscmp(file_data->cFileName, L".") != 0 && if (wcscmp(file_data->cFileName, L".") != 0 &&
wcscmp(file_data->cFileName, L"..") != 0) wcscmp(file_data->cFileName, L"..") != 0) {
return DirEntry_from_find_data(&iterator->path, file_data); entry = DirEntry_from_find_data(&iterator->path, file_data);
if (!entry)
break;
return entry;
}
/* Loop till we get a non-dot directory or finish iterating */ /* Loop till we get a non-dot directory or finish iterating */
} }
/* Error or no more files */
ScandirIterator_close(iterator); ScandirIterator_close(iterator);
PyErr_SetNone(PyExc_StopIteration);
return NULL; return NULL;
} }
...@@ -12010,12 +12012,11 @@ ScandirIterator_iternext(ScandirIterator *iterator) ...@@ -12010,12 +12012,11 @@ ScandirIterator_iternext(ScandirIterator *iterator)
struct dirent *direntp; struct dirent *direntp;
Py_ssize_t name_len; Py_ssize_t name_len;
int is_dot; int is_dot;
PyObject *entry;
/* Happens if the iterator is iterated twice */ /* Happens if the iterator is iterated twice */
if (!iterator->dirp) { if (!iterator->dirp)
PyErr_SetNone(PyExc_StopIteration);
return NULL; return NULL;
}
while (1) { while (1) {
errno = 0; errno = 0;
...@@ -12024,9 +12025,9 @@ ScandirIterator_iternext(ScandirIterator *iterator) ...@@ -12024,9 +12025,9 @@ ScandirIterator_iternext(ScandirIterator *iterator)
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
if (!direntp) { if (!direntp) {
/* Error or no more files */
if (errno != 0) if (errno != 0)
return path_error(&iterator->path); path_error(&iterator->path);
/* No more files found in directory, stop iterating */
break; break;
} }
...@@ -12035,20 +12036,22 @@ ScandirIterator_iternext(ScandirIterator *iterator) ...@@ -12035,20 +12036,22 @@ ScandirIterator_iternext(ScandirIterator *iterator)
is_dot = direntp->d_name[0] == '.' && is_dot = direntp->d_name[0] == '.' &&
(name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2)); (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
if (!is_dot) { if (!is_dot) {
return DirEntry_from_posix_info(&iterator->path, direntp->d_name, entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
name_len, direntp->d_ino name_len, direntp->d_ino
#ifdef HAVE_DIRENT_D_TYPE #ifdef HAVE_DIRENT_D_TYPE
, direntp->d_type , direntp->d_type
#endif #endif
); );
if (!entry)
break;
return entry;
} }
/* Loop till we get a non-dot directory or finish iterating */ /* Loop till we get a non-dot directory or finish iterating */
} }
/* Error or no more files */
ScandirIterator_close(iterator); ScandirIterator_close(iterator);
PyErr_SetNone(PyExc_StopIteration);
return NULL; return NULL;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment