legionus / kbd

Mirror of https://git.kernel.org/pub/scm/linux/kernel/git/legion/kbd.git
https://kbd-project.org
Other
85 stars 40 forks source link

'loadkeys -d' from 2.1.0 and 2.2.0 throws syntax error, unexpected ERROR #31

Closed KIC-8462852 closed 5 years ago

KIC-8462852 commented 5 years ago

Hi,

'loadkeys -d' loads defkeymap (e.g. 'defkeymap.map.gz') and if this filename is a symlink (e.g. '/usr/share/kbd/keymaps/defkeymap.map.gz -> /usr/share/kbd/keymaps/i386/qwerty/pt-latin1.map.gz') it also looks for includes near its target (i.e. as of this example in '/usr/share/kbd/keymaps/i386/include' dir). 'find_standard_incl_file' uses 'readlink' and then calls 'find_incl_file_near_fn'. However, as of 2.1.0 and 2.2.0, in this situation the readlink code is never reached and thus 'loadkeys -d' is unable to load the includes from the location near the symlink target. Example, having the following:

/usr/share/kbd/keymaps/defkeymap.map.gz -> i386/qwerty/pt-latin1.map.gz /usr/share/kbd/keymaps/i386/include/... /usr/share/kbd/keymaps/i386/qwerty/...

/usr/share/kbd/keymaps
|-- defkeymap.map.gz -> i386/qwerty/pt-latin1.map.gz
`-- i386
    |-- include
    |   |-- (...)
    |   |-- linux-keys-bare.inc
    |   |-- linux-with-alt-and-altgr.inc
    |   |-- qwerty-layout.inc
    |   |-- (...)
    |   |-- unicode.map.gz
    |   `-- windowkeys.map.gz
    `-- qwerty
        |-- (...)
        |-- pt-latin1.map.gz
        |-- pt-latin9.map.gz
        |-- (...)
        |-- us-acentos.map.gz
        `-- us.map.gz

'loadkeys -d' loads the keymap 'i386/qwerty/pt-latin1.map.gz' and then fails finding the first declared include file 'qwerty-layout' that should be found at 'i386/include/' terminating the execution:

~# loadkeys -d -v Loading defkeymap.map.gz switching to qwerty-layout syntax error, unexpected ERROR

(...)
open(".", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_CLOEXEC|O_DIRECTORY) = 4
fstat64(4, {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
getdents(4, /* 10 entries */, 32768)    = 184
getdents(4, /* 0 entries */, 32768)     = 0
close(4)                                = 0
stat64("./amiga", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat64("./atari", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat64("./defkeymap.map.gz", {st_mode=S_IFREG|0644, st_size=989, ...}) = 0
stat64("./i386", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat64("./include", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat64("./mac", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat64("./ppc", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat64("./sun", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
pipe2([4, 5], O_CLOEXEC)                = 0
clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0xb7dbf768) = 22689
close(5)                                = 0
fcntl64(4, F_SETFD, 0)                  = 0
fstat64(4, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
read(4, "# Derived from pt.map by lacyp@u"..., 4096) = 2696
read(4, "", 4096)                       = 0
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=22689, si_uid=0, si_status=0, si_utime=0, si_stime=0} ---
stat64("qwerty-layout", 0xbfd0e980)     = -1 ENOENT (No such file or directory)
open(".", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_CLOEXEC|O_DIRECTORY) = 5
fstat64(5, {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
getdents(5, /* 10 entries */, 32768)    = 184
getdents(5, /* 0 entries */, 32768)     = 0
close(5)                                = 0
stat64("./amiga", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat64("./atari", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat64("./defkeymap.map.gz", {st_mode=S_IFREG|0644, st_size=989, ...}) = 0
stat64("./i386", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat64("./include", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat64("./mac", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat64("./ppc", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat64("./sun", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
open("../include", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_CLOEXEC|O_DIRECTORY) = -1 ENOENT (No such file or directory)
write(2, "scandir: No such file or directo"..., 34scandir: No such file or directory) = 34
write(2, "\n", 1
)                       = 1
stat64("qwerty-layout", 0xbfd0e930)     = -1 ENOENT (No such file or directory)
open(".", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_CLOEXEC|O_DIRECTORY) = 5
fstat64(5, {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
getdents(5, /* 10 entries */, 32768)    = 184
getdents(5, /* 0 entries */, 32768)     = 0
close(5)                                = 0
stat64("./amiga", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat64("./atari", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat64("./defkeymap.map.gz", {st_mode=S_IFREG|0644, st_size=989, ...}) = 0
stat64("./i386", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat64("./include", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat64("./mac", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat64("./ppc", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat64("./sun", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
open("./../include", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_CLOEXEC|O_DIRECTORY) = -1 ENOENT (No such file or directory)
write(2, "scandir: No such file or directo"..., 34scandir: No such file or directory) = 34
write(2, "\n", 1
)                       = 1
write(2, "syntax error, unexpected ERROR", 30syntax error, unexpected ERROR) = 30
write(2, "\n", 1
)                       = 1
close(4)                                = 0
wait4(22689, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 22689
close(3)                                = 0
exit_group(1)                           = ?
+++ exited with 1 +++

The following patch restores the expected behavior.

kbd-2.2.0.patch

Signed-off-by: Jose P Santos <j.ps@member.fsf.org>

--- src/libkbdfile/kbdfile.c.orig       2019-07-26 13:26:24.000000000 +0100
+++ src/libkbdfile/kbdfile.c    2019-08-02 20:24:47.549574629 +0100
@@ -433,8 +433,8 @@
                rc = findfile_in_dir(fnam, dir, recdepth, suffixes, fp);
                free(dir);

-               if (rc <= 0)
-                       return rc;
+               if (!rc)
+                       return 0;
        }

        return 1;

Thx, jps

legionus commented 5 years ago

@KIC-8462852 Good catch! We can't stop on first error.