From: Stanislav Brabec Date: Fri, 20 Apr 2012 17:16:37 +0200 Subject: handle numlock value in /etc/sysconfig/keyboard (bnc#746595) --- Makefile.am | 13 +++++++++++ configure.ac | 5 +++++ rules/73-seat-numlock.rules | 8 +++++++ src/login/numlock-on.c | 37 ++++++++++++++++++++++++++++++++ src/vconsole/vconsole-setup.c | 38 +++++++++++++++++++++++++++++++++ units/systemd-vconsole-setup.service.in | 2 +- 6 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 rules/73-seat-numlock.rules create mode 100644 src/login/numlock-on.c diff --git a/Makefile.am b/Makefile.am index e44b075..00905d0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2113,6 +2113,19 @@ dist_udevrules_DATA += \ rules/61-accelerometer.rules # ------------------------------------------------------------------------------ +numlock_on_SOURCES = \ + src/login/numlock-on.c + +numlock_on_CFLAGS = \ + $(AM_CFLAGS) + +udevlibexec_PROGRAMS += \ + numlock-on + +dist_udevrules_DATA += \ + rules/73-seat-numlock.rules + +# ------------------------------------------------------------------------------ if ENABLE_GUDEV if ENABLE_GTK_DOC SUBDIRS += \ diff --git a/configure.ac b/configure.ac index 5421461..a2d8755 100644 --- a/configure.ac +++ b/configure.ac @@ -787,6 +787,11 @@ AM_CONDITIONAL(ENABLE_MANPAGES, [test "x$have_manpages" = "xyes"]) # ------------------------------------------------------------------------------ +AC_PATH_PROG([HWINFO], [hwinfo], [/usr/sbin/hwinfo], [/sbin:/usr/sbin:/usr/bin:/bin]) +AC_DEFINE_UNQUOTED([HWINFO], ["${HWINFO}"], [Path to hwinfo binary. (SUSE)]) +AC_PATH_PROG([SETLEDS], [setleds], [/bin/setleds], [/sbin:/usr/sbin:/usr/bin:/bin]) +AC_DEFINE_UNQUOTED([SETLEDS], ["${SETLEDS}"], [Path to setleds binary.]) + # Location of the init scripts as mandated by LSB SYSTEM_SYSVINIT_PATH=/etc/init.d SYSTEM_SYSVRCND_PATH=/etc/rc.d diff --git a/rules/73-seat-numlock.rules b/rules/73-seat-numlock.rules new file mode 100644 index 0000000..e0061ed --- /dev/null +++ b/rules/73-seat-numlock.rules @@ -0,0 +1,8 @@ +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. + +SUBSYSTEM=="tty", ACTION=="add", KERNEL=="tty[0-9]|tty1[0-2]", TEST=="/run/numlock-on", RUN+="numlock-on $env{DEVNAME}" diff --git a/src/login/numlock-on.c b/src/login/numlock-on.c new file mode 100644 index 0000000..77a8368 --- /dev/null +++ b/src/login/numlock-on.c @@ -0,0 +1,37 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 Stanislav Brabec + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include "config.h" +#include +#include +#include + +int main (int argc, char *argv[]) { + static const char *args[] = { SETLEDS, "-D", "+num", NULL }; + + if (argc != 2) + return EX_USAGE; + close (STDIN_FILENO); + if (open (argv[1], O_RDONLY) != STDIN_FILENO) + return EX_IOERR; + /* add cast to prevent warning caused by -Wwrite-strings */ + return execv(args[0], (char * const*) args); +} diff --git a/src/vconsole/vconsole-setup.c b/src/vconsole/vconsole-setup.c index 5f3354e..f5cafc1 100644 --- a/src/vconsole/vconsole-setup.c +++ b/src/vconsole/vconsole-setup.c @@ -326,12 +326,14 @@ int main(int argc, char **argv) { char *vc_kbd_delay = NULL; char *vc_kbd_rate = NULL; char *vc_kbd_disable_caps_lock = NULL; + char *vc_kbd_numlock = NULL; char *vc_compose_table = NULL; pid_t kbd_rate_pid = 0, compose_table_pid = 0; #endif int fd = -1; bool utf8; bool disable_capslock = false; + bool numlock = false; pid_t font_pid = 0, keymap_pid = 0; bool font_copy = false; int r = EXIT_FAILURE; @@ -399,6 +401,7 @@ int main(int argc, char **argv) { "KBD_DELAY", &vc_kbd_delay, "KBD_RATE", &vc_kbd_rate, "KBD_DISABLE_CAPS_LOCK", &vc_kbd_disable_caps_lock, + "KBD_NUMLOCK", &vc_kbd_numlock, "COMPOSETABLE", &vc_compose_table, NULL); if (r < 0 && r != -ENOENT) @@ -413,6 +416,37 @@ int main(int argc, char **argv) { 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; + if (vc_kbd_numlock && strcasecmp(vc_kbd_numlock, "BIOS") == 0) { + int hwinfo_fd[2]; + pid_t hwinfo_pid; + + pipe(hwinfo_fd); + if ((hwinfo_pid = fork()) < 0) { + log_error("Failed to fork: %m"); + _exit(EXIT_FAILURE); + } else if (hwinfo_pid == 0) { + const char *args[3]; + int i = 0; + args[i++] = HWINFO; + args[i++] = "--bios"; + args[i++] = NULL; + close(hwinfo_fd[0]); + fclose(stdout); + dup2(hwinfo_fd[1], STDOUT_FILENO); + execv(args[0], (char **) args); + _exit(EXIT_FAILURE); + } else { + char line[17]; + FILE *hwinfo_file = fdopen(hwinfo_fd[0], "r"); + close(hwinfo_fd[1]); + while (fgets(line, 17, hwinfo_file)) + if (strstr(line, "Num Lock: on")) + numlock = true; + close(hwinfo_fd[0]); + fclose(hwinfo_file); + } + } else + numlock = vc_kbd_numlock && strcasecmp(vc_kbd_numlock, "YES") == 0; #endif } @@ -435,6 +469,10 @@ int main(int argc, char **argv) { finish: if (keymap_pid > 0) wait_for_terminate_and_warn(KBD_LOADKEYS, keymap_pid); + if (numlock) + close(open("/run/numlock-on", O_WRONLY|O_CREAT, 0644)); + else + unlink("/run/numlock-on"); #ifdef HAVE_SYSV_COMPAT if (compose_table_pid > 0) diff --git a/units/systemd-vconsole-setup.service.in b/units/systemd-vconsole-setup.service.in index 18faa63..44ebbd0 100644 --- a/units/systemd-vconsole-setup.service.in +++ b/units/systemd-vconsole-setup.service.in @@ -11,7 +11,7 @@ Documentation=man:systemd-vconsole-setup.service(8) man:vconsole.conf(5) DefaultDependencies=no Conflicts=shutdown.target After=systemd-readahead-collect.service systemd-readahead-replay.service -Before=sysinit.target shutdown.target +Before=sysinit.target shutdown.target systemd-udev-trigger.service ConditionPathExists=/dev/tty0 [Service]