/*[clinic input] os.scandir path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None Return an iterator of DirEntry objects for given path. path can be specified as either str, bytes, or a path-like object. If path is bytes, the names of yielded DirEntry objects will also be bytes; in all other circumstances they will be str. If path is None, uses the path='.'. [clinic start generated code]*/ static PyObject * os_scandir_impl(PyObject *module, path_t *path) /*[clinic end generated code: output=6eb2668b675ca89e input=6bdd312708fc3bb0]*/ { ScandirIterator *iterator; #ifdef MS_WINDOWS wchar_t *path_strW; #else const char *path_str; #ifdef HAVE_FDOPENDIR int fd = -1; #endif #endif if (PySys_Audit("os.scandir", "O", path->object ? path->object : Py_None) < 0) { return NULL; } PyObject *ScandirIteratorType = get_posix_state(module)->ScandirIteratorType; iterator = PyObject_New(ScandirIterator, (PyTypeObject *)ScandirIteratorType); if (!iterator) return NULL; #ifdef MS_WINDOWS iterator->handle = INVALID_HANDLE_VALUE; #else iterator->dirp = NULL; #endif memcpy(&iterator->path, path, sizeof(path_t)); /* Move the ownership to iterator->path */ path->object = NULL; path->cleanup = NULL; #ifdef MS_WINDOWS iterator->first_time = 1; path_strW = join_path_filenameW(iterator->path.wide, L"*.*"); if (!path_strW) goto error; Py_BEGIN_ALLOW_THREADS iterator->handle = FindFirstFileW(path_strW, &iterator->file_data); Py_END_ALLOW_THREADS PyMem_Free(path_strW); if (iterator->handle == INVALID_HANDLE_VALUE) { path_error(&iterator->path); goto error; } #else /* POSIX */ errno = 0; #ifdef HAVE_FDOPENDIR if (path->fd != -1) { /* closedir() closes the FD, so we duplicate it */ fd = _Py_dup(path->fd); if (fd == -1) goto error; Py_BEGIN_ALLOW_THREADS iterator->dirp = fdopendir(fd); Py_END_ALLOW_THREADS } else #endif { if (iterator->path.narrow) path_str = iterator->path.narrow; else path_str = "."; Py_BEGIN_ALLOW_THREADS iterator->dirp = opendir(path_str); Py_END_ALLOW_THREADS } if (!iterator->dirp) { path_error(&iterator->path); #ifdef HAVE_FDOPENDIR if (fd != -1) { Py_BEGIN_ALLOW_THREADS close(fd); Py_END_ALLOW_THREADS } #endif goto error; } #endif return (PyObject *)iterator; error: Py_DECREF(iterator); return NULL; }