将特定信号发送到外部USB键盘?或者,我如何修复fdopen()?

Modified on: Sat, 30 Jun 2018 09:37:30 +0800

一些背景:当我从命令行运行命令时,我正试图让外部键盘上的大写锁定指示灯亮起。理想情况下它可以编写脚本,以便我可以将它用于警报和事物(我拆解了键盘)。

我得到了这个看起来应该有效的命令:

fd=fdopen("/dev/console"); ioctl(fd, 0x4B32, 0x04);

当我尝试在OS X或Ubuntu服务器上运行此命令时,我发生了这种情况:

fd=fdopen("/dev/console"); ioctl(fd, 0x4B32, 0x04);

所以看起来问题出在第一部分。我需要安装一套软件/实用程序吗?如何手动控制外接键盘上的大写锁定灯?

作者:Undo

最佳答案

您的问题是您尝试在shell提示符中输入C代码,但由于显而易见的原因,这不起作用。您可以将其放入正确的C文件中,编译它并获得可以执行的有效二进制文件:

#include <linux/kd.h>

#include <sys/ioctl.h>

#include <fcntl.h>
#include <unistd.h>

#include <err.h>
#include <stdio.h>
#include <stdlib.h>

static void
usage(char *argv0)
{
    fprintf(stderr, "Usage: %s <on|off>\n", argv0);
    exit(EXIT_FAILURE);
}

int
main(int argc, char *argv[])
{
    int fd;
    int on;
    unsigned char state;

    if (argc != 2)
        usage(argv[0]);

    if (strcmp(argv[1], "on") == 0)
        on = 1;
    else if(strcmp(argv[1], "off") == 0)
        on = 0;
    else
        usage(argv[0]);


    fd = open("/dev/console", O_RDWR);
    if (fd == -1)
        err(EXIT_FAILURE, "open /dev/console");

    if (ioctl(fd, KDGETLED, &state) == -1)
        err(EXIT_FAILURE, "KDGETLED");

    if (on)
        state |= LED_CAP;
    else
        state &= ~LED_CAP;

    if (ioctl(fd, KDSETLED, state) == -1)
        err(EXIT_FAILURE, "KDSETLED");

    close(fd);

    return 0;
}

将其放入一个名为例如caps.c并编译它:

$ gcc -o caps caps.c

然后您可以将其作为

运行

$ ./caps on

打开LED或

$ ./caps off

将其关闭(切换留给读者练习。)

注意:要打开/dev/console,您需要超级用户权限。

另一个注意事项:这也不会阻止您的终端或X服务器偶尔更改CapsLock LED(例如,当按下 Caps 时)。这也不适用于OS X,但仅适用于Linux,因为没有标准化的方法来执行此操作。最后,无法单独更改几个键盘上的LED。


相关问答

添加新评论