[pypy-commit] cffi default: Add another example. This one segfaults CPython on a bogus

arigo noreply at buildbot.pypy.org
Sun Jun 17 16:16:59 CEST 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r403:5aff894301f6
Date: 2012-06-17 15:28 +0200
http://bitbucket.org/cffi/cffi/changeset/5aff894301f6/

Log:	Add another example. This one segfaults CPython on a bogus
	reference count issue. Needs to investigate.

diff --git a/demo/bsdopendirtype.py b/demo/bsdopendirtype.py
new file mode 100644
--- /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)


More information about the pypy-commit mailing list