0

I'm working on a C program with joysticks and I'd like to get last event which is as the last line of js0 file. I'm trying to move my cursor before the last element but it doesn't seem working. Any idea why?

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");
}

I'm sure the file I'm reading is at least (sizeof(e)) long. Lseek returns me -1 so I got errno and it was 29 - Illegal seek: why should this be an illegal seek? I get the same results even if I use 0 as offset

  lseek(fd, 0, SEEK_END)

I'm using last version Ubuntu, thanks for your help

DaSim
  • 363
  • 5
  • 10
  • 3
    Did you check `fd` return from `open` to see if there was an error opening the file? You should always check for errors on your system call... just in case. – lurker Jun 13 '17 at 20:39
  • 3
    What does `ls -l /dev/input/js0` show? Are you sure `/dev/input/js0` is a seekable device? – Andrew Henle Jun 13 '17 at 20:46
  • @andrew I got this "crw-rw-r--+ 1 root input 13, 0 giu 13 21:10 /dev/input/js0" and I think giu stands for june (I'm italian). What does seekable device mean? I'm working on a file so I should be able to move across it in my opinion. Sorry but I'm not so expert with C, however thanks guys! – DaSim Jun 13 '17 at 20:59
  • As @AndrewHenle implied, not all files are seekable. Some can only be read sequentially, and a device file providing joystick events seems fairly likely to be in the unseekable category. – John Bollinger Jun 13 '17 at 20:59
  • @luker you're right, thanks, however opening wasn't a problem because I can read the file. My problem is that lseek isn't doing what I thought – DaSim Jun 13 '17 at 20:59
  • Thanks @john! Any suggestion on how can I get last line? I don't get any other idea than reading line-by-line until I find some kind of EOF (is ther any EOF for unseekable files?) – DaSim Jun 13 '17 at 21:02

1 Answers1

4

why should this be an illegal seek?

The file you are trying to read from is a character special file (that's what the 'c' in the first position of its mode string indicates) by which the kernel's joystick driver can communicate with userspace programs, such as yours. Such files are like pipes -- not seekable. Any attempt to seek to a different position in such a file will fail, and some lseek() implementations might fail even when the arguments correspond to zero net position change. You can find more information about device files here: What are character special and block special files in a unix system?

In comments, you ask

Any suggestion on how can I get last line?

, but that's unlikely to be what you actually want. In a file such as this one that represents a communication channel, reaching the end of the file (so as to be able to recognize the last line) indicates that the channel has been closed and all data have been read from it. No more data will ever be available via that file descriptor. That won't happen in your case under ordinary circumstances. And I doubt it is what you're hoping to observe.

What I think you want is to discover the most recent event available from the joystick device, and that's conceptually easy: you read events from the device until a read blocks, or would do. The Linux kernel documentation for the device you're using has some suggestions for avoiding blocking indefinitely:

  • Use select() to determine whether data are available from the device before attempting to read from it.

  • Open the device in non-blocking mode (i.e. with option O_NONBLOCK), and be prepared for your read()s to fail (returning -1) with errno set to EAGAIN.

Note that you should be checking the return value from read() in any case, and that there is at least one other failure mode that is not necessarily a genuine error (EINTR). Do read its manual page, as well as those of the other functions you're using, for details such as these.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
  • Thank you very much @John, I really didn't have any idea of what was happening but now I have a complete map of what to do! gonna try it as soon as possible – DaSim Jun 14 '17 at 06:48
  • It works!! Thanks a lot @john! May I ask you another question? Do I have to close js0 at the end of the program or not? I didn't read it anywhere but I usually close every file I read – DaSim Jun 14 '17 at 17:54
  • @Dariooo, it is a good habit to close every file as soon as your need for it is over, and I commend you for doing that. In fact, however, whenever a process exits, all its remaining open file handles are automatically closed by the system. Thus, you don't have to worry about badness ensuing if your program happens to crash or be forcibly terminated. – John Bollinger Jun 14 '17 at 18:00