From: Lennart Poettering Date: Wed, 24 Jun 2020 12:47:39 +0000 (+0200) Subject: dlfcn-util: add dlsym_many_and_warn() helper X-Git-Tag: v247-rc1~457^2~2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=046c91314a4046039a344c9058d3f390d8920ab1;p=thirdparty%2Fsystemd.git dlfcn-util: add dlsym_many_and_warn() helper When we dlopen() some library we most likely will resolve more than a few symbols, hence add a helper that makes it easy. --- diff --git a/src/basic/dlfcn-util.c b/src/basic/dlfcn-util.c new file mode 100644 index 00000000000..08ded96965b --- /dev/null +++ b/src/basic/dlfcn-util.c @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ + +#include "dlfcn-util.h" + +int dlsym_many_and_warn(void *dl, int level, ...) { + va_list ap; + int r; + + /* Tries to resolve a bunch of function symbols, and logs errors about the ones it cannot + * resolve. Note that this function possibly modifies the supplied function pointers if the whole + * operation fails */ + + va_start(ap, level); + + for (;;) { + void (**fn)(void); + void (*tfn)(void); + const char *symbol; + + fn = va_arg(ap, typeof(fn)); + if (!fn) + break; + + symbol = va_arg(ap, typeof(symbol)); + + tfn = (typeof(tfn)) dlsym(dl, symbol); + if (!tfn) { + r = log_full_errno(level, + SYNTHETIC_ERRNO(ELIBBAD), + "Can't find symbol %s: %s", symbol, dlerror()); + va_end(ap); + return r; + } + + *fn = tfn; + } + + va_end(ap); + return 0; +} diff --git a/src/basic/dlfcn-util.h b/src/basic/dlfcn-util.h index d254afb68b5..df66cdfd38f 100644 --- a/src/basic/dlfcn-util.h +++ b/src/basic/dlfcn-util.h @@ -6,3 +6,5 @@ #include "macro.h" DEFINE_TRIVIAL_CLEANUP_FUNC(void*, dlclose); + +int dlsym_many_and_warn(void *dl, int level, ...); diff --git a/src/basic/meson.build b/src/basic/meson.build index 90924d6cb89..42d0754d6d1 100644 --- a/src/basic/meson.build +++ b/src/basic/meson.build @@ -39,6 +39,7 @@ basic_sources = files(''' device-nodes.h dirent-util.c dirent-util.h + dlfcn-util.c dlfcn-util.h efivars.c efivars.h