blob: 4fd1d176df5a485e60c3720754c19f84b1174229 [file] [log] [blame]
# 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")