From: Timo Sirainen Date: Fri, 2 Jul 2010 14:23:32 +0000 (+0100) Subject: openbsd: Hide errors written by dlopen() if we wanted to ignore them. X-Git-Tag: 2.0.rc1~10 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=6c62d058146f3292aa09f912db33642d7756dde8;p=thirdparty%2Fdovecot%2Fcore.git openbsd: Hide errors written by dlopen() if we wanted to ignore them. doveadm loads all plugins at startup that it can. It shouldn't be printing unnecessary error messages to stderr. --HG-- branch : HEAD --- diff --git a/src/lib/module-dir.c b/src/lib/module-dir.c index a4004ea6e7..7d9bbe1f58 100644 --- a/src/lib/module-dir.c +++ b/src/lib/module-dir.c @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -96,6 +97,35 @@ module_check_missing_dependencies(struct module *module, return TRUE; } +static void *quiet_dlopen(const char *path, int flags) +{ +#ifndef __OpenBSD__ + return dlopen(path, flags); +#else + void *handle; + int fd, fd_null; + + /* OpenBSD likes to print all "undefined symbol" errors to stderr. + Hide them by sending them to /dev/null. */ + fd_null = open("/dev/null", O_WRONLY); + if (fd_null == -1) + i_fatal("open(/dev/null) failed: %m"); + fd = dup(STDERR_FILENO); + if (fd == -1) + i_fatal("dup() failed: %m"); + if (dup2(fd_null, STDERR_FILENO) < 0) + i_fatal("dup2() failed: %m"); + handle = dlopen(path, flags); + if (dup2(fd, STDERR_FILENO) < 0) + i_fatal("dup2() failed: %m"); + if (close(fd) < 0) + i_error("close() failed: %m"); + if (close(fd_null) < 0) + i_error("close() failed: %m"); + return handle; +#endif +} + static struct module * module_load(const char *path, const char *name, const struct module_dir_load_settings *set, @@ -105,11 +135,16 @@ module_load(const char *path, const char *name, struct module *module; const char *const *module_version; - handle = dlopen(path, RTLD_GLOBAL | RTLD_NOW); - if (handle == NULL) { - if (!set->ignore_dlopen_errors) + if (set->ignore_dlopen_errors) { + handle = quiet_dlopen(path, RTLD_GLOBAL | RTLD_NOW); + if (handle == NULL) + return NULL; + } else { + handle = dlopen(path, RTLD_GLOBAL | RTLD_NOW); + if (handle == NULL) { i_error("dlopen(%s) failed: %s", path, dlerror()); - return NULL; + return NULL; + } } module = i_new(struct module, 1);