locale: use O_PATH directory fd and faccessat() in find_converted_keymap()

Previously, it is assumed that the paths in KBD_KEYMAP_DIRS are ended
with a slash. But, in the next commit, paths will become controllable by
users, and each path may not be ended with a slash.

This should not change any effective behaviors.
Just refactoring and preparation.
This commit is contained in:
Yu Watanabe
2024-03-15 03:15:57 +09:00
parent f63c1ada25
commit 361c5b4beb
+16 -9
View File
@@ -735,7 +735,7 @@ 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;
assert(xc);
assert(!isempty(xc->layout));
@@ -748,18 +748,25 @@ int find_converted_keymap(const X11Context *xc, char **ret) {
if (!n)
return -ENOMEM;
p = strjoin("xkb/", n, ".map");
pz = strjoin("xkb/", n, ".map.gz");
if (!p || !pz)
return -ENOMEM;
NULSTR_FOREACH(dir, KBD_KEYMAP_DIRS) {
_cleanup_free_ char *p = NULL, *pz = NULL;
_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;
}