Get Input Keys Status Under Linux

Sometimes direct access to the Linux input subsystem is useful. In highly space constrained environment you might find yourself without any input wrapper library. This is the case of initramfs. In order to keep boot time short, initramfs must be as small as possible. Usually my initramfs contains little more than a statically linked Busybox.

In one of my projects the system user could force a special boot mode by pressing a magic key combination on the keypad. This is useful for recovery mode, software upgrades, etc. So, how do we know what keys are currently pressed? The EVIOCGKEY ioctl comes to the rescue. EVIOCGKEY macro is defined in the linux/input.h header. You provide a bits array buffer, to this ioctl. Each bit represents a key code according to its offset in the array. The key code numbers are also defined in linux/input.h.

Here is an short example (with error checking and common headers omitted for brevity):

#include <linux/input.h>

uint8_t keys[16];

fd = open("/dev/input/event0", O_RDONLY);
ioctl (fd, EVIOCGKEY(sizeof keys), &keys);

for (i = 0; i < sizeof keys; i++)
    for (j = 0; j < 8; j++)
        if (keys[i] & (1 << j))
            printf ("key code %d\n", (i*8) + j);

Make sure that the keys buffer is large enough to hold the highest key code number you are interested in.