Add socket activation and lazy opening of /dev/uinput which makes acpi_fakekeyd both more robust and helps speed up boot (by avoiding sleeping in the init script).
An added benefit of the systemd socket activation is that the daemon is never actually started on systems (like my laptop) where the "extra" keys don't actually generate ACPI events. --- debian/acpi-fakekey.init | 18 ++--- debian/acpi-fakekey.install | 3 + debian/acpi-fakekey.modules.conf | 3 + debian/acpi-fakekey.service | 7 ++ debian/acpi-fakekey.socket | 9 ++ debian/control | 3 + debian/patches/acpi_fakekey.diff | 148 +++++++++++++++++++++++--------------- debian/rules | 2 - 8 files changed, 121 insertions(+), 72 deletions(-) create mode 100644 debian/acpi-fakekey.modules.conf create mode 100644 debian/acpi-fakekey.service create mode 100644 debian/acpi-fakekey.socket diff --git a/debian/acpi-fakekey.init b/debian/acpi-fakekey.init index d276383..ce6196b 100644 --- a/debian/acpi-fakekey.init +++ b/debian/acpi-fakekey.init @@ -1,6 +1,6 @@ #!/bin/sh -# INIT script to check whether we're on batteries, and so start with laptop -# mode etc enabled. +# INIT script to start the ACPI fakekey daemon that turns ACPI events into +# input events via the kernel uinput module. ### BEGIN INIT INFO # Provides: acpi-fakekey @@ -25,19 +25,13 @@ case "$1" in log_action_end_msg 1 "Modprobe uinput failed. Please use 'dmesg' to find out why" fi fi - # give udev time to create the devices - sleep 1 fi - if [ -d /sys/devices/virtual/misc/uinput ]; then - if start-stop-daemon --start --quiet --oknodo --exec /usr/sbin/acpi_fakekeyd - then - log_action_end_msg 0 - else - log_action_end_msg 1 "Could not start /usr/sbin/acpi_fakekeyd" - fi - else + if start-stop-daemon --start --quiet --oknodo --exec /usr/sbin/acpi_fakekeyd + then log_action_end_msg 0 + else + log_action_end_msg 1 "Could not start /usr/sbin/acpi_fakekeyd" fi ;; stop) diff --git a/debian/acpi-fakekey.install b/debian/acpi-fakekey.install index 28625f4..1ba5e32 100644 --- a/debian/acpi-fakekey.install +++ b/debian/acpi-fakekey.install @@ -1,2 +1,5 @@ acpi_fakekey /usr/bin acpi_fakekeyd /usr/sbin +debian/acpi-fakekey.service /lib/systemd/system +debian/acpi-fakekey.socket /lib/systemd/system +debian/acpi-fakekey.modules.conf /etc/modules-load.d diff --git a/debian/acpi-fakekey.modules.conf b/debian/acpi-fakekey.modules.conf new file mode 100644 index 0000000..3a1c6b0 --- /dev/null +++ b/debian/acpi-fakekey.modules.conf @@ -0,0 +1,3 @@ +# /etc/modules-load.d/acpi-fakekey.modules.conf +# The uinput module is used by the acpi-fakekeyd daemon (package acpi-fakekey) +uinput diff --git a/debian/acpi-fakekey.service b/debian/acpi-fakekey.service new file mode 100644 index 0000000..b1e4535 --- /dev/null +++ b/debian/acpi-fakekey.service @@ -0,0 +1,7 @@ +[Unit] +Description=ACPI fakekey daemon +Requires=acpi-fakekey.socket + +[Service] +Type=simple +ExecStart=/usr/sbin/acpi_fakekeyd -f diff --git a/debian/acpi-fakekey.socket b/debian/acpi-fakekey.socket new file mode 100644 index 0000000..99769bf --- /dev/null +++ b/debian/acpi-fakekey.socket @@ -0,0 +1,9 @@ +[Unit] +Description=ACPI fakekey daemon FIFO + +[Socket] +ListenFIFO=/var/run/acpi_fakekey +SocketMode=0200 + +[Install] +WantedBy=sockets.target diff --git a/debian/control b/debian/control index 5938b24..8c1f36e 100644 --- a/debian/control +++ b/debian/control @@ -3,7 +3,8 @@ Section: admin Priority: optional Maintainer: Debian Acpi Team <pkg-acpi-de...@lists.alioth.debian.org> Uploaders: Michael Meskes <mes...@debian.org> -Build-Depends: debhelper (>= 7.0.50~), quilt (>= 0.40) +Build-Depends: debhelper (>= 7.0.50~), quilt (>= 0.40), + libsystemd-daemon-dev [linux-any], dh-systemd (>= 1.5), pkg-config Vcs-Git: git://git.debian.org/git/pkg-acpi/acpi-support.git Vcs-Browser: http://git.debian.org/?p=pkg-acpi/acpi-support.git Standards-Version: 3.9.3 diff --git a/debian/patches/acpi_fakekey.diff b/debian/patches/acpi_fakekey.diff index 74656b9..fdb9a1a 100644 --- a/debian/patches/acpi_fakekey.diff +++ b/debian/patches/acpi_fakekey.diff @@ -1,6 +1,5 @@ -diff -Nru acpi-support-0.115/acpi_fakekey.c /tmp/Umsn0ebzYy/acpi-support-0.115+thjaeger1/acpi_fakekey.c ---- acpi-support-0.115/acpi_fakekey.c 2008-09-26 00:14:34.000000000 +0100 -+++ acpi-support-0.115+thjaeger1/acpi_fakekey.c 2009-01-19 09:09:31.000000000 +0000 +--- a/acpi_fakekey.c ++++ b/acpi_fakekey.c @@ -1,68 +1,29 @@ #include <unistd.h> #include <fcntl.h> @@ -85,9 +84,8 @@ diff -Nru acpi-support-0.115/acpi_fakekey.c /tmp/Umsn0ebzYy/acpi-support-0.115+t + return EXIT_SUCCESS; } - -diff -Nru /tmp/clWVJzRiJd/acpi-support-0.115/Makefile /tmp/Umsn0ebzYy/acpi-support-0.115+thjaeger1/Makefile ---- acpi-support-0.115/Makefile 2008-09-26 00:14:34.000000000 +0100 -+++ acpi-support-0.115+thjaeger1/Makefile 2009-01-19 09:09:31.000000000 +0000 +--- a/Makefile ++++ b/Makefile @@ -1,8 +1,10 @@ -all: acpi_fakekey +all: acpi_fakekey acpi_fakekeyd @@ -98,19 +96,20 @@ diff -Nru /tmp/clWVJzRiJd/acpi-support-0.115/Makefile /tmp/Umsn0ebzYy/acpi-suppo + gcc -Wall $(shell dpkg-buildflags --get CFLAGS) $(shell dpkg-buildflags --get CPPFLAGS) $(shell dpkg-buildflags --get LDFLAGS) -o $@ $< + +acpi_fakekeyd: acpi_fakekeyd.c -+ gcc -Wall $(shell dpkg-buildflags --get CFLAGS) $(shell dpkg-buildflags --get CPPFLAGS) $(shell dpkg-buildflags --get LDFLAGS) -o $@ $< ++ gcc -Wall $(shell dpkg-buildflags --get CFLAGS) $(shell dpkg-buildflags --get CPPFLAGS) $(shell dpkg-buildflags --get LDFLAGS) $(shell pkg-config --cflags --libs libsystemd-daemon) -o $@ $< # Keep this manually generated so that it doesn't build-dep on # 'linux-headers' and stays predictable. -@@ -15,4 +19,4 @@ +@@ -15,4 +17,4 @@ test -f aliased-keys && cat aliased-keys >> $@ clean: - rm -f acpi_fakekey + $(RM) acpi_fakekey acpi_fakekeyd ---- acpi-support/acpi_fakekeyd.c 2010-06-15 12:35:38.846063228 +0200 -+++ acpi-support/acpi_fakekeyd.c 2010-06-15 18:22:03.000000000 +0200 -@@ -0,0 +1,103 @@ +--- /dev/null ++++ b/acpi_fakekeyd.c +@@ -0,0 +1,137 @@ ++#define _BSD_SOURCE +#include <unistd.h> +#include <fcntl.h> +#include <string.h> @@ -118,99 +117,132 @@ diff -Nru /tmp/clWVJzRiJd/acpi-support-0.115/Makefile /tmp/Umsn0ebzYy/acpi-suppo +#include <stdio.h> +#include <linux/uinput.h> +#include <sys/stat.h> ++#include <systemd/sd-daemon.h> + +#define FIFO "/var/run/acpi_fakekey" + -+void fail(const char *str) { ++static void fail(const char *str) { + perror(str); + exit(EXIT_FAILURE); +} + -+void daemonize() { -+ int pid; -+ if ((pid = fork()) == -1) -+ fail("fork"); -+ -+ if (pid) -+ exit(EXIT_SUCCESS); + -+ if (setsid() == -1) -+ fail("setsid"); -+ -+ if (chdir("/") == -1) -+ fail("chdir"); ++static int create_fifo() { ++ int fifo, n; ++ ++ n = sd_listen_fds(1); ++ if (n > 1) ++ fail("sd_listen_fds"); ++ else if (n == 1) { ++ fifo = SD_LISTEN_FDS_START + 0; ++ if (!sd_is_fifo(fifo, FIFO)) ++ fail("sd_is_fifo"); ++ } else { ++ remove(FIFO); ++ if (mkfifo(FIFO, 0200) == -1) ++ fail("mkfifo"); ++ if ((fifo = open(FIFO, O_RDWR | O_NONBLOCK)) == -1) ++ fail("open fifo"); ++ } + -+ if (!freopen("/dev/null", "r", stdin)) -+ fail("freopen"); -+ if (!freopen("/dev/null", "w", stdout)) -+ fail("freopen"); -+ if (!freopen("/dev/null", "w", stderr)) -+ fail("freopen"); ++ return fifo; +} + -+int main(int argc, char** argv) { -+ int fd; -+ int fifo; -+ int i; ++static int create_uinputdev() { ++ int udev, i; + struct uinput_user_dev dev; -+ fd_set sfd; + -+ if ((fd = open("/dev/uinput", O_WRONLY | O_NDELAY)) == -1) -+ fail("open device"); ++ /* Failure to open dev is not fatal, module might be loaded later */ ++ udev = open("/dev/uinput", O_WRONLY | O_NDELAY); ++ if (udev < 0) { ++ perror("failed to open /dev/uinput"); ++ return -1; ++ } + + memset(&dev, 0, sizeof(dev)); + strncpy(dev.name, "ACPI Virtual Keyboard Device", UINPUT_MAX_NAME_SIZE); + dev.id.version = 4; + dev.id.bustype = BUS_USB; + -+ ioctl(fd, UI_SET_EVBIT, EV_KEY); ++ ioctl(udev, UI_SET_EVBIT, EV_KEY); + for (i = 0; i < 256; i++) -+ ioctl(fd, UI_SET_KEYBIT, i); -+ if (write(fd, &dev, sizeof(dev)) == -1) ++ ioctl(udev, UI_SET_KEYBIT, i); ++ ++ if (write(udev, &dev, sizeof(dev)) == -1) + fail("write"); + -+ if (ioctl(fd, UI_DEV_CREATE) == -1) ++ if (ioctl(udev, UI_DEV_CREATE) == -1) + fail("create device"); + -+ remove(FIFO); -+ if (mkfifo(FIFO, 0200) == -1) -+ fail("mkfifo"); -+ -+ if ((fifo = open(FIFO, O_RDWR | O_NONBLOCK)) == -1) -+ fail("open fifo"); ++ return udev; ++} ++ ++int main(int argc, char **argv) { ++ int do_daemonize = 1; ++ int udev; ++ int fifo; ++ fd_set sfd; + -+ daemonize(); ++ if (argc == 2 && !strcmp(argv[1], "-f")) ++ do_daemonize = 0; ++ else if (argc > 1) ++ fail("invalid arguments"); ++ ++ udev = create_uinputdev(); ++ ++ fifo = create_fifo(); ++ ++ if (do_daemonize && (daemon(0, 0) != 0)) ++ fail("daemon"); + + FD_ZERO(&sfd); + FD_SET(fifo, &sfd); -+ while (select(fifo+1, &sfd, 0, 0, 0) != -1) { ++ while (select(fifo + 1, &sfd, 0, 0, 0) != -1) { + int n; -+ unsigned char key; ++ unsigned char key; + struct input_event event; -+ if ((n = read(fifo, &key, 1)) == -1) ++ ++ n = read(fifo, &key, 1); ++ if (n < 0) + break; -+ if (!n) ++ if (n == 0) + continue; + ++ /* Try again to create a uinput device if necessary */ ++ if (udev < 0) { ++ udev = create_uinputdev(); ++ if (udev < 0) ++ continue; ++ } ++ ++ /* Key pressed */ ++ memset(&event, 0, sizeof(event)); + event.type = EV_KEY; + event.code = key; + event.value = 1; -+ if (write(fd, &event, sizeof event) == -1) ++ if (write(udev, &event, sizeof(event)) == -1) + break; ++ ++ /* Key released */ ++ memset(&event, 0, sizeof(event)); ++ event.type = EV_KEY; ++ event.code = key; + event.value = 0; -+ if (write(fd, &event, sizeof event) == -1) ++ if (write(udev, &event, sizeof(event)) == -1) + break; -+ /* Need to write sync event */ ++ ++ /* Sync */ + memset(&event, 0, sizeof(event)); + event.type = EV_SYN; + event.code = SYN_REPORT; + event.value = 0; -+ if (write(fd, &event, sizeof event) == -1) ++ if (write(udev, &event, sizeof(event)) == -1) + break; + } + -+ ioctl(fd, UI_DEV_DESTROY); -+ close(fd); ++ ioctl(udev, UI_DEV_DESTROY); ++ close(udev); ++ close(fifo); + remove(FIFO); + return EXIT_FAILURE; +} diff --git a/debian/rules b/debian/rules index 1eba9a1..c716e45 100755 --- a/debian/rules +++ b/debian/rules @@ -8,7 +8,7 @@ arch-depends := -V'arch:Suggests=toshset' endif %: - dh ${@} --with quilt + dh ${@} --with quilt,systemd override_dh_auto_clean: dh_auto_clean -- To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org