Eryk Sun <eryk...@gmail.com> added the comment:
Assign an errcheck function to check the return value and raise an OSError exception on failure. Load the C library with use_errno=True to get the value of C errno. Make sure to properly handle encoding Unicode strings for the file-system encoding, including conversion of __fspath__ paths (e.g. 3.x pathlib). Finally, don't load libraries and define prototypes in API functions. It's redundant and inefficient. You're just needlessly increasing the loaders reference count on the shared library and needlessly redefining prototypes that never change. Load it once at module or class level. For example: import os import sys import ctypes import ctypes.util import contextlib libc = ctypes.CDLL(ctypes.util.find_library("c"), use_errno=True) class DIR(ctypes.Structure): """Opaque type for directory entries""" PDIR = ctypes.POINTER(DIR) class c_fschar_p(ctypes.c_char_p): if sys.version_info[0] >= 3: @classmethod def from_param(cls, param): if isinstance(param, (str, bytes, os.PathLike)): param = os.fsencode(param) return super().from_param(param) else: @classmethod def from_param(cls, param): if isinstance(param, unicode): param = param.encode(sys.getfilesystemencoding()) return super(c_fschar_p, cls).from_param(param) def check_bool(result, func, args): if not result: err = ctypes.get_errno() raise OSError(err, os.strerror(err)) return args def check_int(result, func, args): if result == -1: err = ctypes.get_errno() raise OSError(err, os.strerror(err)) return args libc.opendir.errcheck = check_bool libc.opendir.argtypes = (c_fschar_p,) libc.opendir.restype = PDIR libc.dirfd.errcheck = check_int libc.dirfd.argtypes = (PDIR,) libc.closedir.errcheck = check_int libc.closedir.argtypes = (PDIR,) @contextlib.contextmanager def get_directory_file_descriptor(directory): dir_p = libc.opendir(directory) try: if __debug__: print("dir_p = %s:%r" % (directory, dir_p)) dir_fd = libc.dirfd(dir_p) if __debug__: print("dir_fd = %r" % dir_fd) yield dir_fd finally: libc.closedir(dir_p) if __debug__: print("closed %r" % dir_p) ---------- nosy: +eryksun _______________________________________ Python tracker <rep...@bugs.python.org> <https://bugs.python.org/issue35180> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com