From: Frederic Crozat Date: Fri, 19 Aug 2011 15:29:49 +0000 Subject: handle disable_caplock and compose_table and kbd_rate (bnc#746595) --- src/vconsole/vconsole-setup.c | 151 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 148 insertions(+), 3 deletions(-) Index: systemd-218/src/vconsole/vconsole-setup.c =================================================================== --- systemd-218.orig/src/vconsole/vconsole-setup.c +++ systemd-218/src/vconsole/vconsole-setup.c @@ -40,6 +40,7 @@ #include "macro.h" #include "virt.h" #include "fileio.h" +#include "strv.h" static bool is_vconsole(int fd) { unsigned char data[1]; @@ -101,8 +102,8 @@ static int enable_utf8(int fd) { return r; } -static int keymap_load(const char *vc, const char *map, const char *map_toggle, bool utf8, pid_t *_pid) { - const char *args[8]; +static int keymap_load(const char *vc, const char *map, const char *map_toggle, bool utf8, bool disable_capslock, pid_t *_pid) { + const char *args[9]; int i = 0; pid_t pid; @@ -121,6 +122,8 @@ static int keymap_load(const char *vc, c args[i++] = map; if (map_toggle) args[i++] = map_toggle; + if (disable_capslock) + args[i++] = "disable.capslock"; args[i++] = NULL; pid = fork(); @@ -236,11 +239,113 @@ static void font_copy_to_all_vcs(int fd) } } +#ifdef HAVE_SYSV_COMPAT +static int load_compose_table(const char *vc, const char *compose_table, pid_t *_pid) { + const char *args[1024]; + int i = 0, j = 0; + pid_t pid; + char **strv_compose_table = NULL; + char *to_free[1024]; + + if (isempty(compose_table)) { + /* An empty map means no compose table*/ + *_pid = 0; + return 0; + } + + 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) { + if (compose_clear) + args[i++] = "-c"; + } + asprintf(&arg, "compose.%s",*name); + compose_loaded = true; + args[i++] = to_free[j++] = arg; + + } + strv_free(strv_compose_table); + } + args[i++] = NULL; + + if ((pid = fork()) < 0) { + log_error("Failed to fork: %m"); + return -errno; + } else if (pid == 0) { + execv(args[0], (char **) args); + _exit(EXIT_FAILURE); + } + + *_pid = pid; + + for (i=0 ; i < j ; i++) + free (to_free[i]); + + return 0; +} +#endif + +static int set_kbd_rate(const char *vc, const char *kbd_rate, const char *kbd_delay, pid_t *_pid) { + const char *args[7]; + int i = 0; + pid_t pid; + + if (isempty(kbd_rate) && isempty(kbd_delay)) { + *_pid = 0; + return 0; + } + + 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; + + if ((pid = fork()) < 0) { + log_error("Failed to fork: %m"); + return -errno; + } else if (pid == 0) { + execv(args[0], (char **) args); + _exit(EXIT_FAILURE); + } + + *_pid = pid; + return 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; + pid_t kbd_rate_pid = 0, compose_table_pid = 0; +#endif + bool disable_capslock = false; _cleanup_close_ int fd = -1; bool utf8; pid_t font_pid = 0, keymap_pid = 0; @@ -273,6 +378,28 @@ 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 + r = parse_env_file("/etc/vconsole.conf", NEWLINE, "KEYMAP", &vc_keymap, "KEYMAP_TOGGLE", &vc_keymap_toggle, @@ -312,14 +439,32 @@ int main(int argc, char **argv) { if (font_pid > 0) wait_for_terminate_and_warn(KBD_SETFONT, font_pid, true); - r = keymap_load(vc, vc_keymap, vc_keymap_toggle, utf8, &keymap_pid); + r = keymap_load(vc, vc_keymap, vc_keymap_toggle, utf8, disable_capslock, &keymap_pid); if (r < 0) { log_error_errno(r, "Failed to start " KBD_LOADKEYS ": %m"); return EXIT_FAILURE; } +#ifdef HAVE_SYSV_COMPAT + r = load_compose_table(vc, vc_compose_table, &compose_table_pid); + if (r < 0) { + log_error_errno(r, "Failed to start " KBD_LOADKEYS " loading the compose table: %m"); + return EXIT_FAILURE; + } + r = set_kbd_rate(vc, vc_kbd_rate, vc_kbd_delay, &kbd_rate_pid); + if (r < 0) { + log_error_errno(r, "Failed to start kbdrate: %m"); + return EXIT_FAILURE; + } +#endif if (keymap_pid > 0) wait_for_terminate_and_warn(KBD_LOADKEYS, keymap_pid, true); +#ifdef HAVE_SYSV_COMPAT + if (compose_table_pid > 0) + wait_for_terminate_and_warn(KBD_LOADKEYS, compose_table_pid, true); + if (kbd_rate_pid > 0) + wait_for_terminate_and_warn("/usr/bin/kbdrate", kbd_rate_pid, true); +#endif /* Only copy the font when we started setfont successfully */ if (font_copy && font_pid > 0)