mirror of
https://github.com/systemd/systemd.git
synced 2025-01-25 10:04:04 +03:00
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')
|
||||
if want_qrencode != 'false' and not skip_deps
|
||||
libqrencode = dependency('libqrencode',
|
||||
version : '>= 4',
|
||||
required : want_qrencode == 'true')
|
||||
have = libqrencode.found()
|
||||
else
|
||||
|
@ -5,12 +5,45 @@
|
||||
#if HAVE_QRENCODE
|
||||
#include <qrencode.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "dlfcn-util.h"
|
||||
#include "locale-util.h"
|
||||
#include "terminal-util.h"
|
||||
|
||||
#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) {
|
||||
/* Four rows of border */
|
||||
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) {
|
||||
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;
|
||||
int r;
|
||||
|
||||
@ -76,17 +106,7 @@ int print_qrcode(FILE *out, const char *header, const char *string) {
|
||||
if (!is_locale_utf8() || !colors_enabled())
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
dl = dlopen("libqrencode.so.4", RTLD_LAZY);
|
||||
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);
|
||||
r = dlopen_qrencode();
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
@ -5,6 +5,8 @@
|
||||
#include <errno.h>
|
||||
|
||||
#if HAVE_QRENCODE
|
||||
int dlopen_qrencode(void);
|
||||
|
||||
int print_qrcode(FILE *out, const char *header, const char *string);
|
||||
#else
|
||||
static inline int print_qrcode(FILE *out, const char *header, const char *string) {
|
||||
|
@ -71,6 +71,10 @@ tests += [
|
||||
libshared],
|
||||
[]],
|
||||
|
||||
[['src/test/test-dlopen-so.c'],
|
||||
[libshared],
|
||||
[]],
|
||||
|
||||
[['src/test/test-job-type.c'],
|
||||
[libcore,
|
||||
libshared],
|
||||
|
40
src/test/test-dlopen-so.c
Normal file
40
src/test/test-dlopen-so.c
Normal file
@ -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
|
||||
LD_LIBRARY_PATH="${LD_LIBRARY_PATH:+$LD_LIBRARY_PATH:}$(get_ldpath $i):$(get_ldpath $i)/src/udev" inst_libs $i
|
||||
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() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user