[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: how to check for dirent.d_type support from shell, python or perl?
From: |
Jim Meyering |
Subject: |
Re: how to check for dirent.d_type support from shell, python or perl? |
Date: |
Fri, 13 May 2011 15:45:06 +0200 |
Pádraig Brady wrote:
> On 13/05/11 13:06, Jim Meyering wrote:
>> Very nice. Thank you!
>> That appears to work fine on Linux/glibc,
>> but fails on a solaris 10 system which lacks ctypes:
>>
>> and fails on solaris 5.11 and freebsd 8.x due to the absence of libc.so.6
>> (one of those has libc.so and libc.so.1):
>
> Yep, you'll need this around the whole script:
>
> try:
> # the script
> except:
> sys.exit(1)
>
> If we were paranoid about segfaults which I've seen
> happen with ctypes, one might wrap the script in (unlimit -c 0; )
>
>> requiring that "." be the first entry
>> should be enough for nearly all uses.
>>
>> sys.exit(ep.contents.d_name != "." or ep.contents.d_type != DT_DIR)
>
> Yep that should give enough test coverage,
> and we can just comment in the script for cases where it fails.
Thanks.
Here's what I have now.
Not that it's likely to change, but it'd be nice not to hard-code
the "6" in "libc.so.6".
#!/usr/bin/python
# Exit 0 if "." has useful d_type information, else 1.
# Intended to exit 0 only on Linux/GNU systems.
import sys
fail = 1
try:
import ctypes
(DT_UNKNOWN, DT_DIR,) = (0, 4,)
class dirent(ctypes.Structure):
_fields_ = [
("d_ino", ctypes.c_long),
("d_off", ctypes.c_long),
("d_reclen", ctypes.c_ushort),
("d_type", ctypes.c_ubyte),
("d_name", ctypes.c_char*256)]
direntp = ctypes.POINTER(dirent)
# FIXME: find a way to avoid hard-coding libc's so-name.
libc = ctypes.cdll.LoadLibrary("libc.so.6")
libc.readdir.restype = direntp
dirp = libc.opendir(".")
if dirp:
ep = libc.readdir(dirp)
# Assume that the first entry will be ".".
if ep and ep.contents.d_name == "." and ep.contents.d_type == DT_DIR:
fail = 0
except:
pass
sys.exit(fail)