我如何等待一个按键中断在Linux系统调用? [英] How do I wait for a keystroke interrupt with a syscall on Linux?

查看:383
本文介绍了我如何等待一个按键中断在Linux系统调用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要当用户presses像F1-12一个特殊的按键在我的程序,这是写在NASM接收中断。我只是需要等待我的主要功能开始的功能按键。我知道这是可能的BIOS的的INT 16h ,它返回一个扫描code。我怎样才能做到这一点Linux下?

I want to receive an interrupt when the user presses a special keystroke like F1-12 in my program, which is written in nasm. I simply need to wait for a function keystroke at the start of my main function. I know that this is possible with the BIOS's int 16h, which returns a scancode. How can I do this under Linux?

推荐答案

必要的code这是相当复杂的;我终于想通了如何使用原始的ioctl检查F1在C,读取和写入。如果你熟悉汇编和Linux系统调用的翻译NASM应该是简单的。

The necessary code for this is rather complicated; I eventually figured out how to check for F1 in C with raw ioctl, read, and write. The translation to nasm should be straightforward if you're familiar with assembly and Linux syscalls.

这不正是你想要的,因为它仅检查F1,他们没有休息。 F1的顺序是0x1b,0x4f,为0x50。你可以找到 OD -t X1 和pressing关键其他序列。例如,F2是0x1b,0x4f,0x51。

It's not exactly what you want, in that it only checks for F1, not the rest of them. F1's sequence is 0x1b, 0x4f, 0x50. You can find other sequences with od -t x1 and pressing the key. For example, F2 is 0x1b, 0x4f, 0x51.

其基本思想是,我们获得当前的终端属性,更新他们是非阻塞和原材料(cfmakeraw),然后设置他们回来。该系统调用的ioctl用于此。

The basic idea is that we get the current terminal attributes, update them to be nonblocking and raw (cfmakeraw), and then set them back. The ioctl syscall is used for this.

#include <unistd.h>
#include <sys/ioctl.h>
#include <termios.h>

struct ktermios {
    tcflag_t c_iflag;
    tcflag_t c_oflag;
    tcflag_t c_cflag;
    tcflag_t c_lflag;
    cc_t c_line;
    cc_t c_cc[19];
};

int getch() {
    unsigned char c;
    read(0, &c, sizeof(c));
    return c;
}

int main(int argc, char *argv[]) {
    struct ktermios orig, new;
    ioctl(0, TCGETS, &orig);
    ioctl(0, TCGETS, &new);

    // from cfmakeraw documentation
    new.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
    new.c_oflag &= ~OPOST;
    new.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
    new.c_cflag &= ~(CSIZE | PARENB);
    new.c_cflag |= CS8;

    ioctl(0, TCSETS, &new);

    while (1) {
        if (getch() == 0x1b && getch() == 0x4f && getch() == 0x50) {
            break;
        }
    }

    write(1, "Got F1!\r\n", 9);
    ioctl(0, TCSETS, &orig);
    return 0;
}

我这基础上这个答案,这是非常有益的。

这篇关于我如何等待一个按键中断在Linux系统调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆