Now that the necessary functions from log.h have been moved to macro.h, we can stop including log.h in macro.h. This requires modifying source files all over the tree to include log.h instead.
68 lines
2.1 KiB
C
68 lines
2.1 KiB
C
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
|
|
|
#include "dlfcn-util.h"
|
|
#include "log.h"
|
|
|
|
static int dlsym_many_or_warnv(void *dl, int log_level, va_list ap) {
|
|
void (**fn)(void);
|
|
|
|
/* 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. */
|
|
|
|
while ((fn = va_arg(ap, typeof(fn)))) {
|
|
void (*tfn)(void);
|
|
const char *symbol;
|
|
|
|
symbol = va_arg(ap, typeof(symbol));
|
|
|
|
tfn = (typeof(tfn)) dlsym(dl, symbol);
|
|
if (!tfn)
|
|
return log_full_errno(log_level,
|
|
SYNTHETIC_ERRNO(ELIBBAD),
|
|
"Can't find symbol %s: %s", symbol, dlerror());
|
|
*fn = tfn;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int dlsym_many_or_warn_sentinel(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_NOW|RTLD_NODELETE);
|
|
if (!dl)
|
|
return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
|
|
"%s is not installed: %s", filename, dlerror());
|
|
|
|
log_debug("Loaded '%s' via dlopen()", filename);
|
|
|
|
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;
|
|
}
|