# A Linux-only demo # # For comparison purposes, this is a ctypes version of readdir.py. import sys import ctypes if not sys.platform.startswith('linux'): raise Exception("Linux-only demo") DIR_p = ctypes.c_void_p ino_t = ctypes.c_long off_t = ctypes.c_long class DIRENT(ctypes.Structure): _fields_ = [ ('d_ino', ino_t), # inode number ('d_off', off_t), # offset to the next dirent ('d_reclen', ctypes.c_ushort), # length of this record ('d_type', ctypes.c_ubyte), # type of file; not supported # by all file system types ('d_name', ctypes.c_char * 256), # filename ] DIRENT_p = ctypes.POINTER(DIRENT) DIRENT_pp = ctypes.POINTER(DIRENT_p) C = ctypes.CDLL(None) readdir_r = C.readdir_r readdir_r.argtypes = [DIR_p, DIRENT_p, DIRENT_pp] readdir_r.restype = ctypes.c_int openat = C.openat openat.argtypes = [ctypes.c_int, ctypes.c_char_p, ctypes.c_int] openat.restype = ctypes.c_int fdopendir = C.fdopendir fdopendir.argtypes = [ctypes.c_int] fdopendir.restype = DIR_p closedir = C.closedir closedir.argtypes = [DIR_p] closedir.restype = ctypes.c_int def walk(basefd, path): print '{', path dirfd = openat(basefd, path, 0) if dirfd < 0: # error in openat() return dir = fdopendir(dirfd) dirent = DIRENT() result = DIRENT_p() while True: if readdir_r(dir, dirent, result): # error in readdir_r() break if not result: break name = dirent.d_name print '%3d %s' % (dirent.d_type, name) if dirent.d_type == 4 and name != '.' and name != '..': walk(dirfd, name) closedir(dir) print '}' walk(-1, "/tmp")