]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
locale: use O_PATH directory fd and faccessat() in find_converted_keymap()
authorYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 14 Mar 2024 18:12:07 +0000 (03:12 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 14 Mar 2024 18:15:57 +0000 (03:15 +0900)
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.

src/locale/localed-util.c

index 0489df573b593077547bf1ca3df6324fc4d3e53a..de88df163d0417d9bbeaad4b10dad2f6c70c54aa 100644 (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;
                 }