summaryrefslogtreecommitdiffstats
path: root/src/shared/kbd-util.c
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2021-03-04 10:42:53 +0100
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2021-03-04 11:44:07 +0100
commit3864b4b038b4c8213cbe0ed60281217c37e0a426 (patch)
tree58709f52fe806dd588d2bc2a952721a378d1e27a /src/shared/kbd-util.c
parentMove basic/kbd-util to shared/ (diff)
downloadsystemd-3864b4b038b4c8213cbe0ed60281217c37e0a426.tar.xz
systemd-3864b4b038b4c8213cbe0ed60281217c37e0a426.zip
shared/kbd-util: fix return value confusion with nftw()
We would return a real error sometimes from the callback, and FTW_STOP other times. Because of FTW_ACTIONRETVAL, everything except FTW_STOP would be ignored. I don't think using FTW_ACTIONRETVAL is useful. nftw() can only be used meaningfully with errno. Even if we return a proper value ourselves from the callback, it will be propagated as a return value from nftw(), but there is no way to distinguish this from a value generated by nftw() itself, which is -1/-EPERM on error. So let's set errno ourselves so the caller can at least look at that. The code still ignores all errors.
Diffstat (limited to 'src/shared/kbd-util.c')
-rw-r--r--src/shared/kbd-util.c42
1 files changed, 19 insertions, 23 deletions
diff --git a/src/shared/kbd-util.c b/src/shared/kbd-util.c
index 79ae962530..fb98dd262e 100644
--- a/src/shared/kbd-util.c
+++ b/src/shared/kbd-util.c
@@ -31,14 +31,14 @@ static int nftw_cb(
return 0;
p = strdup(basename(fpath));
- if (!p)
- return FTW_STOP;
+ if (!p) {
+ errno = ENOMEM;
+ return -1;
+ }
e = endswith(p, ".map");
- if (e)
- *e = 0;
-
- e = endswith(p, ".map.gz");
+ if (!e)
+ e = endswith(p, ".map.gz");
if (e)
*e = 0;
@@ -46,37 +46,33 @@ static int nftw_cb(
return 0;
r = set_consume(keymaps, TAKE_PTR(p));
- if (r < 0 && r != -EEXIST)
- return r;
+ if (r < 0 && r != -EEXIST) {
+ errno = -r;
+ return -1;
+ }
return 0;
}
int get_keymaps(char ***ret) {
- _cleanup_strv_free_ char **l = NULL;
- const char *dir;
- int r;
-
keymaps = set_new(&string_hash_ops);
if (!keymaps)
return -ENOMEM;
- NULSTR_FOREACH(dir, KBD_KEYMAP_DIRS) {
- r = nftw(dir, nftw_cb, 20, FTW_PHYS|FTW_ACTIONRETVAL);
-
- if (r == FTW_STOP)
- log_debug("Directory not found %s", dir);
- else if (r < 0)
- log_debug_errno(r, "Can't add keymap: %m");
- }
+ const char *dir;
+ NULSTR_FOREACH(dir, KBD_KEYMAP_DIRS)
+ if (nftw(dir, nftw_cb, 20, FTW_PHYS) < 0) {
+ if (errno != ENOENT)
+ log_debug_errno(errno, "Failed to read keymap list from %s, ignoring: %m", dir);
+ }
- l = set_get_strv(keymaps);
+ _cleanup_strv_free_ char **l = set_get_strv(keymaps);
if (!l) {
- set_free_free(keymaps);
+ keymaps = set_free_free(keymaps);
return -ENOMEM;
}
- set_free(keymaps);
+ keymaps = set_free(keymaps);
if (strv_isempty(l))
return -ENOENT;