Various dlopen/linking cleanups from #42100 (#42166)

- **bpf-util: rename from bpf-dlopen, unify version-specific symbol
handling**
- **cryptsetup: dlopen libcryptsetup in tokens**
- **tree-wide: dlopen libpam in pam plugins**
- **test-bus-marshal: dlopen() glib and libdbus instead of linking
directly**
- **lock-util: Simplify timeout for lock_generic_with_timeout()**
- **color-util: simplify hsv_to_rgb, fix rgb_to_hsv negative-hue wrap**
- **tree-wide: Use our own macros instead of fabs()/fmax()/fmin()**
- **locale-util: dlopen() libintl instead of linking against it**
- **home: Use log2u64() over log2()**
- **meson: drop libdl, threads, and librt dependencies**
- **libc: Use dlsym() from a constructor instead of weak symbols**
- **libc: Make sure C23 versions of strtol(), sscanf() are not used**
This commit is contained in:
Daan De Meyer
2026-05-19 08:54:27 +02:00
committed by GitHub
78 changed files with 802 additions and 719 deletions
+31
View File
@@ -7,7 +7,12 @@
#include <sys/stat.h>
#include <unistd.h>
#ifndef __GLIBC__
#include "sd-dlopen.h"
#endif
#include "dirent-util.h"
#include "dlfcn-util.h"
#include "env-util.h"
#include "fd-util.h"
#include "fileio.h"
@@ -22,6 +27,32 @@
#include "strv.h"
#include "utf8.h"
#ifdef __GLIBC__
DLSYM_PROTOTYPE(dgettext) = dgettext;
#else
DLSYM_PROTOTYPE(dgettext) = NULL;
#endif
int dlopen_libintl(int log_level) {
#ifdef __GLIBC__
return 1;
#else
static void *libintl_dl = NULL;
SD_ELF_NOTE_DLOPEN(
"intl",
"Support for message translation via gettext",
SD_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED,
"libintl.so.8");
return dlopen_many_sym_or_warn(
&libintl_dl,
"libintl.so.8",
log_level,
DLSYM_ARG(dgettext));
#endif
}
static char* normalize_locale(const char *name) {
const char *e;
+12 -1
View File
@@ -1,9 +1,18 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <libintl.h> /* IWYU pragma: export */
#include <locale.h> /* IWYU pragma: export */
#include "basic-forward.h"
#include "dlfcn-util.h"
/* format_arg(2) propagates the format-string nature of the second argument to the return value, so that
* printf(_("Hello %s"), name) still gets checked. It survives both DLSYM_PROTOTYPE's typeof() and the
* ternary in _() below — verified on gcc and clang. */
extern DLSYM_PROTOTYPE(dgettext) __attribute__((format_arg(2)));
int dlopen_libintl(int log_level);
typedef enum LocaleVariable {
/* We don't list LC_ALL here on purpose. People should be
@@ -31,7 +40,9 @@ int get_locales(char ***ret);
bool locale_is_valid(const char *name);
int locale_is_installed(const char *name);
#define _(String) dgettext(GETTEXT_PACKAGE, String)
/* Falls back to the untranslated string if dlopen_libintl() hasn't run or has failed, so callers don't have
* to gate every translatable message on a runtime check. */
#define _(String) (sym_dgettext ? sym_dgettext(GETTEXT_PACKAGE, (String)) : (String))
#define N_(String) String
bool is_locale_utf8(void);
+1 -26
View File
@@ -1,7 +1,6 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -227,25 +226,6 @@ int lock_generic_with_timeout(int fd, LockType type, int operation, usec_t timeo
if (r < 0)
return log_error_errno(r, "Failed to flock block device in child process: %m");
if (r == 0) {
struct sigevent sev = {
.sigev_notify = SIGEV_SIGNAL,
.sigev_signo = SIGALRM,
};
timer_t id;
if (timer_create(CLOCK_MONOTONIC, &sev, &id) < 0) {
log_error_errno(errno, "Failed to allocate CLOCK_MONOTONIC timer: %m");
_exit(EXIT_FAILURE);
}
struct itimerspec its = {};
timespec_store(&its.it_value, timeout);
if (timer_settime(id, /* flags= */ 0, &its, NULL) < 0) {
log_error_errno(errno, "Failed to start CLOCK_MONOTONIC timer: %m");
_exit(EXIT_FAILURE);
}
if (lock_generic(fd, type, operation) < 0) {
log_error_errno(errno, "Unable to get an exclusive lock on the device: %m");
_exit(EXIT_FAILURE);
@@ -255,7 +235,7 @@ int lock_generic_with_timeout(int fd, LockType type, int operation, usec_t timeo
}
siginfo_t status;
r = pidref_wait_for_terminate(&pidref, &status);
r = pidref_wait_for_terminate_full(&pidref, timeout, &status);
if (r < 0)
return r;
@@ -270,11 +250,6 @@ int lock_generic_with_timeout(int fd, LockType type, int operation, usec_t timeo
return 0;
case CLD_KILLED:
if (status.si_status == SIGALRM)
return -ETIMEDOUT;
_fallthrough_;
case CLD_DUMPED:
return -EPROTO;
-3
View File
@@ -212,15 +212,12 @@ libbasic_static = static_library(
include_directories : basic_includes,
implicit_include_directories : false,
dependencies : [libbzip2_cflags,
libdl,
libgcrypt_cflags,
liblz4_cflags,
libm,
librt,
libxz_cflags,
libz_cflags,
libzstd_cflags,
threads,
userspace],
c_args : ['-fvisibility=default'],
build_by_default : false)