0

我正在开发一个带有操纵杆的 C 程序,我想获得最后一个事件,它是 js0 文件的最后一行。我试图将光标移动到最后一个元素之前,但它似乎不起作用。知道为什么吗?

int fd = open ("/dev/input/js0", O_RDONLY);
struct js_event e;
lseek(fd, -(sizeof(e)), SEEK_END);    
read (fd, &e, sizeof(e));
switch(e.type){
    case JS_EVENT_BUTTON: printf("btn\n");
    break;
    case JS_EVENT_AXIS: printf("axes\n");
    break;
    default: printf("smth else\n");
}

我确定我正在阅读的文件至少是 (sizeof(e)) 长。Lseek 返回 -1 所以我得到了 errno 并且是 29 - 非法搜索:为什么这应该是非法搜索?即使我使用 0 作为偏移量,我也会得到相同的结果

  lseek(fd, 0, SEEK_END)

我正在使用最新版本的 Ubuntu,感谢您的帮助

4

1 回答 1

4

为什么这应该是非法的寻求?

您尝试从中读取的文件是一个字符特殊文件(这是其模式字符串的第一个位置中的“c”表示的内容),内核的操纵杆驱动程序可以通过该文件与用户空间程序(例如您的程序)进行通信。这样的文件就像管道——不可搜索。任何在此类文件中寻找不同位置的尝试都将失败,lseek()即使参数对应于零净位置变化,某些实现也可能会失败。您可以在此处找到有关设备文件的更多信息:什么是 unix 系统中的字符特殊文件和块特殊文件?

在评论中,你问

关于如何获得最后一行的任何建议?

,但这不太可能是您真正想要的。在诸如这个表示通信通道的文件中,到达文件末尾(以便能够识别最后一行)表示通道已关闭并且已从中读取所有数据。通过该文件描述符将不再有可用的数据在一般情况下,您的情况不会发生这种情况。我怀疑这是你希望观察到的。

我认为您想要的是发现可从操纵杆设备获得的最新事件,这在概念上很容易:您从设备读取事件,直到读取阻塞,或者会这样做。 您正在使用的设备的 Linux 内核文档提供了一些避免无限期阻塞的建议:

  • 用于select()在尝试从设备读取数据之前确定数据是否可用。

  • 以非阻塞模式打开设备(使用 option O_NONBLOCK),并为您的 s设置read()为 失败(返回-1)做好准备。errnoEAGAIN

请注意,您应该read()在任何情况下检查返回值,并且至少存在一种其他故障模式不一定是真正的错误 ( EINTR)。请阅读其手册页以及您正在使用的其他功能的手册页,以了解诸如此类的详细信息。

于 2017-06-13T21:57:37.450 回答