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.
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.
 .Pp
 The
 .Fn readdir_r

Reply via email to