Set NumLock according to /etc/sysconfig/keyboard. https://bugzilla.novell.com/show_bug.cgi?id=746595 Authors: Stanislav Brabec Cristian Rodríguez Index: systemd-205/src/vconsole/vconsole-setup.c =================================================================== --- systemd-205.orig/src/vconsole/vconsole-setup.c +++ systemd-205/src/vconsole/vconsole-setup.c @@ -42,6 +42,10 @@ #include "fileio.h" #include "strv.h" +#define BIOS_DATA_AREA 0x400 +#define BDA_KEYBOARD_STATUS_FLAGS_4 0x97 +#define BDA_KSF4_NUMLOCK_MASK 0x02 + static bool is_vconsole(int fd) { unsigned char data[1]; @@ -321,12 +325,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; @@ -389,6 +395,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) @@ -403,6 +410,36 @@ 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 defined(__i386__) || defined(__x86_64__) + if (vc_kbd_numlock && strcaseeq(vc_kbd_numlock, "bios")) { + int _cleanup_close_ fdmem; + char c; + + fdmem = open ("/dev/mem", O_RDONLY); + + if(fdmem < 0) { + r = EXIT_FAILURE; + log_error("Failed to open /dev/mem: %m"); + goto finish; + } + + if(lseek(fdmem, BIOS_DATA_AREA + BDA_KEYBOARD_STATUS_FLAGS_4, SEEK_SET) == (off_t) -1) { + r = EXIT_FAILURE; + log_error("Failed to seek /dev/mem: %m"); + goto finish; + } + + if(read (fdmem, &c, sizeof(char)) == -1) { + r = EXIT_FAILURE; + log_error("Failed to read /dev/mem: %m"); + goto finish; + } + + if (c & BDA_KSF4_NUMLOCK_MASK) + numlock = true; + } else +#endif + numlock = vc_kbd_numlock && strcaseeq(vc_kbd_numlock, "yes"); #endif } @@ -425,6 +462,10 @@ int main(int argc, char **argv) { finish: if (keymap_pid > 0) wait_for_terminate_and_warn(KBD_LOADKEYS, keymap_pid); + if (numlock) + touch("/run/numlock-on"); + else + unlink("/run/numlock-on"); #ifdef HAVE_SYSV_COMPAT if (compose_table_pid > 0) @@ -444,6 +485,7 @@ finish: free(vc_font); free(vc_font_map); free(vc_font_unimap); + free(vc_kbd_numlock); #ifdef HAVE_SYSV_COMPAT free(vc_kbd_delay); free(vc_kbd_rate); Index: systemd-205/Makefile.am =================================================================== --- systemd-205.orig/Makefile.am +++ systemd-205/Makefile.am @@ -2361,6 +2361,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 += \ Index: systemd-205/rules/73-seat-numlock.rules =================================================================== --- /dev/null +++ systemd-205/rules/73-seat-numlock.rules @@ -0,0 +1,8 @@ +# This file is part of SUSE customization 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-205/src/login/numlock-on.c =================================================================== --- /dev/null +++ systemd-205/src/login/numlock-on.c @@ -0,0 +1,34 @@ +/* + * numlock-on.c: Turn numlock-on + * + * This file may be freely copied under the terms of the GNU General + * Public License (GPL), version 2, or at your option any later + * version. + + * Copyright (C) 2013 Stanislav Brabec, SUSE + * + * based on setleds.c, which is + * Copyright (C) 1994-1999 Andries E. Brouwer + */ + +#include +#include +#include +#include + +int +main(int argc, char **argv) { + char flags; + + if (ioctl(0, KDGKBLED, &flags)) { + perror("KDGKBLED"); + exit(1); + } + + if (ioctl(0, KDSKBLED, flags | LED_NUM | (LED_NUM << 4))) { + perror("KDSKBLED"); + exit(1); + } + + exit(0); +} Index: systemd-205/units/systemd-vconsole-setup.service.in =================================================================== --- systemd-205.orig/units/systemd-vconsole-setup.service.in +++ systemd-205/units/systemd-vconsole-setup.service.in @@ -11,7 +11,7 @@ Documentation=man:systemd-vconsole-setup 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]