diff options
author | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2021-06-22 08:48:41 +0200 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2021-06-24 10:16:43 +0200 |
commit | fff25ab22eec825a15c2647a84247221abd6b0c8 (patch) | |
tree | 3814050fb6658bf84cdb3bec69a827bd6075def1 /src/shared | |
parent | meson: drop libseccomp and libselinux from libbasic linkage (diff) | |
download | systemd-fff25ab22eec825a15c2647a84247221abd6b0c8.tar.xz systemd-fff25ab22eec825a15c2647a84247221abd6b0c8.zip |
dlfcn-util: invert function naming and add helper that does the whole job
We warn when the operation fails, not when it succeeds. Hence this should be
"<do>_or_<handle failure>", not "<do>_and_<handle failure>". We *could* use
whatever convention we want, but rust and perl are rather consistent in using
the logical convention. We don't care about perl that much, but having a naming
convention inverted wrt. rust would be rather confusing.
Also, pretty much every implementation does similar steps, so add a nice
wrapper which combines opening of the library and loading of the symbols.
Also add missing sentinel attribute in dlopen_or_warn().
Diffstat (limited to 'src/shared')
-rw-r--r-- | src/shared/bpf-dlopen.c | 2 | ||||
-rw-r--r-- | src/shared/cryptsetup-util.c | 2 | ||||
-rw-r--r-- | src/shared/dlfcn-util.c | 70 | ||||
-rw-r--r-- | src/shared/dlfcn-util.h | 8 | ||||
-rw-r--r-- | src/shared/idn-util.c | 4 | ||||
-rw-r--r-- | src/shared/libfido2-util.c | 2 | ||||
-rw-r--r-- | src/shared/pwquality-util.c | 2 | ||||
-rw-r--r-- | src/shared/qrcode-util.c | 2 | ||||
-rw-r--r-- | src/shared/tpm2-util.c | 6 |
9 files changed, 63 insertions, 35 deletions
diff --git a/src/shared/bpf-dlopen.c b/src/shared/bpf-dlopen.c index 0556148458..0d222ae19e 100644 --- a/src/shared/bpf-dlopen.c +++ b/src/shared/bpf-dlopen.c @@ -35,7 +35,7 @@ int dlopen_bpf(void) { return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "libbpf is not installed: %s", dlerror()); - r = dlsym_many_and_warn( + r = dlsym_many_or_warn( dl, LOG_DEBUG, DLSYM_ARG(bpf_link__destroy), diff --git a/src/shared/cryptsetup-util.c b/src/shared/cryptsetup-util.c index 9deae39dea..99c78f6858 100644 --- a/src/shared/cryptsetup-util.c +++ b/src/shared/cryptsetup-util.c @@ -62,7 +62,7 @@ int dlopen_cryptsetup(void) { return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "libcryptsetup support is not installed: %s", dlerror()); - r = dlsym_many_and_warn( + r = dlsym_many_or_warn( dl, LOG_DEBUG, DLSYM_ARG(crypt_activate_by_passphrase), diff --git a/src/shared/dlfcn-util.c b/src/shared/dlfcn-util.c index 2dbff0e358..c027e3396b 100644 --- a/src/shared/dlfcn-util.c +++ b/src/shared/dlfcn-util.c @@ -2,39 +2,63 @@ #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 */ +static int dlsym_many_or_warnv(void *dl, int log_level, va_list ap) { + void (**fn)(void); - va_start(ap, level); + /* Tries to resolve a bunch of function symbols, and logs an error about if it cannot resolve one of + * them. Note that this function possibly modifies the supplied function pointers if the whole + * operation fails. */ - for (;;) { - void (**fn)(void); + while ((fn = va_arg(ap, typeof(fn)))) { 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; - } - + if (!tfn) + return log_full_errno(log_level, + SYNTHETIC_ERRNO(ELIBBAD), + "Can't find symbol %s: %s", symbol, dlerror()); *fn = tfn; } - va_end(ap); return 0; } + +int dlsym_many_or_warn(void *dl, int log_level, ...) { + va_list ap; + int r; + + va_start(ap, log_level); + r = dlsym_many_or_warnv(dl, log_level, ap); + va_end(ap); + + return r; +} + +int dlopen_many_sym_or_warn_sentinel(void **dlp, const char *filename, int log_level, ...) { + _cleanup_(dlclosep) void *dl = NULL; + int r; + + if (*dlp) + return 0; /* Already loaded */ + + dl = dlopen(filename, RTLD_LAZY); + if (!dl) + return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), + "%s is not installed: %s", filename, dlerror()); + + va_list ap; + va_start(ap, log_level); + r = dlsym_many_or_warnv(dl, log_level, ap); + va_end(ap); + + if (r < 0) + return r; + + /* Note that we never release the reference here, because there's no real reason to. After all this + * was traditionally a regular shared library dependency which lives forever too. */ + *dlp = TAKE_PTR(dl); + return 1; +} diff --git a/src/shared/dlfcn-util.h b/src/shared/dlfcn-util.h index aa713d328b..87585b406a 100644 --- a/src/shared/dlfcn-util.h +++ b/src/shared/dlfcn-util.h @@ -7,9 +7,13 @@ DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(void*, dlclose, NULL); -int dlsym_many_and_warn(void *dl, int level, ...); +int dlsym_many_or_warn(void *dl, int log_level, ...) _sentinel_; +int dlopen_many_sym_or_warn_sentinel(void **dlp, const char *filename, int log_level, ...) _sentinel_; -/* Macro useful for putting together variable/symbol name pairs when calling dlsym_many_and_warn(). Assumes +#define dlopen_many_sym_or_warn(dlp, filename, log_level, ...) \ + dlopen_many_sym_or_warn_sentinel(dlp, filename, log_level, __VA_ARGS__, NULL) + +/* Macro useful for putting together variable/symbol name pairs when calling dlsym_many_or_warn(). Assumes * that each library symbol to resolve will be placed in a variable with the "sym_" prefix, i.e. a symbol * "foobar" is loaded into a variable "sym_foobar". */ #define DLSYM_ARG(arg) \ diff --git a/src/shared/idn-util.c b/src/shared/idn-util.c index 1c4472dc66..63a9ebf99d 100644 --- a/src/shared/idn-util.c +++ b/src/shared/idn-util.c @@ -32,7 +32,7 @@ int dlopen_idn(void) { return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "libidn2 support is not installed: %s", dlerror()); - r = dlsym_many_and_warn( + r = dlsym_many_or_warn( dl, LOG_DEBUG, DLSYM_ARG(idn2_lookup_u8), @@ -73,7 +73,7 @@ int dlopen_idn(void) { "libidn support is not installed: %s", dlerror()); } - r = dlsym_many_and_warn( + r = dlsym_many_or_warn( dl, LOG_DEBUG, DLSYM_ARG(idna_to_ascii_4i), diff --git a/src/shared/libfido2-util.c b/src/shared/libfido2-util.c index ec09937d83..c69943262d 100644 --- a/src/shared/libfido2-util.c +++ b/src/shared/libfido2-util.c @@ -72,7 +72,7 @@ int dlopen_libfido2(void) { return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "libfido2 support is not installed: %s", dlerror()); - r = dlsym_many_and_warn( + r = dlsym_many_or_warn( dl, LOG_DEBUG, DLSYM_ARG(fido_assert_allow_cred), diff --git a/src/shared/pwquality-util.c b/src/shared/pwquality-util.c index 5bd33eee4c..d7776e7eff 100644 --- a/src/shared/pwquality-util.c +++ b/src/shared/pwquality-util.c @@ -35,7 +35,7 @@ int dlopen_pwquality(void) { return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "libpwquality support is not installed: %s", dlerror()); - r = dlsym_many_and_warn( + r = dlsym_many_or_warn( dl, LOG_DEBUG, DLSYM_ARG(pwquality_check), diff --git a/src/shared/qrcode-util.c b/src/shared/qrcode-util.c index 79ac640672..5345b7288b 100644 --- a/src/shared/qrcode-util.c +++ b/src/shared/qrcode-util.c @@ -29,7 +29,7 @@ int dlopen_qrencode(void) { return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "libqrcode support is not installed: %s", dlerror()); - r = dlsym_many_and_warn( + r = dlsym_many_or_warn( dl, LOG_DEBUG, DLSYM_ARG(QRcode_encodeString), diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c index b2540c62fe..da78e1f406 100644 --- a/src/shared/tpm2-util.c +++ b/src/shared/tpm2-util.c @@ -52,7 +52,7 @@ int dlopen_tpm2(void) { return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "TPM2 support is not installed: %s", dlerror()); - r = dlsym_many_and_warn( + r = dlsym_many_or_warn( dl, LOG_DEBUG, DLSYM_ARG(Esys_Create), @@ -84,7 +84,7 @@ int dlopen_tpm2(void) { return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "TPM2 support is not installed: %s", dlerror()); - r = dlsym_many_and_warn( + r = dlsym_many_or_warn( dl, LOG_DEBUG, DLSYM_ARG(Tss2_RC_Decode), @@ -104,7 +104,7 @@ int dlopen_tpm2(void) { return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "TPM2 support is not installed: %s", dlerror()); - r = dlsym_many_and_warn( + r = dlsym_many_or_warn( dl, LOG_DEBUG, DLSYM_ARG(Tss2_MU_TPM2B_PRIVATE_Marshal), |