Lseek SEEK_END无法使用?

时间:2017-06-13 20:34:40

标签: c seek lseek

我正在使用操纵杆处理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所以我得到了错误,这是29 - 非法寻求:为什么这是非法的寻求?即使我使用0作为偏移量

,我也得到相同的结果
  lseek(fd, 0, SEEK_END)

我使用的是上一版Ubuntu, 谢谢你的帮助

1 个答案:

答案 0 :(得分:4)

  

为什么这是非法的搜查?

您尝试读取的文件是字符特殊文件(即模式字符串的第一个位置中的“c”表示),内核的操纵杆驱动程序可以通过该文件与用户空间程序(例如您的程序)进行通信。这些文件就像管道 - 不可寻找。任何试图在这样的文件中寻找不同位置的尝试都将失败,并且即使参数对应于零净位置变化,某些lseek()实现也可能失败。您可以在此处找到有关设备文件的更多信息:What are character special and block special files in a unix system?

在评论中,你问

  

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

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

我认为你想要的是发现操纵杆设备提供的最近的事件,这在概念上很容易:你从设备读取事件直到读取阻塞,或者会这样做。 The Linux kernel documentation for the device you're using有一些避免无限期阻止的建议:

  • 在尝试从中读取数据之前,请先使用select()确定数据是否可用。

  • 以非阻止模式打开设备(选项O_NONBLOCK),并为read()失败做好准备(返回{{1将-1设置为errno

请注意,在任何情况下都应检查EAGAIN的返回值,并且至少有一个其他失败模式不一定是真正的错误(read())。请阅读its manual page以及您正在使用的其他功能,以获取此类详细信息。