Hi Markus, thank you for your reply! > POSIX doesn't know O_SEARCH or O_PATH, and thus mandates nothing about > their meaning. POSIX 2008 with 2013 corrigenda mentions both O_SEARCH and O_EXEC. http://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html > Try strace(1). That should tell you what glibc and musl are doing > differently. For instace, whether glibc removes O_SEARCH from the fd. Thank you! I'll try it and report the results here. FWIW it does not seem to be correct that O_SEARCH can be equal to O_PATH; from what I gathered from manuals and various mailing lists discussions, O_SEARCH may be equal to O_EXEC since each of these flags is valid either for directory or file respectively. 28 авг. 2016 г. 10:11 пользователь "Markus Wichmann" написал: > On Sat, Aug 27, 2016 at 09:23:50PM +0300, Dmitry Selyutin wrote: > > int const flags = (O_DIRECTORY | O_SEARCH); > > int descriptor = open(path, flags); > > DIR *handle = fdopendir(descriptor); > > struct dirent *entry = readdir(handle); > > > > To cut the long story short, any attempt to call readdir(3) on directory > > handle obtained via fdopendir(3) returns NULL and sets the errno variable > > to EBADF. This behavior arises only on descriptors opened with > (O_DIRECTORY > > | O_SEARCH) flags enabled; it goes away if O_SEARCH flag is removed. > > > > Try strace(1). That should tell you what glibc and musl are doing > differently. For instace, whether glibc removes O_SEARCH from the fd. > > musl defines O_SEARCH to be equal to O_PATH. The manpage says that > O_PATH means the file isn't opened for reading. I guess if you do that > then getdents(2) will fail, which is what musl uses to implement > readdir(3). > > I tried to do the same trace in glibc 2.19 (which is what Debian stable > is using right now), but to no avail: O_SEARCH isn't even mentioned > anywhere in that code. But its implementation of fdopendir(3) rejects > fds open only for writing. The readdir(3) implementation is, of course, > overcomplicated, but also seems to just call getdents(2). And then it > tries to pack the kernel structures into its own structures, probably > for ABI reasons. And people wonder why I dislike dynamic linking... > > > So it seems that O_SEARCH is the reason; I thought that this flag tells > > exactly "well, I'm going to use it for search only", which implies "well, > > I'm going to use only readdir(3) to get information about files inside". > Is > > my interpretation correct? > > > > My manpage doesn't know O_SEARCH, but it knows O_PATH, and then you're > wrong. It means "I'll only use this fd in *at() and fchdir() and > similar; this fd isn't open for reading." > > > I'm not really sure if it is a bug, since I suspect POSIX may allow > open(3) > > with (O_DIRECTORY | O_SEARCH) flags to behave in an > implementation-defined > > matter; it can be possible that file descriptors obtained via open(3) > with > > O_DIRECTORY flag set are guaranteed to work only with fchdir(3) and > *at(3) > > operations. However, if such behavior is intentional, it would be a good > > idea (in my opinion) make fdopendir(3) return NULL (though it won't match > > behavior e.g. for glibc). > > > > POSIX doesn't know O_SEARCH or O_PATH, and thus mandates nothing about > their meaning. > > Ciao, > Markus >