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.
This commit is contained in:
Lennart Poettering 2020-12-07 14:09:37 +01:00
parent 61927b9f11
commit ad914843c6
2 changed files with 36 additions and 14 deletions

View 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;

View 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) {