On Tue, Apr 21, 2015 at 12:57:03PM -0400, Wietse Venema wrote: > PS: I don't buy the argument that readdir() cannot report a dangling > symlink.
That's not the argument I'm making. It absolutely reports dangling symlinks, without error. > It reports directory entries. There is no need for readdir() > to dereference a symlink. Absolutely, but in: while ((conf_name = scan_dir_next(dir)) != 0) { vstring_sprintf(sub_conf_path, "%s/%s", conf_path_d, conf_name); dymap_read_conf(vstring_str(sub_conf_path), plugin_dir); } each entry returned by readdir() vis scan_dir_next() is immediately used in dymap_read_conf(), which will encounter ENOENT. > > Wietse > > --- /var/tmp/postfix-3.1-20150330/src/util/scan_dir.c 2014-12-06 > 20:35:33.000000000 -0500 > +++ ./scan_dir.c 2015-04-21 12:47:06.072252950 -0400 > @@ -177,6 +177,8 @@ > #define STREQ(x,y) (strcmp((x),(y)) == 0) > > if (info) { > + /* Some implementations report spurious errors. */ > + errno = 0; > while ((dp = readdir(info->dir)) != 0) { > if (STREQ(dp->d_name, ".") || STREQ(dp->d_name, "..")) { > if (msg_verbose > 1) > If the intention was always to only catch readdir() errors, and not to report errors from accessing files while looping through the readdir() results, then indeed this is the right patch, because we only care about errno from the last readdir() that returns NULL. Given the "sticky" errno, the previous code also mixed in errors from file access, which led me to think you actually wanted to do something with those too, but now it is clear that's not the case. So indeed the fix is to reset errno in scan_dir_next(). Which then means then any errno after scan_dir_next() reports the end is a readdir() error. -- Viktor.