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).
>
> 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.

> with strtoul) are documented, so it seems like a good idea to at least hint
> to users that this could happen. The following man page diff attempts to
> address this, although there may well be cleaner ways of achieving the same
> end.
>
>
> Laurie
> --
> Personal                                            
http://tratt.net/laurie/
> The Converge programming language                    
 http://convergepl.org/
>   https://github.com/ltratt              http://twitter.com/laurencetratt
>
>
>
> --- directory.3.orig    Thu Feb  2 11:51:38 2012
> +++ directory.3 Thu Feb  2 11:58:36 2012
> @@ -109,6 +109,12 @@
>  upon reaching the end of the directory or detecting an invalid
>  .Fn seekdir
>  operation.
> +.Va errno
> +may not be set even if
> +.Dv NULL
> +is returned and therefore must be cleared before calling
> +.Fn readdir
> +if its value is required afterwards.

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.

>  .Pp
>  The
>  .Fn readdir_r

Reply via email to