Christian Heimes | 17 Jun 2012 02:13
Picon

Context helper for new os.*at functions

Hello,

Python 3.3 has got new wrappers for the 'at' variants of low level
functions, for example os.openat(). The 'at' variants work like their
brothers and sisters with one exception. The first argument must be a
file descriptor of a directory. The fd is used to calculate the absolute
path instead of the current working directory.

File descriptors are harder to manage than files because a fd isnt't
automatically closed when it gets out of scope. I've written a small
wrapper that takes care of the details. It also ensures that only
directories are opened.

Example:

with atcontext("/etc") as at:
    print(at.open)
    # functools.partial(<built-in function openat>, 3)
    f = at.open("fstab", os.O_RDONLY)
    print(os.read(f, 50))
    os.close(f)

Code:
http://pastebin.com/J4SLjB6k

The code calculates the name and creates dynamic wrapper with
functool.partial. This may not be desired if the wrapper is added to the
os module. I could add explicit methods and generate the doc strings
from the methods' doc strings.

(Continue reading)

Guido van Rossum | 17 Jun 2012 02:46
Favicon

Re: Context helper for new os.*at functions

Hmm... Isn't Larry Hastings working on replacing the separate
functions with an api where you pass an 'fd=...' argument to the
non-at function?

On Sat, Jun 16, 2012 at 5:13 PM, Christian Heimes <lists@...> wrote:
> Hello,
>
> Python 3.3 has got new wrappers for the 'at' variants of low level
> functions, for example os.openat(). The 'at' variants work like their
> brothers and sisters with one exception. The first argument must be a
> file descriptor of a directory. The fd is used to calculate the absolute
> path instead of the current working directory.
>
> File descriptors are harder to manage than files because a fd isnt't
> automatically closed when it gets out of scope. I've written a small
> wrapper that takes care of the details. It also ensures that only
> directories are opened.
>
> Example:
>
> with atcontext("/etc") as at:
>    print(at.open)
>    # functools.partial(<built-in function openat>, 3)
>    f = at.open("fstab", os.O_RDONLY)
>    print(os.read(f, 50))
>    os.close(f)
>
> Code:
> http://pastebin.com/J4SLjB6k
>
(Continue reading)

Christian Heimes | 17 Jun 2012 03:34
Picon

Re: Context helper for new os.*at functions

Am 17.06.2012 02:46, schrieb Guido van Rossum:
> Hmm... Isn't Larry Hastings working on replacing the separate
> functions with an api where you pass an 'fd=...' argument to the
> non-at function?

Oh, is he? I didn't know that. Indeed, it sounds like a good approach.

Users must still handle the fd correctly and make sure they open a
directory. Linux's man(2) open warns about possibility of
denial-of-service attempts for wrong fds. Linux has O_DIRECTORY for this
purpose. On other OSes users should do a stat() call in front, which is
open for race conditions but still better than getting stuck in a FIFO.

I could modify the wrapper a bit to make the wrapper useful for the new API:

class atcontext:
   def fileno(self):
       # for PyObject_AsFileDescriptor()
       return self.dirfd

with atcontext("/etc") as at:
    os.open("fstab", os.O_RDONLY, fd=at)

Christian

Gmane