[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: dirfd on mingw

From: Eric Blake
Subject: Re: dirfd on mingw
Date: Thu, 28 Apr 2011 16:29:03 -0600
User-agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv: Gecko/20110307 Fedora/3.1.9-0.39.b3pre.fc14 Lightning/1.0b3pre Mnenhy/0.8.3 Thunderbird/3.1.9

On 04/28/2011 04:10 PM, Bruno Haible wrote:
> Eric Blake wrote:
>> what about my idea of
>> starting to associate DIR* with directory fds, for the sake of dirfd?
> OK, you want to implement dirfd for native Windows? There are two issues:
> 1) Use a fake fd without a HANDLE, or use a real HANDLE?
> 2) How to associate the fd with with a DIR structure?
> Ad 1): It is possible to open a HANDLE to a directory, see
>   <http://msdn.microsoft.com/en-us/library/aa365258%28v=vs.85%29.aspx>
>   <http://msdn.microsoft.com/en-us/library/aa363858%28v=vs.85%29.aspx>
>   GetFileType of such a handle return FILE_TYPE_DISK.
>   Since fstat() supports only handles of type FILE_TYPE_DISK, FILE_TYPE_CHAR,
>   FILE_TYPE_PIPE, this means fstat() works on such a handle.
>   The attached program below has been tested on Windows XP (even with an
>   unprivileged user account).
>   But an fd with a fake handle (INVALID_HANDLE_VALUE) is possible as well;
>   it requires a bit more code in fstat() then.

We already replace fstat() for fchdir(); it calls stat() on the
underlying name of the directory associated with the dummy fd.  And
perhaps the dummy fd for fchdir _should_ open a directory HANDLE, as
windows guarantees that a directory with an open handle is less likely
to be renamed out from under us, and the premise of storing the
directory name in the fchdir shadow array is that the name is still
likely to be valid the next time we need to get back to that directory
(if other processes can rename the directory behind our back, we're
liable to act on the wrong directory).

>   In either case, that fd is not helpful for openat() purposes.

Not directly, but the shadow table makes it useful.

> Ad 2): You can wrap the DIR structure so that the gnulib defined DIR is a
>   wrapper around the original DIR:
>      struct { int fd; DIR *real_d; }
>   Then opendir, readdir, closedir, rewinddir need to be overridden.
>   Or you can make a mapping  DIR * -> int , through a simple association list.
>   (There won't be many DIR * objects open on average.)

I was envisioning the reverse - maintain the shadow list of known fds
associated with a DIR.  The DIR*->int lookup for dirfd is then a matter
of walking the shadow fd list of all known directory dummy fds, to see
if any of them have that DIR* associated with them, via pointer equality
of DIR*.  We have at worst fdtablesize entries to walk through, but
usually less than that.

opendir is already overridden by fchdir, but wasn't doing anything on
mingw (since dirfd was returning -1).  Post-fix, it would now open a
dummy fd at the same time as creating the DIR*, and store that DIR* in
the shadow table.  fdopendir uses the existing fd shadows to look up
what directory name is tied to the fd, calls the real opendir with that
name, then ties the DIR* to the shadow table at that point.  And
closedir obviously cleans up the shadow table.  readdir and rewinddir
need no overwrite in that case.

>   For which kinds of operations would you need an  int -> DIR *  mapping?

None, but maintaining a finite-sized int->DIR* table makes DIR*->int
reverse lookups relatively easy.

Eric Blake   address@hidden    +1-801-349-2682
Libvirt virtualization library http://libvirt.org

Attachment: signature.asc
Description: OpenPGP digital signature

reply via email to

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