Merge pull request #17884 from poettering/test-dlopen
tests: add test that dlopen()s our weak shared library deps once
This commit is contained in:
commit
733558adef
|
@ -1117,6 +1117,7 @@ conf.set10('HAVE_LIBIPTC', have)
|
||||||
want_qrencode = get_option('qrencode')
|
want_qrencode = get_option('qrencode')
|
||||||
if want_qrencode != 'false' and not skip_deps
|
if want_qrencode != 'false' and not skip_deps
|
||||||
libqrencode = dependency('libqrencode',
|
libqrencode = dependency('libqrencode',
|
||||||
|
version : '>= 4',
|
||||||
required : want_qrencode == 'true')
|
required : want_qrencode == 'true')
|
||||||
have = libqrencode.found()
|
have = libqrencode.found()
|
||||||
else
|
else
|
||||||
|
|
|
@ -5,12 +5,45 @@
|
||||||
#if HAVE_QRENCODE
|
#if HAVE_QRENCODE
|
||||||
#include <qrencode.h>
|
#include <qrencode.h>
|
||||||
|
|
||||||
|
#include "alloc-util.h"
|
||||||
#include "dlfcn-util.h"
|
#include "dlfcn-util.h"
|
||||||
#include "locale-util.h"
|
#include "locale-util.h"
|
||||||
#include "terminal-util.h"
|
#include "terminal-util.h"
|
||||||
|
|
||||||
#define ANSI_WHITE_ON_BLACK "\033[40;37;1m"
|
#define ANSI_WHITE_ON_BLACK "\033[40;37;1m"
|
||||||
|
|
||||||
|
static void *qrcode_dl = NULL;
|
||||||
|
|
||||||
|
static QRcode* (*sym_QRcode_encodeString)(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive) = NULL;
|
||||||
|
static void (*sym_QRcode_free)(QRcode *qrcode) = NULL;
|
||||||
|
|
||||||
|
int dlopen_qrencode(void) {
|
||||||
|
_cleanup_(dlclosep) void *dl = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if (qrcode_dl)
|
||||||
|
return 0; /* Already loaded */
|
||||||
|
|
||||||
|
dl = dlopen("libqrencode.so.4", RTLD_LAZY);
|
||||||
|
if (!dl)
|
||||||
|
return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
|
||||||
|
"libqrcode support is not installed: %s", dlerror());
|
||||||
|
|
||||||
|
r = dlsym_many_and_warn(
|
||||||
|
dl,
|
||||||
|
LOG_DEBUG,
|
||||||
|
DLSYM_ARG(QRcode_encodeString),
|
||||||
|
DLSYM_ARG(QRcode_free),
|
||||||
|
NULL);
|
||||||
|
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. */
|
||||||
|
qrcode_dl = TAKE_PTR(dl);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static void print_border(FILE *output, unsigned width) {
|
static void print_border(FILE *output, unsigned width) {
|
||||||
/* Four rows of border */
|
/* Four rows of border */
|
||||||
for (unsigned y = 0; y < 4; y += 2) {
|
for (unsigned y = 0; y < 4; y += 2) {
|
||||||
|
@ -65,9 +98,6 @@ static void write_qrcode(FILE *output, QRcode *qr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int print_qrcode(FILE *out, const char *header, const char *string) {
|
int print_qrcode(FILE *out, const char *header, const char *string) {
|
||||||
QRcode* (*sym_QRcode_encodeString)(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive);
|
|
||||||
void (*sym_QRcode_free)(QRcode *qrcode);
|
|
||||||
_cleanup_(dlclosep) void *dl = NULL;
|
|
||||||
QRcode* qr;
|
QRcode* qr;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
@ -76,17 +106,7 @@ int print_qrcode(FILE *out, const char *header, const char *string) {
|
||||||
if (!is_locale_utf8() || !colors_enabled())
|
if (!is_locale_utf8() || !colors_enabled())
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
dl = dlopen("libqrencode.so.4", RTLD_LAZY);
|
r = dlopen_qrencode();
|
||||||
if (!dl)
|
|
||||||
return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
|
|
||||||
"QRCODE support is not installed: %s", dlerror());
|
|
||||||
|
|
||||||
r = dlsym_many_and_warn(
|
|
||||||
dl,
|
|
||||||
LOG_DEBUG,
|
|
||||||
DLSYM_ARG(QRcode_encodeString),
|
|
||||||
DLSYM_ARG(QRcode_free),
|
|
||||||
NULL);
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#if HAVE_QRENCODE
|
#if HAVE_QRENCODE
|
||||||
|
int dlopen_qrencode(void);
|
||||||
|
|
||||||
int print_qrcode(FILE *out, const char *header, const char *string);
|
int print_qrcode(FILE *out, const char *header, const char *string);
|
||||||
#else
|
#else
|
||||||
static inline int print_qrcode(FILE *out, const char *header, const char *string) {
|
static inline int print_qrcode(FILE *out, const char *header, const char *string) {
|
||||||
|
|
|
@ -71,6 +71,10 @@ tests += [
|
||||||
libshared],
|
libshared],
|
||||||
[]],
|
[]],
|
||||||
|
|
||||||
|
[['src/test/test-dlopen-so.c'],
|
||||||
|
[libshared],
|
||||||
|
[]],
|
||||||
|
|
||||||
[['src/test/test-job-type.c'],
|
[['src/test/test-job-type.c'],
|
||||||
[libcore,
|
[libcore,
|
||||||
libshared],
|
libshared],
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
|
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "cryptsetup-util.h"
|
||||||
|
#include "idn-util.h"
|
||||||
|
#include "macro.h"
|
||||||
|
#include "main-func.h"
|
||||||
|
#include "pwquality-util.h"
|
||||||
|
#include "qrcode-util.h"
|
||||||
|
#include "tests.h"
|
||||||
|
|
||||||
|
static int run(int argc, char **argv) {
|
||||||
|
test_setup_logging(LOG_DEBUG);
|
||||||
|
|
||||||
|
/* Try to load each of our weak library dependencies once. This is supposed to help finding cases
|
||||||
|
* where .so versions change and distributions update, but systemd doesn't have the new so names
|
||||||
|
* around yet. */
|
||||||
|
|
||||||
|
#if HAVE_LIBIDN2 || HAVE_LIBIDN
|
||||||
|
assert_se(dlopen_idn() >= 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_LIBCRYPTSETUP
|
||||||
|
assert_se(dlopen_cryptsetup() >= 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_PWQUALITY
|
||||||
|
assert_se(dlopen_pwquality() >= 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_QRENCODE
|
||||||
|
assert_se(dlopen_qrencode() >= 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_MAIN_FUNCTION(run);
|
|
@ -676,6 +676,19 @@ install_missing_libraries() {
|
||||||
for i in $initdir{,/usr}/{sbin,bin}/* $initdir{,/usr}/lib/systemd/{,tests/{,manual/,unsafe/}}*; do
|
for i in $initdir{,/usr}/{sbin,bin}/* $initdir{,/usr}/lib/systemd/{,tests/{,manual/,unsafe/}}*; do
|
||||||
LD_LIBRARY_PATH="${LD_LIBRARY_PATH:+$LD_LIBRARY_PATH:}$(get_ldpath $i):$(get_ldpath $i)/src/udev" inst_libs $i
|
LD_LIBRARY_PATH="${LD_LIBRARY_PATH:+$LD_LIBRARY_PATH:}$(get_ldpath $i):$(get_ldpath $i)/src/udev" inst_libs $i
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# A number of dependencies is now optional via dlopen, so the install
|
||||||
|
# script will not pick them up, since it looks at linkage.
|
||||||
|
for lib in libcryptsetup libidn libidn2 pwquality libqrencode; do
|
||||||
|
if pkg-config --exists ${lib}; then
|
||||||
|
path=$(pkg-config --variable=libdir ${lib})
|
||||||
|
if ! [[ ${lib} =~ ^lib ]]; then
|
||||||
|
lib="lib${lib}"
|
||||||
|
fi
|
||||||
|
inst_libs "${path}/${lib}.so"
|
||||||
|
inst_library "${path}/${lib}.so"
|
||||||
|
fi
|
||||||
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup_loopdev() {
|
cleanup_loopdev() {
|
||||||
|
|
Loading…
Reference in New Issue