1#!/usr/bin/python 2# Exit 0 if "." and "./tempfile" have useful d_type information, else 1. 3# Intended to exit 0 only on Linux/GNU systems. 4import os 5import sys 6import tempfile 7 8fail = 1 9fname = None 10 11try: 12 import ctypes.util 13 14 (DT_UNKNOWN, DT_DIR, DT_REG) = (0, 4, 8) 15 16 class dirent(ctypes.Structure): 17 _fields_ = [ 18 ("d_ino", ctypes.c_long), 19 ("d_off", ctypes.c_long), 20 ("d_reclen", ctypes.c_ushort), 21 ("d_type", ctypes.c_ubyte), 22 ("d_name", ctypes.c_char*256)] 23 24 # Pass NULL to dlopen, assuming the python 25 # interpreter is linked with the C runtime 26 libc = ctypes.CDLL(None) 27 28 # Setup correct types for all args and returns 29 # even if only passing, to avoid truncation etc. 30 dirp = ctypes.c_void_p 31 direntp = ctypes.POINTER(dirent) 32 33 libc.readdir.argtypes = [dirp] 34 libc.readdir.restype = direntp 35 36 libc.opendir.restype = dirp 37 38 # Ensure a file is present 39 f, fname = tempfile.mkstemp(dir='.') 40 fname = os.path.basename(fname) 41 42 dirp = libc.opendir(".") 43 if dirp: 44 while True: 45 ep = libc.readdir(dirp) 46 if not ep: break 47 d_type = ep.contents.d_type 48 name = ep.contents.d_name 49 if name == "." or name == "..": 50 if d_type != DT_DIR: break 51 # Check files too since on XFS, only dirs have DT_DIR 52 # while everything else has DT_UNKNOWN 53 elif name == fname: 54 if d_type == DT_REG: 55 fail = 0 56 break 57 elif d_type != DT_DIR and d_type != DT_UNKNOWN: 58 fail = 0 59 break 60except: 61 pass 62 63try: 64 if fname: 65 os.unlink(fname); 66except: 67 pass 68 69sys.exit(fail) 70