coreutils
[Top][All Lists]
Advanced

[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)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]