Index: systemd-44/src/vconsole/vconsole-setup.c =================================================================== --- systemd-44.orig/src/vconsole/vconsole-setup.c +++ systemd-44/src/vconsole/vconsole-setup.c @@ -265,12 +265,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; int r = EXIT_FAILURE; pid_t font_pid = 0, keymap_pid = 0; @@ -374,6 +376,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)) < 0) { @@ -391,6 +394,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; #elif defined(TARGET_ARCH) if ((r = parse_env_file("/etc/rc.conf", NEWLINE, @@ -558,6 +592,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 TARGET_SUSE if (compose_table_pid > 0) Index: systemd-44/Makefile.am =================================================================== --- systemd-44.orig/Makefile.am +++ systemd-44/Makefile.am @@ -42,6 +42,7 @@ dbussessionservicedir=@dbussessionservic dbussystemservicedir=@dbussystemservicedir@ dbusinterfacedir=@dbusinterfacedir@ udevrulesdir=@udevrulesdir@ +udevhelperdir=@udevhelperdir@ pamlibdir=@pamlibdir@ pkgconfigdatadir=$(datadir)/pkgconfig pkgconfiglibdir=$(libdir)/pkgconfig @@ -202,6 +203,9 @@ rootlibexec_PROGRAMS = \ systemgenerator_PROGRAMS = \ systemd-getty-generator +udevhelper_PROGRAMS = \ + numlock-on + noinst_PROGRAMS = \ test-engine \ test-job-type \ @@ -2033,6 +2037,12 @@ systemd_uaccess_LDADD = \ $(UDEV_LIBS) \ $(ACL_LIBS) +numlock_on_SOURCES = \ + src/login/numlock-on.c + +numlock_on_CFLAGS = \ + $(AM_CFLAGS) + rootlibexec_PROGRAMS += \ systemd-uaccess @@ -2040,7 +2050,8 @@ dist_udevrules_DATA += \ src/login/70-uaccess.rules dist_udevrules_DATA += \ - src/login/71-seat.rules + src/login/71-seat.rules \ + src/login/73-seat-numlock.rules nodist_udevrules_DATA += \ src/login/73-seat-late.rules Index: systemd-44/configure.ac =================================================================== --- systemd-44.orig/configure.ac +++ systemd-44/configure.ac @@ -410,6 +410,13 @@ fi with_distro=`echo ${with_distro} | tr '[[:upper:]]' '[[:lower:]]' ` AC_DEFINE_UNQUOTED(DISTRIBUTION, ["${with_distro}"], [Target Distribution]) +if test z"$with_distro" = z"suse" ; then + AC_PATH_PROG([HWINFO], [hwinfo], [/usr/sbin/hwinfo], [/sbin:/usr/sbin:/usr/bin:/bin]) + AC_DEFINE_UNQUOTED([HWINFO], ["${HWINFO}"], [Path to hwinfo binary. (SUSE)]) +fi +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 @@ -579,6 +586,11 @@ AC_ARG_WITH([udevrulesdir], [], [with_udevrulesdir=`pkg-config --variable=udevdir udev`/rules.d]) +AC_ARG_WITH([udevhelperdir], + AS_HELP_STRING([--with-udevhelperdir=DIR], [Directory for udev helpers]), + [], + [with_udevhelperdir=`pkg-config --variable=udevdir udev`]) + AC_ARG_WITH([rootprefix], AS_HELP_STRING([--with-rootprefix=DIR], [rootfs directory prefix for config files and kernel modules]), [], [with_rootprefix=${ac_default_prefix}]) @@ -611,6 +623,7 @@ AC_SUBST([dbussessionservicedir], [$with AC_SUBST([dbussystemservicedir], [$with_dbussystemservicedir]) AC_SUBST([dbusinterfacedir], [$with_dbusinterfacedir]) AC_SUBST([udevrulesdir], [$with_udevrulesdir]) +AC_SUBST([udevhelperdir], [$with_udevhelperdir]) AC_SUBST([pamlibdir], [$with_pamlibdir]) AC_SUBST([rootprefix], [$with_rootprefix]) AC_SUBST([rootlibdir], [$with_rootlibdir]) @@ -650,6 +663,7 @@ AC_MSG_RESULT([ rootlib dir: ${with_rootlibdir} PAM modules dir: ${with_pamlibdir} udev rules dir: ${with_udevrulesdir} + udev hepler dir: ${with_udevhelperdir} D-Bus policy dir: ${with_dbuspolicydir} D-Bus session dir: ${with_dbussessionservicedir} D-Bus system dir: ${with_dbussystemservicedir} Index: systemd-44/src/login/73-seat-numlock.rules.in =================================================================== --- /dev/null +++ systemd-44/src/login/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}" Index: systemd-44/src/login/numlock-on.c =================================================================== --- /dev/null +++ systemd-44/src/login/numlock-on.c @@ -0,0 +1,36 @@ +/*-*- 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 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; + return execv(args[0], args); +}