How to get a directory file descriptor?

C

Cong Ma

Dear all,

Can you give me some hint on getting a directory file descriptor in Python?
Besides, what's good about os.fchdir() if I can't get a directory fd in the
first place?

Thanks for your reply.

Regards,
Cong.
 
R

r0g

Cong said:
Dear all,

Can you give me some hint on getting a directory file descriptor in Python?
Besides, what's good about os.fchdir() if I can't get a directory fd in the
first place?

Thanks for your reply.

Regards,
Cong.

for each in os.listdir(os.getcwd()):
print each

Roger.
 
C

Cong Ma

r0g said:
for each in os.listdir(os.getcwd()):
print each

Roger.
Roger,

It seemed I didn't make it clearly enough...

Your code fetches a bunch of strings representing file names in the working
directory, which is fine. But what I want is something like an integer file
descriptor, like the one returned by os.open() for files, or the Linux dirfd()
call, which returns an integer for a pointer to a DIR stream.

Regards,
Cong.
 
R

r0g

Cong said:
Roger,

It seemed I didn't make it clearly enough...

Your code fetches a bunch of strings representing file names in the working
directory, which is fine. But what I want is something like an integer file
descriptor, like the one returned by os.open() for files, or the Linux dirfd()
call, which returns an integer for a pointer to a DIR stream.

Regards,
Cong.

Erm, yeah, that's the os.listdir() bit.

Roger.
 
A

alex23

Can you give me some hint on getting a directory file descriptor in Python?
Besides, what's good about os.fchdir() if I can't get a directory fd in the
first place?

Try: os.open('<dirname>', os.O_RDONLY)

Check os for a list of the valid flag types.
 
D

D'Arcy J.M. Cain

Your code fetches a bunch of strings representing file names in the working
directory, which is fine. But what I want is something like an integer file
descriptor, like the one returned by os.open() for files, or the Linux dirfd()
call, which returns an integer for a pointer to a DIR stream.

Is this what you want?

ofiles = [open(x) for x in os.listdir(os.getcwd())]
 
A

alex23

Is this what you want?

ofiles = [open(x) for x in os.listdir(os.getcwd())]

'open' returns a "file object", whereas the OP is after "file
descriptors", which are returned by 'os.open'.
 
C

Cong Ma

alex23 said:
Is this what you want?

ofiles = [open(x) for x in os.listdir(os.getcwd())]

'open' returns a "file object", whereas the OP is after "file
descriptors", which are returned by 'os.open'.
You got it.

So if I can't seem to get directory file descriptors, the only way to use
os.fchdir() in Python is to embed Python in C code?
 
A

alex23

So if I can't seem to get directory file descriptors, the only way to use
os.fchdir() in Python is to embed Python in C code?

This doesn't work for you?

import os
dirfd = os.open("directory-name", os.O_DIRECTORY)
os.fchdir(dirfd)

Are you getting errors? Incorrect behaviour?
 
G

greg

alex23 said:
import os
dirfd = os.open("directory-name", os.O_DIRECTORY)
os.fchdir(dirfd)

os.O_DIRECTORY must be fairly new -- it doesn't exist
in my 2.5 installation. But os.O_RDONLY seems to work
just as well for this purpose.
 
A

alex23

os.O_DIRECTORY must be fairly new -- it doesn't exist
in my 2.5 installation. But os.O_RDONLY seems to work
just as well for this purpose.

Which OS are you using?

Python 2.5.2 (r252:60911, Jul 31 2008, 17:28:52)
[GCC 4.2.3 (Ubuntu 4.2.3-2ubuntu7)] on linux2
Type "help", "copyright", "credits" or "license" for more information.True

I'm pretty certain it was present under Windows XP as well.
 
C

Cong Ma

alex23 said:
os.O_DIRECTORY must be fairly new -- it doesn't exist
in my 2.5 installation. But os.O_RDONLY seems to work
just as well for this purpose.

Which OS are you using?

Python 2.5.2 (r252:60911, Jul 31 2008, 17:28:52)
[GCC 4.2.3 (Ubuntu 4.2.3-2ubuntu7)] on linux2
Type "help", "copyright", "credits" or "license" for more information.True

I'm pretty certain it was present under Windows XP as well.
Hello,

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

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? In C, I think, calling opendir() followed by dirfd() should be the
correct way of doing this?

Thanks.
 
S

Steve Holden

alex23 said:
os.O_DIRECTORY must be fairly new -- it doesn't exist
in my 2.5 installation. But os.O_RDONLY seems to work
just as well for this purpose.

Which OS are you using?

Python 2.5.2 (r252:60911, Jul 31 2008, 17:28:52)
[GCC 4.2.3 (Ubuntu 4.2.3-2ubuntu7)] on linux2
Type "help", "copyright", "credits" or "license" for more information.True

I'm pretty certain it was present under Windows XP as well.

OK, here's a little mystery. This is Vista (spit):

Microsoft Windows [Version 6.0.6001]
Copyright (c) 2006 Microsoft Corporation. All rights reserved.

C:\Users\sholden>python
Python 2.5.2 (r252:60911, Feb 21 2008, 13:11:45) [MSC v.1310 32 bit
(Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.Traceback (most recent call last):

Since these two are the exact same version I presume O_DIRECTORY is not
meaningful on Windows. Anyway, when I try to use O_RDONLY on Vista I get
"Permission denied":
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: [Errno 13] Permission denied: 'C:\\Users\\sholden\\Documents'

regards
Steve
 
A

alex23

Since these two are the exact same version I presume O_DIRECTORY is not
meaningful on Windows. Anyway, when I try to use O_RDONLY on Vista I get
"Permission denied":

Sorry, my bad. I got the exact same "Permission denied" response when
I first tried this under XP, so I shelled to a linux box and tested
there...then promptly forgot all about it. In my defence, it was
pretty late at night when I did so :)

In fact, I can't even find a reference to O_DIRECTORY in the manual at
all...
 
A

alex23

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.

Yes, I just noticed that myself.
       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,

Well, that certainly explains it's absence :)
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?

I'm sorry, that's outside of my knowledge. But it seemed to work fine
when I tried it.
 
C

Cong Ma

Nick said:
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.

Thank you so much Nick. I'll take a look into the ctypes module.

I guess the reason of Python library not including those wrappers has something
to do with standard compliance. The fchdir(2) manual says "comforming to
POSIX.1-2001" but the opendir(3) manual says "fdopendir() is specified in
POSIX.1-2008."
 
T

Terry Reedy

Steve said:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'O_DIRECTORY'

The 3.0 manual lists 4 groups of flags: unix and windows, unix only,
windows only, gnu only (check system-specific manual). O_DIRECTORY is
in the gnu group.
 
G

greg

Steve said:
Anyway, when I try to use O_RDONLY on Vista I get
"Permission denied":

According to the library ref, fchdir() is Unix-only, so there
probably isn't a use case for getting a file descriptor for
a directory on Windows in the first place.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top