diff options
author | Armin Rigo <arigo@tunes.org> | 2012-06-17 15:28:22 +0200 |
---|---|---|
committer | Armin Rigo <arigo@tunes.org> | 2012-06-17 15:28:22 +0200 |
commit | 800fd444c1bcbb277102864cc224b47d08db3887 (patch) | |
tree | 4dfdee562a298e7d94e07f47b97ad8c79624090e /demo | |
parent | be0cf814f049281bb17ee4448c0875b2e473a5f1 (diff) | |
download | cffi-800fd444c1bcbb277102864cc224b47d08db3887.tar.gz |
Add another example. This one segfaults CPython on a bogus
reference count issue. Needs to investigate.
Diffstat (limited to 'demo')
-rw-r--r-- | demo/bsdopendirtype.py | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/demo/bsdopendirtype.py b/demo/bsdopendirtype.py new file mode 100644 index 0000000..6c2dadd --- /dev/null +++ b/demo/bsdopendirtype.py @@ -0,0 +1,62 @@ +from cffi import FFI + +ffi = FFI() +ffi.cdef(""" + typedef ... DIR; + struct dirent { + unsigned char d_type; /* type of file */ + char d_name[]; /* filename */ + ...; + }; + DIR *opendir(const char *name); + int closedir(DIR *dirp); + struct dirent *readdir(DIR *dirp); + static const int DT_BLK, DT_CHR, DT_DIR, DT_FIFO, DT_LNK, DT_REG, DT_SOCK; +""") +lib = ffi.verify(""" + #include <sys/types.h> + #include <dirent.h> +""") + + +def _posix_error(): + raise OSError(ffi.errno, os.strerror(ffi.errno)) + +_dtype_to_smode = { + lib.DT_BLK: 0060000, + lib.DT_CHR: 0020000, + lib.DT_DIR: 0040000, + lib.DT_FIFO: 0010000, + lib.DT_LNK: 0120000, + lib.DT_REG: 0100000, + lib.DT_SOCK: 0140000, +} + +def opendir(dir): + if len(dir) == 0: + dir = '.' + dirname = dir + if not dirname.endswith('/'): + dirname += '/' + dirp = lib.opendir(dir) + if dirp == None: + raise _posix_error() + try: + while True: + ffi.errno = 0 + dirent = lib.readdir(dirp) + if dirent == None: + if ffi.errno != 0: + raise _posix_error() + return + name = str(dirent.d_name) + if name == '.' or name == '..': + continue + name = dirname + name + try: + smode = _dtype_to_smode[dirent.d_type] + except KeyError: + smode = os.lstat(name).st_mode + yield name, smode + finally: + lib.closedir(dirp) |