diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2016-02-08 15:56:36 (GMT) |
---|---|---|
committer | Serhiy Storchaka <storchaka@gmail.com> | 2016-02-08 15:56:36 (GMT) |
commit | 988b9bcd881c21286d0bce64009c8b5afa50da8e (patch) | |
tree | 3a32c66a3e117347b002c22247ec166caf64c8ad | |
parent | 5f6a0b4eb26695be759cd32e49e83f38b5123ce6 (diff) | |
download | cpython-988b9bcd881c21286d0bce64009c8b5afa50da8e.zip cpython-988b9bcd881c21286d0bce64009c8b5afa50da8e.tar.gz cpython-988b9bcd881c21286d0bce64009c8b5afa50da8e.tar.bz2 |
Issue #26117: The os.scandir() iterator now closes file descriptor not only
when the iteration is finished, but when it was failed with error.
-rw-r--r-- | Misc/NEWS | 3 | ||||
-rw-r--r-- | Modules/posixmodule.c | 37 |
2 files changed, 23 insertions, 17 deletions
@@ -73,6 +73,9 @@ Core and Builtins 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 #25911: Restored support of bytes paths in os.walk() on Windows. - Issue #26045: Add UTF-8 suggestion to error message when posting a diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index e4b27a7..710bcde 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -11942,12 +11942,11 @@ ScandirIterator_iternext(ScandirIterator *iterator) { WIN32_FIND_DATAW *file_data = &iterator->file_data; BOOL success; + PyObject *entry; /* Happens if the iterator is iterated twice */ - if (iterator->handle == INVALID_HANDLE_VALUE) { - PyErr_SetNone(PyExc_StopIteration); + if (iterator->handle == INVALID_HANDLE_VALUE) return NULL; - } while (1) { if (!iterator->first_time) { @@ -11955,9 +11954,9 @@ ScandirIterator_iternext(ScandirIterator *iterator) success = FindNextFileW(iterator->handle, file_data); Py_END_ALLOW_THREADS if (!success) { + /* Error or no more files */ if (GetLastError() != ERROR_NO_MORE_FILES) - return path_error(&iterator->path); - /* No more files found in directory, stop iterating */ + path_error(&iterator->path); break; } } @@ -11965,15 +11964,18 @@ ScandirIterator_iternext(ScandirIterator *iterator) /* Skip over . and .. */ if (wcscmp(file_data->cFileName, L".") != 0 && - wcscmp(file_data->cFileName, L"..") != 0) - return DirEntry_from_find_data(&iterator->path, file_data); + wcscmp(file_data->cFileName, L"..") != 0) { + 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 */ } + /* Error or no more files */ ScandirIterator_close(iterator); - - PyErr_SetNone(PyExc_StopIteration); return NULL; } @@ -11998,12 +12000,11 @@ ScandirIterator_iternext(ScandirIterator *iterator) struct dirent *direntp; Py_ssize_t name_len; int is_dot; + PyObject *entry; /* Happens if the iterator is iterated twice */ - if (!iterator->dirp) { - PyErr_SetNone(PyExc_StopIteration); + if (!iterator->dirp) return NULL; - } while (1) { errno = 0; @@ -12012,9 +12013,9 @@ ScandirIterator_iternext(ScandirIterator *iterator) Py_END_ALLOW_THREADS if (!direntp) { + /* Error or no more files */ if (errno != 0) - return path_error(&iterator->path); - /* No more files found in directory, stop iterating */ + path_error(&iterator->path); break; } @@ -12023,20 +12024,22 @@ ScandirIterator_iternext(ScandirIterator *iterator) is_dot = direntp->d_name[0] == '.' && (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2)); 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 #ifdef HAVE_DIRENT_D_TYPE , direntp->d_type #endif ); + if (!entry) + break; + return entry; } /* Loop till we get a non-dot directory or finish iterating */ } + /* Error or no more files */ ScandirIterator_close(iterator); - - PyErr_SetNone(PyExc_StopIteration); return NULL; } |