]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
qrcode-util: make dlopen() logic more like the other cases
authorLennart Poettering <lennart@poettering.net>
Mon, 7 Dec 2020 13:09:37 +0000 (14:09 +0100)
committerLennart Poettering <lennart@poettering.net>
Wed, 9 Dec 2020 12:34:27 +0000 (13:34 +0100)
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.

src/shared/qrcode-util.c
src/shared/qrcode-util.h

index f7d2d984c96510688f02cb33f56c43711f18ad50..6b9ff8531bbe171a68a0cfa6b0c71fb55aa8aacb 100644 (file)
@@ -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;
 
index 6fc45c93d1a1360f50be6064c120f8e2b1daa2d8..b64ecce80a3e9590379a034af2458fc98488e6de 100644 (file)
@@ -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) {