Original-From: Frederic Crozat Original-Date: Fri, 19 Aug 2011 15:29:49 +0000 Subject: handle disable_caplock and compose_table and kbd_rate References: https://bugzilla.opensuse.org/746595 Last-Editor: Jan Engelhardt Date: Fri Jun 19 21:36:27 CEST 2015 --- src/vconsole/vconsole-setup.c | 151 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 147 insertions(+), 4 deletions(-) Index: systemd-228/src/vconsole/vconsole-setup.c =================================================================== --- systemd-228.orig/src/vconsole/vconsole-setup.c +++ systemd-228/src/vconsole/vconsole-setup.c @@ -34,6 +34,8 @@ #include "alloc-util.h" #include "fd-util.h" #include "fileio.h" +#include "macro.h" +#include "strv.h" #include "io-util.h" #include "locale-util.h" #include "log.h" @@ -104,8 +106,10 @@ static int enable_utf8(int fd) { return r; } -static int keyboard_load_and_wait(const char *vc, const char *map, const char *map_toggle, bool utf8) { - const char *args[8]; +static int keyboard_load_and_wait(const char *vc, const char *map, + const char *map_toggle, bool utf8, bool disable_capslock) +{ + const char *args[9]; int i = 0, r; pid_t pid; @@ -122,6 +126,8 @@ static int keyboard_load_and_wait(const args[i++] = map; if (map_toggle) args[i++] = map_toggle; + if (disable_capslock) + args[i++] = "disable.capslock"; args[i++] = NULL; pid = fork(); @@ -251,11 +257,117 @@ static void font_copy_to_all_vcs(int fd) } } +#ifdef HAVE_SYSV_COMPAT +static int compose_load_and_wait(const char *vc, const char *compose_table) +{ + const char *args[1024]; + unsigned int i = 0, j = 0; + int ret; + pid_t pid; + char **strv_compose_table = NULL; + char *to_free[1024]; + + if (isempty(compose_table)) + /* An empty map means no compose table */ + return 1; + + args[i++] = KBD_LOADKEYS; + args[i++] = "-q"; + args[i++] = "-C"; + args[i++] = vc; + + strv_compose_table = strv_split(compose_table, WHITESPACE); + if (strv_compose_table) { + bool compose_loaded = false; + bool compose_clear = false; + char **name; + char *arg; + + STRV_FOREACH(name, strv_compose_table) { + if (streq(*name, "-c") || streq(*name, "clear")) { + compose_clear = true; + continue; + } + if (!compose_loaded && compose_clear) + args[i++] = "-c"; + asprintf(&arg, "compose.%s", *name); + compose_loaded = true; + args[i++] = to_free[j++] = arg; + if (i >= ELEMENTSOF(args) - 1) + break; + } + strv_free(strv_compose_table); + } + args[i++] = NULL; + + pid = fork(); + if (pid < 0) + return log_error_errno(errno, "Failed to fork: %m"); + if (pid == 0) { + reset_all_signal_handlers(); + reset_signal_mask(); + execv(args[0], (char **) args); + _exit(EXIT_FAILURE); + } + + ret = wait_for_terminate_and_warn(args[0], pid, true); + for (i = 0; i < j; ++i) + free(to_free[i]); + if (ret < 0) + return ret; + return ret == 0; +} +#endif + +static int kbdrate_set_and_wait(const char *vc, const char *kbd_rate, + const char *kbd_delay) +{ + const char *args[7]; + int i = 0, ret; + pid_t pid; + + if (isempty(kbd_rate) && isempty(kbd_delay)) + return 1; + + args[i++] = "/bin/kbdrate"; + if (!isempty(kbd_rate)) { + args[i++] = "-r"; + args[i++] = kbd_rate; + } + if (!isempty(kbd_delay)) { + args[i++] = "-d"; + args[i++] = kbd_delay; + } + args[i++] = "-s"; + args[i++] = NULL; + + pid = fork(); + if (pid < 0) + return log_error_errno(errno, "Failed to fork: %m"); + if (pid == 0) { + reset_all_signal_handlers(); + reset_signal_mask(); + execv(args[0], (char **) args); + _exit(EXIT_FAILURE); + } + ret = wait_for_terminate_and_warn(args[0], pid, true); + if (ret < 0) + return ret; + return ret == 0; +} + int main(int argc, char **argv) { const char *vc; _cleanup_free_ char *vc_keymap = NULL, *vc_keymap_toggle = NULL, *vc_font = NULL, *vc_font_map = NULL, *vc_font_unimap = NULL; +#ifdef HAVE_SYSV_COMPAT + _cleanup_free_ char + *vc_kbd_delay = NULL, *vc_kbd_rate = NULL, + *vc_kbd_disable_caps_lock = NULL, *vc_compose_table = NULL; +#endif + bool disable_capslock = false; + bool comp_ok, rate_ok; _cleanup_close_ int fd = -1; bool utf8, font_copy = false, font_ok, keyboard_ok; int r = EXIT_FAILURE; @@ -286,6 +398,31 @@ int main(int argc, char **argv) { utf8 = is_locale_utf8(); +#ifdef HAVE_SYSV_COMPAT + r = parse_env_file("/etc/sysconfig/keyboard", NEWLINE, + "KEYTABLE", &vc_keymap, + "KBD_DELAY", &vc_kbd_delay, + "KBD_RATE", &vc_kbd_rate, + "KBD_DISABLE_CAPS_LOCK", &vc_kbd_disable_caps_lock, + "COMPOSETABLE", &vc_compose_table, + NULL); + if (r < 0 && r != -ENOENT) + log_warning("Failed to read /etc/sysconfig/keyboard: %s", + strerror(-r)); + + r = parse_env_file("/etc/sysconfig/console", NEWLINE, + "CONSOLE_FONT", &vc_font, + "CONSOLE_SCREENMAP", &vc_font_map, + "CONSOLE_UNICODEMAP", &vc_font_unimap, + NULL); + if (r < 0 && r != -ENOENT) + log_warning("Failed to read /etc/sysconfig/console: %s", + strerror(-r)); + + disable_capslock = vc_kbd_disable_caps_lock && + strcasecmp(vc_kbd_disable_caps_lock, "YES") == 0; +#endif /* HAVE_SYSV_COMPAT */ + r = parse_env_file("/etc/vconsole.conf", NEWLINE, "KEYMAP", &vc_keymap, "KEYMAP_TOGGLE", &vc_keymap_toggle, @@ -317,11 +454,17 @@ int main(int argc, char **argv) { (void) disable_utf8(fd); font_ok = font_load_and_wait(vc, vc_font, vc_font_map, vc_font_unimap) > 0; - keyboard_ok = keyboard_load_and_wait(vc, vc_keymap, vc_keymap_toggle, utf8) > 0; + keyboard_ok = keyboard_load_and_wait(vc, vc_keymap, vc_keymap_toggle, + utf8, disable_capslock) > 0; +#ifdef HAVE_SYSV_COMPAT + comp_ok = compose_load_and_wait(vc, vc_compose_table); + rate_ok = kbdrate_set_and_wait(vc, vc_kbd_rate, vc_kbd_delay); +#endif /* Only copy the font when we executed setfont successfully */ if (font_copy && font_ok) (void) font_copy_to_all_vcs(fd); - return font_ok && keyboard_ok ? EXIT_SUCCESS : EXIT_FAILURE; + return font_ok && keyboard_ok && comp_ok && rate_ok ? + EXIT_SUCCESS : EXIT_FAILURE; }