diff options
author | Lennart Poettering <lennart@poettering.net> | 2020-12-07 14:09:37 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2020-12-09 13:34:27 +0100 |
commit | ad914843c6072d64a8e265bb3fda1c1d61f46df6 (patch) | |
tree | 77ecbc1559b4bdf10f7c906f28babb1152cad3de | |
parent | manager: Fix HW watchdog when systemd starts before driver loaded (diff) | |
download | systemd-ad914843c6072d64a8e265bb3fda1c1d61f46df6.tar.xz systemd-ad914843c6072d64a8e265bb3fda1c1d61f46df6.zip |
qrcode-util: make dlopen() logic more like the other cases
Let's add a dlopen_qrencode() function that does the actual dlopen()
stuff and caches the result.
This is useful so that we later can automatically test for all dlopen
hookups to work correctly.
-rw-r--r-- | src/shared/qrcode-util.c | 48 | ||||
-rw-r--r-- | src/shared/qrcode-util.h | 2 |
2 files changed, 36 insertions, 14 deletions
diff --git a/src/shared/qrcode-util.c b/src/shared/qrcode-util.c index f7d2d984c9..6b9ff8531b 100644 --- a/src/shared/qrcode-util.c +++ b/src/shared/qrcode-util.c @@ -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; diff --git a/src/shared/qrcode-util.h b/src/shared/qrcode-util.h index 6fc45c93d1..b64ecce80a 100644 --- a/src/shared/qrcode-util.h +++ b/src/shared/qrcode-util.h @@ -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) { |