On Tue, Apr 21, 2015 at 06:58:40PM +0300, Mika Ilmaranta wrote: > diff -up postfix-3.0.1/src/global/dynamicmaps.c.reset-errno > postfix-3.0.1/src/global/dynamicmaps.c > --- postfix-3.0.1/src/global/dynamicmaps.c.reset-errno 2015-04-21 > 18:37:29.641532865 +0300 > +++ postfix-3.0.1/src/global/dynamicmaps.c 2015-04-21 18:40:35.594131643 > +0300 > @@ -329,6 +329,12 @@ void dymap_init(const char *conf_path > if (access(conf_path_d, R_OK | X_OK) == 0 > && (dir = scan_dir_open(conf_path_d)) != 0) { > sub_conf_path = vstring_alloc(100); > + > + if(errno != 0) > + msg_warn("%s: errno set before scan_dir_next while loop, resetting > now: %m", myname); > + > + errno = 0; > + > 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); > > > And I get log: > > Apr 21 18:51:11 foo7 postfix/postmap[5099]: warning: dymap_init: errno > set before scan_dir_next while loop, resetting now: No such file or > directory
Indeed errno should be reset, if it is to be tested below, but I don't think that the test is appropriate. So my patch would be (perhaps this should also clear errno above the loop subject to a similar #if 0 ... #endif): diff --git a/src/global/dynamicmaps.c b/src/global/dynamicmaps.c index f978460..6391aee 100644 --- a/src/global/dynamicmaps.c +++ b/src/global/dynamicmaps.c @@ -333,9 +333,19 @@ void dymap_init(const char *conf_path, const char *plugin_dir) vstring_sprintf(sub_conf_path, "%s/%s", conf_path_d, conf_name); dymap_read_conf(vstring_str(sub_conf_path), plugin_dir); } - if (errno != 0) - /* Don't crash all programs - degrade gracefully. */ +#if 0 + /* + * The dynamicmaps.cf.d directory is managed by people, not Postfix + * software, so we can encounter symlinks to non-existent files there, + * or race against users deleting files. Therefore, we ignore ENOENT. + * + * Since errors other than ENOENT are fatal in dymap_read_conf(), + * there's nothing left to report here other than errors in readdir() + * via scan_dir_next(). That seems to unlikely to bother reporting. + */ + if (errno != 0 && errno != ENOENT) msg_warn("%s: directory read error: %m", conf_path_d); +#endif scan_dir_close(dir); vstring_free(sub_conf_path); } else if (errno != ENOENT) { -- Viktor.