summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2020-12-07 14:09:37 +0100
committerLennart Poettering <lennart@poettering.net>2020-12-09 13:34:27 +0100
commitad914843c6072d64a8e265bb3fda1c1d61f46df6 (patch)
tree77ecbc1559b4bdf10f7c906f28babb1152cad3de
parentmanager: Fix HW watchdog when systemd starts before driver loaded (diff)
downloadsystemd-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.c48
-rw-r--r--src/shared/qrcode-util.h2
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) {