Supposedly, these functions make it easier to do various file accesses in a
threaded environment because the POSIX threading system failed to provide a
means for each thread to have its own current directory context. But even
then, it is more convenient to have separate descriptors open to various
directories than to be juggling the current directory all the time.
I'm not using threads at all for this program project. But it does need to
do file tree recursion. And that's one of the things I thought these *at()
functions would be good for.
But there is no opendirat(int dirfd, const char *name) function.
So it is still necessary to either construct a long pathname to give to the
opendir() function, or call fchdir() to change the current directory to one
specified by a given directory (and this breaks theads) then call opendir()
with a simple name.
Or, could I do this (defintions and error checks omitted for clarity):
nextfd = openat( dirfd, dirname, O_DIRECTORY );
snprintf( selfname, sizeof selfname, "/proc/self/fd/%d", nextfd );
dir = opendir( selfname );
close( nextfd );
...
closedir( dir );
Previously, I would have done this which is unsafe with threads:
savedir = open( ".", O_DIRECTORY );
fchdir( dirfd );
dir = opendir( "." );
fchdir( savedir );
...
closedir( dir );
--
|WARNING: Due to extreme spam, googlegroups.com is blocked. Due to ignorance |
| by the abuse department, bellsouth.net is blocked. If you post to |
| Usenet from these places, find another Usenet provider ASAP. |
| Phil Howard KA9WGN (email for humans: first name in lower case at ipal.net) |
> In a program I was about to start doing, it was going to be especially
> useful
> to make use of the various *at() filesystem functions. However, there is
> an important one missing.
> But there is no opendirat(int dirfd, const char *name) function.
But there is fopendir!
For example:
dir = opendir(openat(dirfd, ".", O_DIRECTORY));
That does not seem to be in either any of my include headers nor man pages.
It looks like fopendir() exists in Windows. I've also found an implementation
online in source code. But it has a couple issues. One is that it is making
assumptions about the members of struct DIR, and manipulating them directly.
So it would not be portable. The other is that it puts the descriptor into
that struct. That implies that the semantics shall be that closedir() will
close the descriptor passed to fopendir(). Is that the semantics you expect?
The alternative is that a duplicate descriptor is made. But is that to be
done before the fopendir() call or inside its implementation? If I'm going
to add fopendir() to my own library until it becomes more widespread in Linux,
then I really ought to at least get the semantics the way it ultimately will
be when it is available in libc.
Actually .... I found something else:
extern DIR *fdopendir (int __fd);
Still no idea if closedir() on the DIR * it returns will do close(__fd).
>On Fri, 11 Jul 2008 08:40:58 +0100 Timothy Baldwin <T.E.Ba...@members.leeds.ac.uk> wrote:
>| In message <g56fg...@news5.newsguy.com>, phil-new...@ipal.net
>| <phil-new...@ipal.net> wrote:
>|
>|> In a program I was about to start doing, it was going to be especially
>|> useful
>|> to make use of the various *at() filesystem functions. However, there is
>|> an important one missing.
>|
>|
>|> But there is no opendirat(int dirfd, const char *name) function.
>|
>|
>| But there is fopendir!
>|
>| For example:
>| dir = opendir(openat(dirfd, ".", O_DIRECTORY));
>
>Actually .... I found something else:
>
> extern DIR *fdopendir (int __fd);
http://www.kernel.org/doc/man-pages/online/pages/man3/opendir.3.html
This Linux man page text appeared only late last year (so won't be in man
pages on anything except fairly recent distros -- but you can get the
latest man-pages tarball here: http://www.kernel.org/doc/man-pages/).
The interfaces has been in glibc since 2.4 (early 2006), and will be
standardized in the next edition of POSIX.1.
>Still no idea if closedir() on the DIR * it returns will do close(__fd).
AFAICT from looking at the source of glibc's fdopendir(), everything should
work as expected.
Cheers,
Michael
| AFAICT from looking at the source of glibc's fdopendir(), everything should
| work as expected.
The question is, by who's expectation?
One person might expect the whole opendir/readdir/closedir to always close the
underlying file descriptor "because that is how closedir would be coded".
Another person might expect the fact that fdopendir() was called to set a flag
to remember that the caller just wants to layer readdir/closedir over its own
existing descriptor that it may be also using elsewhere, even after the layer
is no longer needed and its allocations are released with closedir().
If I were to have been the one to implement fdopendir() over a given descriptor,
I would have implemnted it with the tracking flag so that a descriptor that is
open before the caller calls fdopendir() is still open after the caller calls
closedir() to clean up the library allocations.
Is that what you would have expected?
The source to glibc is a tangled mess I stay away from.
>On Mon, 14 Jul 2008 06:47:05 +0200 Michael Kerrisk <mtk.ma...@gmail.com> wrote:
>
>| AFAICT from looking at the source of glibc's fdopendir(), everything should
>| work as expected.
>
>The question is, by who's expectation?
Here's what the upcoming POSIX.1 revision says:
[[
The fdopendir( ) function shall be equivalent to the opendir( ) function
except that the directory is
specified by a file descriptor rather than by a name. The file offset
associated with the file
descriptor at the time of the call determines which entries are returned.
Upon successful return from fdopendir( ), the file descriptor is under the
control of the system,
and if any attempt is made to close the file descriptor, or to modify the
state of the associated
description, other than by means of closedir( ), readdir( ), readdir_r( ),
or rewinddir( ), the behavior
is undefined. Upon calling closedir( ) the file descriptor shall be closed.
]]