mirror of
git://git.sv.gnu.org/coreutils.git
synced 2026-02-15 03:41:57 +02:00
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
This commit is contained in:
6
init.cfg
6
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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user