~ubuntuone-pqm-team/python-cffi/stable

« back to all changes in this revision

Viewing changes to demo/readdir2.py

  • Committer: Ricardo Kirkner
  • Date: 2015-03-27 18:39:55 UTC
  • Revision ID: ricardo.kirkner@canonical.com-20150327183955-nw7tunfwxjfnxn9s
Tags: 0.9.2
imported cffi 0.9.2 from tarball

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# A Linux-only demo, using verify() instead of hard-coding the exact layouts
 
2
#
 
3
import sys
 
4
from cffi import FFI
 
5
 
 
6
if not sys.platform.startswith('linux'):
 
7
    raise Exception("Linux-only demo")
 
8
 
 
9
 
 
10
ffi = FFI()
 
11
ffi.cdef("""
 
12
 
 
13
    typedef ... DIR;
 
14
 
 
15
    struct dirent {
 
16
        unsigned char  d_type;      /* type of file; not supported
 
17
                                       by all file system types */
 
18
        char           d_name[...]; /* filename */
 
19
        ...;
 
20
    };
 
21
 
 
22
    int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result);
 
23
    int openat(int dirfd, const char *pathname, int flags);
 
24
    DIR *fdopendir(int fd);
 
25
    int closedir(DIR *dirp);
 
26
 
 
27
    static const int DT_DIR;
 
28
 
 
29
""")
 
30
ffi.C = ffi.verify("""
 
31
#ifndef _ATFILE_SOURCE
 
32
#  define _ATFILE_SOURCE
 
33
#endif
 
34
#ifndef _BSD_SOURCE
 
35
#  define _BSD_SOURCE
 
36
#endif
 
37
#include <fcntl.h>
 
38
#include <sys/types.h>
 
39
#include <dirent.h>
 
40
""")
 
41
 
 
42
 
 
43
def walk(basefd, path):
 
44
    print '{', path
 
45
    dirfd = ffi.C.openat(basefd, path, 0)
 
46
    if dirfd < 0:
 
47
        # error in openat()
 
48
        return
 
49
    dir = ffi.C.fdopendir(dirfd)
 
50
    dirent = ffi.new("struct dirent *")
 
51
    result = ffi.new("struct dirent **")
 
52
    while True:
 
53
        if ffi.C.readdir_r(dir, dirent, result):
 
54
            # error in readdir_r()
 
55
            break
 
56
        if result[0] == ffi.NULL:
 
57
            break
 
58
        name = ffi.string(dirent.d_name)
 
59
        print '%3d %s' % (dirent.d_type, name)
 
60
        if dirent.d_type == ffi.C.DT_DIR and name != '.' and name != '..':
 
61
            walk(dirfd, name)
 
62
    ffi.C.closedir(dir)
 
63
    print '}'
 
64
 
 
65
 
 
66
walk(-1, "/tmp")