How to get a directory file descriptor?

Nick Craig-Wood nick at craig-wood.com
Wed Nov 26 08:30:40 EST 2008


Cong Ma <cma at mail.bnu.edu.cn> wrote:
>  Thanks for your reply. I checked my Python 2.5 install on Linux and there's the
>  O_DIRECTORY flag. However this is not mentioned anywhere in the Library Reference.
> 
>  There's another question regarding to this flag though: I checked the manual of
>  the Linux system call open(2), in which there's a paragraph on this flag:
> 
>         O_DIRECTORY
>                If pathname is not a directory, cause the open  to  fail.   This
>                flag is Linux-specific, and was added in kernel version 2.1.126,
>                to avoid denial-of-service problems if opendir(3) is called on a
>                FIFO  or  tape  device,  but  should  not be used outside of the
>                implementation of opendir(3).

That says avoid to me!

>  Note the "should not be used outside of the implementation of opendir(3)" part.
>  Does that mean using Python's os.open() with the O_DIRECTORY flag is a Bad
>  Thing?

IMHO yes.

> In C, I think, calling opendir() followed by dirfd() should be the
> correct way of doing this?

Here is how you do exactly that in python using ctypes

from ctypes import CDLL, c_char_p, c_int, Structure, POINTER
from ctypes.util import find_library

class c_dir(Structure):
    """Opaque type for directory entries, corresponds to struct DIR"""
c_dir_p = POINTER(c_dir)

c_lib = CDLL(find_library("c"))
opendir = c_lib.opendir
opendir.argtypes = [c_char_p]
opendir.restype = c_dir_p
dirfd = c_lib.dirfd
dirfd.argtypes = [c_dir_p]
dirfd.restype = c_int
closedir = c_lib.closedir
closedir.argtypes = [c_dir_p]
closedir.restype = c_int

dir_p = opendir(".")
print "dir_p = %r" % dir_p
dir_fd = dirfd(dir_p)
print "dir_fd = %r" % dir_fd
print "closed (rc %r)" % closedir(dir_p)

Which prints on my linux machine

dir_p = <ctypes.LP_c_dir object at 0xb7d13cd4>
dir_fd = 3
closed (rc 0)

I don't know why os doesn't wrap - opendir, closedir, dirfd, readdir
etc - I guess because except if you are doing something esoteric, then
os.list and os.walk do everything you could possibly want.

-- 
Nick Craig-Wood <nick at craig-wood.com> -- http://www.craig-wood.com/nick



More information about the Python-list mailing list