e7e4d7
From eafaa2e88f7af16756142a31ab63d032b31395e3 Mon Sep 17 00:00:00 2001
e7e4d7
From: Pádraig Brady <P@draigBrady.com>
e7e4d7
Date: Fri, 06 Nov 2015 16:31:22 +0000
e7e4d7
Subject: tests: fix dirent d_type support verification
e7e4d7
e7e4d7
* tests/d_type-check: Check also the d_type of files,
e7e4d7
which excludes XFS appropriately.  Specify all argument
e7e4d7
and return types to avoid truncated pointers being passed,
e7e4d7
which skipped the test due to crashes on x86_64 at least.
e7e4d7
Simplify the C library lookup by reusing the interpreter's.
e7e4d7
e7e4d7
chroot issue reported at https://bugzilla.redhat.com/1263341
e7e4d7
---
e7e4d7
diff --git a/tests/d_type-check b/tests/d_type-check
e7e4d7
index ff1eb60..1a2f76f 100644
e7e4d7
--- a/tests/d_type-check
e7e4d7
+++ b/tests/d_type-check
e7e4d7
@@ -1,13 +1,17 @@
e7e4d7
 #!/usr/bin/python
e7e4d7
-# Exit 0 if "." has useful d_type information, else 1.
e7e4d7
+# Exit 0 if "." and "./tempfile" have useful d_type information, else 1.
e7e4d7
 # Intended to exit 0 only on Linux/GNU systems.
e7e4d7
+import os
e7e4d7
 import sys
e7e4d7
+import tempfile
e7e4d7
 
e7e4d7
 fail = 1
e7e4d7
+fname = None
e7e4d7
+
e7e4d7
 try:
e7e4d7
   import ctypes
e7e4d7
 
e7e4d7
-  (DT_UNKNOWN, DT_DIR,) = (0, 4,)
e7e4d7
+  (DT_UNKNOWN, DT_DIR, DT_REG) = (0, 4, 8)
e7e4d7
 
e7e4d7
   class dirent(ctypes.Structure):
e7e4d7
     _fields_ = [
e7e4d7
@@ -17,20 +21,48 @@ try:
e7e4d7
       ("d_type", ctypes.c_ubyte),
e7e4d7
       ("d_name", ctypes.c_char*256)]
e7e4d7
 
e7e4d7
+  # Pass NULL to dlopen, assuming the python
e7e4d7
+  # interpreter is linked with the C runtime
e7e4d7
+  libc = ctypes.CDLL(None)
e7e4d7
+
e7e4d7
+  # Setup correct types for all args and returns
e7e4d7
+  # even if only passing, to avoid truncation etc.
e7e4d7
+  dirp = ctypes.c_void_p
e7e4d7
   direntp = ctypes.POINTER(dirent)
e7e4d7
 
e7e4d7
-  # FIXME: find a way to avoid hard-coding libc's so-name.
e7e4d7
-  libc = ctypes.cdll.LoadLibrary("libc.so.6")
e7e4d7
+  libc.readdir.argtypes = [dirp]
e7e4d7
   libc.readdir.restype = direntp
e7e4d7
 
e7e4d7
+  libc.opendir.restype = dirp
e7e4d7
+
e7e4d7
+  # Ensure a file is present
e7e4d7
+  f, fname = tempfile.mkstemp(dir='.')
e7e4d7
+  fname = os.path.basename(fname)
e7e4d7
+
e7e4d7
   dirp = libc.opendir(".")
e7e4d7
   if dirp:
e7e4d7
-    ep = libc.readdir(dirp)
e7e4d7
-    if ep:
e7e4d7
+    while True:
e7e4d7
+      ep = libc.readdir(dirp)
e7e4d7
+      if not ep: break
e7e4d7
+      d_type = ep.contents.d_type
e7e4d7
       name = ep.contents.d_name
e7e4d7
-      if (name == "." or name == "..") and ep.contents.d_type == DT_DIR:
e7e4d7
+      if name == "." or name == "..":
e7e4d7
+        if d_type != DT_DIR: break
e7e4d7
+      # Check files too since on XFS, only dirs have DT_DIR
e7e4d7
+      # while everything else has DT_UNKNOWN
e7e4d7
+      elif name == fname:
e7e4d7
+        if d_type == DT_REG:
e7e4d7
+          fail = 0
e7e4d7
+        break
e7e4d7
+      elif d_type != DT_DIR and d_type != DT_UNKNOWN:
e7e4d7
         fail = 0
e7e4d7
+        break
e7e4d7
+except:
e7e4d7
+  pass
e7e4d7
 
e7e4d7
+try:
e7e4d7
+  if fname:
e7e4d7
+    os.unlink(fname);
e7e4d7
 except:
e7e4d7
   pass
e7e4d7
 
e7e4d7
--
e7e4d7
cgit v0.9.0.2