summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPádraig Brady <P@draigBrady.com>2015-11-06 16:31:22 +0000
committerPádraig Brady <P@draigBrady.com>2015-11-06 16:40:42 +0000
commiteafaa2e88f7af16756142a31ab63d032b31395e3 (patch)
tree59d6311f1d8875becdbff3d064adf70ba56d117f
parentd820706d44f25de3f58ad41a7032997089d15385 (diff)
downloadcoreutils-eafaa2e88f7af16756142a31ab63d032b31395e3.tar.xz
tests: fix dirent d_type support verification
* init.cfg (require_dirent_d_type_): Don't use df -x to exclude XFS, since this depends on a correct mtab which is brittle and often not correct within chroots. * tests/d_type-check: Check also the d_type of files, which excludes XFS appropriately. Specify all argument and return types to avoid truncated pointers being passed, which skipped the test due to crashes on x86_64 at least. Simplify the C library lookup by reusing the interpreter's. chroot issue reported at https://bugzilla.redhat.com/1263341
-rw-r--r--init.cfg6
-rw-r--r--tests/d_type-check45
2 files changed, 39 insertions, 12 deletions
diff --git a/init.cfg b/init.cfg
index d6c0dcce5..ef450d790 100644
--- a/init.cfg
+++ b/init.cfg
@@ -488,12 +488,6 @@ require_dirent_d_type_()
python < /dev/null \
|| skip_ python missing: assuming no d_type support
- # Manually exclude xfs, since the test would mistakenly report
- # that it has d_type support: d_type == DT_DIR for "." and "..",
- # but DT_UNKNOWN for all other types.
- df -x xfs . > /dev/null 2>&1 \
- || skip_ requires d_type support
-
python "$abs_srcdir"/tests/d_type-check \
|| skip_ requires d_type support
}
diff --git a/tests/d_type-check b/tests/d_type-check
index ff1eb60b9..1a2f76f51 100644
--- a/tests/d_type-check
+++ b/tests/d_type-check
@@ -1,13 +1,17 @@
#!/usr/bin/python
-# Exit 0 if "." has useful d_type information, else 1.
+# Exit 0 if "." and "./tempfile" have useful d_type information, else 1.
# Intended to exit 0 only on Linux/GNU systems.
+import os
import sys
+import tempfile
fail = 1
+fname = None
+
try:
import ctypes.util
- (DT_UNKNOWN, DT_DIR,) = (0, 4,)
+ (DT_UNKNOWN, DT_DIR, DT_REG) = (0, 4, 8)
class dirent(ctypes.Structure):
_fields_ = [
@@ -17,19 +21,48 @@ try:
("d_type", ctypes.c_ubyte),
("d_name", ctypes.c_char*256)]
+ # Pass NULL to dlopen, assuming the python
+ # interpreter is linked with the C runtime
+ libc = ctypes.CDLL(None)
+
+ # Setup correct types for all args and returns
+ # even if only passing, to avoid truncation etc.
+ dirp = ctypes.c_void_p
direntp = ctypes.POINTER(dirent)
- libc = ctypes.CDLL(ctypes.util.find_library('c'), use_errno=True)
+ libc.readdir.argtypes = [dirp]
libc.readdir.restype = direntp
+ libc.opendir.restype = dirp
+
+ # Ensure a file is present
+ f, fname = tempfile.mkstemp(dir='.')
+ fname = os.path.basename(fname)
+
dirp = libc.opendir(".")
if dirp:
- ep = libc.readdir(dirp)
- if ep:
+ while True:
+ ep = libc.readdir(dirp)
+ if not ep: break
+ d_type = ep.contents.d_type
name = ep.contents.d_name
- if (name == "." or name == "..") and ep.contents.d_type == DT_DIR:
+ if name == "." or name == "..":
+ if d_type != DT_DIR: break
+ # Check files too since on XFS, only dirs have DT_DIR
+ # while everything else has DT_UNKNOWN
+ elif name == fname:
+ if d_type == DT_REG:
+ fail = 0
+ break
+ elif d_type != DT_DIR and d_type != DT_UNKNOWN:
fail = 0
+ break
+except:
+ pass
+try:
+ if fname:
+ os.unlink(fname);
except:
pass