8

The following code outputs "Illegal seek":

#include <stdio.h>
#include <errno.h>
#include <string.h>

int main() {
    errno = 0;
    getchar();
    getchar();
    getchar();
    ftell( stdin );
    printf( "%s\n", strerror(errno) );
}

This occurs when I run cat script | ./a.out as well as when I just run ./a.out. The problem is with ftell, of course. My question is: why does this occur? I would think stdin can be seekable. fseek also causes the same error. If stdin is not seekable, is there some way I can do the same sort of thing?

Thank you for your replies.

Rick
  • 7,007
  • 2
  • 49
  • 79
Jim
  • 83
  • 1
  • 3
  • 1
    What is the problem you are actually trying to solve with fseek? –  Mar 23 '10 at 18:33
  • related: https://stackoverflow.com/questions/4917801/using-fseek-with-a-file-pointer-that-points-to-stdin – Ciro Santilli OurBigBook.com Nov 17 '19 at 20:52
  • related: [Problems when test whether standard input is capable of seeking](https://unix.stackexchange.com/questions/502518/problems-when-test-whether-standard-input-is-capable-of-seeking) – Rick Mar 19 '20 at 06:11

1 Answers1

14

Fifos aren't seekable. They are simply a buffer. Once data has been read() from a fifo buffer, it can never be retrieved.

Note that if you ran your program:

./a.out < script

then standard input would be a file and not a fifo, so ftell() will then do what you expect.

geocar
  • 9,085
  • 1
  • 29
  • 37
  • 2
    +1 for an example that shows the difference between `cat file|./a.out` and `./a.out – R.. GitHub STOP HELPING ICE Aug 07 '10 at 15:09
  • @R.. What's the difference? – Calmarius Sep 22 '13 at 19:37
  • @Calmarius: cat f|x uses a separate process (and maybe a separate cpu) to copy a file into a fifo. the fifo is being read by the process x. if x does things other than read() this may be faster than if it reads the file itself. x – geocar Sep 23 '13 at 23:40
  • Worth mentioning that `./a.out < script` is likely implemented with [`freopen`](https://en.cppreference.com/w/c/io/freopen) by Bash. – Ciro Santilli OurBigBook.com Nov 17 '19 at 20:49
  • Hi @geocar, I wonder what do you exactly refer to by saying **buffer** here? "Fifos aren't seekable. They are simply a buffer. ". Do you mean it's simply a `char` arrary resides in the memory? – Rick Mar 19 '20 at 05:48
  • No Rick, *I* meant what I said: The important property is that it is not seekable, that is, that you cannot seek it with lseek() or fseek() or any other manner of seeking because it won't work on account of it being not seekable. How the Kernel choses to arrange that buffer in memory has no bearing on "why this code doesn't work", and thinking about it when looking at this problem will only lead to stupid ideas. – geocar Mar 19 '20 at 08:23