diff options
Diffstat (limited to 'src/locale')
-rw-r--r-- | src/locale/localed-util.c | 35 | ||||
-rw-r--r-- | src/locale/localed.c | 48 | ||||
-rw-r--r-- | src/locale/xkbcommon-util.c | 23 | ||||
-rw-r--r-- | src/locale/xkbcommon-util.h | 21 |
4 files changed, 60 insertions, 67 deletions
diff --git a/src/locale/localed-util.c b/src/locale/localed-util.c index e4e57a0..5699659 100644 --- a/src/locale/localed-util.c +++ b/src/locale/localed-util.c @@ -304,7 +304,7 @@ void context_clear(Context *c) { c->x11_cache = sd_bus_message_unref(c->x11_cache); c->vc_cache = sd_bus_message_unref(c->vc_cache); - c->polkit_registry = bus_verify_polkit_async_registry_free(c->polkit_registry); + c->polkit_registry = hashmap_free(c->polkit_registry); }; X11Context *context_get_x11_context(Context *c) { @@ -735,7 +735,9 @@ int vconsole_convert_to_x11(const VCContext *vc, X11Context *ret) { } int find_converted_keymap(const X11Context *xc, char **ret) { - _cleanup_free_ char *n = NULL; + _cleanup_free_ char *n = NULL, *p = NULL, *pz = NULL; + _cleanup_strv_free_ char **keymap_dirs = NULL; + int r; assert(xc); assert(!isempty(xc->layout)); @@ -748,18 +750,29 @@ int find_converted_keymap(const X11Context *xc, char **ret) { if (!n) return -ENOMEM; - NULSTR_FOREACH(dir, KBD_KEYMAP_DIRS) { - _cleanup_free_ char *p = NULL, *pz = NULL; + p = strjoin("xkb/", n, ".map"); + pz = strjoin("xkb/", n, ".map.gz"); + if (!p || !pz) + return -ENOMEM; + + r = keymap_directories(&keymap_dirs); + if (r < 0) + return r; + + STRV_FOREACH(dir, keymap_dirs) { + _cleanup_close_ int dir_fd = -EBADF; bool uncompressed; - p = strjoin(dir, "xkb/", n, ".map"); - pz = strjoin(dir, "xkb/", n, ".map.gz"); - if (!p || !pz) - return -ENOMEM; + dir_fd = open(*dir, O_CLOEXEC | O_DIRECTORY | O_PATH); + if (dir_fd < 0) { + if (errno != ENOENT) + log_debug_errno(errno, "Failed to open %s, ignoring: %m", *dir); + continue; + } - uncompressed = access(p, F_OK) == 0; - if (uncompressed || access(pz, F_OK) == 0) { - log_debug("Found converted keymap %s at %s", n, uncompressed ? p : pz); + uncompressed = faccessat(dir_fd, p, F_OK, 0) >= 0; + if (uncompressed || faccessat(dir_fd, pz, F_OK, 0) >= 0) { + log_debug("Found converted keymap %s at %s/%s", n, *dir, uncompressed ? p : pz); *ret = TAKE_PTR(n); return 1; } diff --git a/src/locale/localed.c b/src/locale/localed.c index 5d96237..c0d1045 100644 --- a/src/locale/localed.c +++ b/src/locale/localed.c @@ -15,6 +15,7 @@ #include "bus-polkit.h" #include "bus-unit-util.h" #include "constants.h" +#include "daemon-util.h" #include "kbd-util.h" #include "localed-util.h" #include "macro.h" @@ -157,11 +158,7 @@ static int process_locale_list_item( if (new_locale[p]) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Locale variable %s set twice, refusing.", name); - new_locale[p] = strdup(e); - if (!new_locale[p]) - return -ENOMEM; - - return 0; + return strdup_to(&new_locale[p], e); } return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Locale assignment %s not valid, refusing.", assignment); @@ -281,13 +278,12 @@ static int method_set_locale(sd_bus_message *m, void *userdata, sd_bus_error *er return sd_bus_reply_method_return(m, NULL); } - r = bus_verify_polkit_async( + r = bus_verify_polkit_async_full( m, - CAP_SYS_ADMIN, "org.freedesktop.locale1.set-locale", - NULL, - interactive, - UID_INVALID, + /* details= */ NULL, + /* good_user= */ UID_INVALID, + interactive ? POLKIT_ALLOW_INTERACTIVE : 0, &c->polkit_registry, error); if (r < 0) @@ -386,13 +382,12 @@ static int method_set_vc_keyboard(sd_bus_message *m, void *userdata, sd_bus_erro if (vc_context_equal(&c->vc, &in) && !x_needs_update) return sd_bus_reply_method_return(m, NULL); - r = bus_verify_polkit_async( + r = bus_verify_polkit_async_full( m, - CAP_SYS_ADMIN, "org.freedesktop.locale1.set-keyboard", - NULL, - interactive, - UID_INVALID, + /* details= */ NULL, + /* good_user= */ UID_INVALID, + interactive ? POLKIT_ALLOW_INTERACTIVE : 0, &c->polkit_registry, error); if (r < 0) @@ -506,13 +501,12 @@ static int method_set_x11_keyboard(sd_bus_message *m, void *userdata, sd_bus_err if (x11_context_equal(&c->x11_from_vc, &in) && x11_context_equal(&c->x11_from_xorg, &in) && !convert) return sd_bus_reply_method_return(m, NULL); - r = bus_verify_polkit_async( + r = bus_verify_polkit_async_full( m, - CAP_SYS_ADMIN, "org.freedesktop.locale1.set-keyboard", - NULL, - interactive, - UID_INVALID, + /* details= */ NULL, + /* good_user= */ UID_INVALID, + interactive ? POLKIT_ALLOW_INTERACTIVE : 0, &c->polkit_registry, error); if (r < 0) @@ -650,26 +644,24 @@ static int run(int argc, char *argv[]) { if (r < 0) return r; - assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, -1) >= 0); - r = sd_event_default(&event); if (r < 0) return log_error_errno(r, "Failed to allocate event loop: %m"); (void) sd_event_set_watchdog(event, true); - r = sd_event_add_signal(event, NULL, SIGINT, NULL, NULL); - if (r < 0) - return log_error_errno(r, "Failed to install SIGINT handler: %m"); - - r = sd_event_add_signal(event, NULL, SIGTERM, NULL, NULL); + r = sd_event_set_signal_exit(event, true); if (r < 0) - return log_error_errno(r, "Failed to install SIGTERM handler: %m"); + return log_error_errno(r, "Failed to install SIGINT/SIGTERM handlers: %m"); r = connect_bus(&context, event, &bus); if (r < 0) return r; + r = sd_notify(false, NOTIFY_READY); + if (r < 0) + log_warning_errno(r, "Failed to send readiness notification, ignoring: %m"); + r = bus_event_loop_with_idle(event, bus, "org.freedesktop.locale1", DEFAULT_EXIT_USEC, NULL, NULL); if (r < 0) return log_error_errno(r, "Failed to run event loop: %m"); diff --git a/src/locale/xkbcommon-util.c b/src/locale/xkbcommon-util.c index 295ac8a..d4e24cd 100644 --- a/src/locale/xkbcommon-util.c +++ b/src/locale/xkbcommon-util.c @@ -9,22 +9,17 @@ #if HAVE_XKBCOMMON static void *xkbcommon_dl = NULL; -struct xkb_context* (*sym_xkb_context_new)(enum xkb_context_flags flags); -void (*sym_xkb_context_unref)(struct xkb_context *context); -void (*sym_xkb_context_set_log_fn)( - struct xkb_context *context, - void (*log_fn)( - struct xkb_context *context, - enum xkb_log_level level, - const char *format, - va_list args)); -struct xkb_keymap* (*sym_xkb_keymap_new_from_names)( - struct xkb_context *context, - const struct xkb_rule_names *names, - enum xkb_keymap_compile_flags flags); -void (*sym_xkb_keymap_unref)(struct xkb_keymap *keymap); +DLSYM_FUNCTION(xkb_context_new); +DLSYM_FUNCTION(xkb_context_unref); +DLSYM_FUNCTION(xkb_context_set_log_fn); +DLSYM_FUNCTION(xkb_keymap_new_from_names); +DLSYM_FUNCTION(xkb_keymap_unref); static int dlopen_xkbcommon(void) { + ELF_NOTE_DLOPEN("xkbcommon", + "Support for keyboard locale descriptions", + ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, "libxkbcommon.so.0"); + return dlopen_many_sym_or_warn( &xkbcommon_dl, "libxkbcommon.so.0", LOG_DEBUG, DLSYM_ARG(xkb_context_new), diff --git a/src/locale/xkbcommon-util.h b/src/locale/xkbcommon-util.h index e99c2d7..92f45c2 100644 --- a/src/locale/xkbcommon-util.h +++ b/src/locale/xkbcommon-util.h @@ -1,23 +1,16 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #pragma once +#include "dlfcn-util.h" + #if HAVE_XKBCOMMON #include <xkbcommon/xkbcommon.h> -extern struct xkb_context* (*sym_xkb_context_new)(enum xkb_context_flags flags); -extern void (*sym_xkb_context_unref)(struct xkb_context *context); -extern void (*sym_xkb_context_set_log_fn)( - struct xkb_context *context, - void (*log_fn)( - struct xkb_context *context, - enum xkb_log_level level, - const char *format, - va_list args)); -extern struct xkb_keymap* (*sym_xkb_keymap_new_from_names)( - struct xkb_context *context, - const struct xkb_rule_names *names, - enum xkb_keymap_compile_flags flags); -extern void (*sym_xkb_keymap_unref)(struct xkb_keymap *keymap); +DLSYM_PROTOTYPE(xkb_context_new); +DLSYM_PROTOTYPE(xkb_context_unref); +DLSYM_PROTOTYPE(xkb_context_set_log_fn); +DLSYM_PROTOTYPE(xkb_keymap_new_from_names); +DLSYM_PROTOTYPE(xkb_keymap_unref); int verify_xkb_rmlvo(const char *model, const char *layout, const char *variant, const char *options); |