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:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user