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 ebl...@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org
signature.asc
Description: OpenPGP digital signature