tty pts终端下获取键值 ctrl c 或3秒自动退出。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <termios.h>
#include <sys/ioctl.h>
#include <linux/kd.h>
#define BUFSZ 18
int fd;
int oldkbdmode;
struct termios oldtermios;void restore(void)
{ioctl(fd,KDSKBMODE, oldkbdmode);tcsetattr(fd, 0, &oldtermios);close(fd);
}void intrupt(int)
{restore();printf("quit\n");exit(0);
}void setup()
{struct termios new = {0};char* tty = ttyname(STDIN_FILENO);if(tty)fd = open(tty,O_RDWR);if(!isatty(fd) || fd < 0){fprintf(stderr,"open tty failed\n");exit(0);}signal(SIGINT, intrupt);signal(SIGALRM,intrupt);ioctl(fd, KDGKBMODE, &oldkbdmode);tcgetattr(fd, &oldtermios);new = oldtermios;new.c_lflag &= ~(ECHO | ICANON);new.c_cc[VMIN] = BUFSZ;new.c_cc[VTIME] = 1;tcsetattr(fd, TCSAFLUSH, &new);ioctl(fd, KDSKBMODE, K_UNICODE);
}int main()
{unsigned char buf[BUFSZ];setup();while(1) {alarm(3);ssize_t n = read(fd, buf, sizeof(buf));if(n > 0)printf("keycode");for(int i = 0; i < n; i++)printf("\thex:0x%2x dec:%3d char:%c \n",buf[i],buf[i],buf[i]); }restore();return 0;
}
K_UNICODE 模式 tty pts 键值一致,xlate模式tty ctrl 无反应,其它一致。
保持一致性最好用K_UNICODE模式,X11下KBDMODE是模拟的,设置kbd模式没什么用,tty下才有用。 有的字符不可打印,%c打印出来会hex 会少个字符。