1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
# 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")
|