On Thu, Feb 2, 2012 at 5:29 AM, Christiano F. Haesbaert <haesba...@haesbaert.org> wrote: > On 2 February 2012 10:13, Laurence Tratt <lau...@tratt.net> wrote: >> To my surprise (and a couple of hours debugging later), readdir does not >> necessarily set errno even if NULL is returned. This is rather confusing >> because if NULL is returned two things might have happened: >> >> 1) The end of the directory has been reached in a normal fashion; errno >> won't have been touched in any way. >> >> 2) One of the errors associated with getdirentries might have occurred, >> in which case errno will have been set to a specific value. >> >> So any user who writes: >> >> if (readdir(dirp) == NULL) { >> if (errno == ...) >> ... >> } >> >> without setting errno to 0 beforehand will get a nasty shock from time to >> time (in my case, I was finding EAGAIN was leaking through from a failed >> flock call).
Yep. This is how readdir() has always behaved and was standardized by POSIX. >> The current man page doesn't claim that errno is always set but one might >> reasonably assume that it is: certainly, it seems a horribly easy way of >> introducing bugs (at least for idiots such as myself). Similar issues (e.g. > > I beg to disagree on this, yes, the interface is horrible: > > The readdir() function returns a pointer to the next directory entry in > the named directory stream dirp. It returns NULL upon reaching the end > of the directory or detecting an invalid seekdir() operation. > > So it says nothing about errno, but then, in the end: > > The readdir() and readdir_r() functions may also fail and set errno for > any of the errors specified for the routine getdirentries(2). > > Actually the reasonable thing to me is "errno can't be trusted from > readdir()", since "may" is not good enough. > And if that is the case, errno may actually be set to anything related > to internals. The use of 'may' is a standard form for the ERRORS section of manpages. What you may be missing is that the 'may' applies to the entire second half of the sentence as a whole. The precedence is similar to: The readdir() function may also ( fail and set errno ... ). I.e., if it fails, it sets errno. > Although I like your intention, I think the problem is in the later part: > > The readdir() and readdir_r() functions may also fail and set errno for > any of the errors specified for the routine getdirentries(2). > > Maybe this could be clarified ? > > Lets see what others think. I'll propose a third option: I think the directory(3) manpage would be clearer if the DESCRIPTION section was unwoven to have separate DESCRIPTION and RETURN VALUES section. Explicit wording that errno is not set when end of directory is reached and that programs that want to tell apart end-of-directory and errors must set errno to zero should be added. I also think readdir() should set errno if it detects an invalid seekdir(). EINVAL seems correct. Philip Guenther