why ftell( stdin ) causes illegal seek error
Asked Answered
G

1

9

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.

Galle answered 23/3, 2010 at 18:15 Comment(3)
What is the problem you are actually trying to solve with fseek?Chapell
related: #4918301Bimbo
related: Problems when test whether standard input is capable of seekingTrilbee
K
15

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.

Komi answered 23/3, 2010 at 18:22 Comment(6)
+1 for an example that shows the difference between cat file|./a.out and ./a.out<file.Harrier
@R.. What's the difference?Ajax
@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<f opens f in the same process, which is probably faster if x doesn't do much besides read the file, and actually gives you a seekable file (since fifos are just a buffer).Komi
Worth mentioning that ./a.out < script is likely implemented with freopen by Bash.Bimbo
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?Trilbee
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.Komi

© 2022 - 2024 — McMap. All rights reserved.