stdin - seek() issue on Linux.
jepler at unpythonic.net
jepler at unpythonic.net
Tue Apr 23 22:50:48 EDT 2002
On Tue, Apr 23, 2002 at 07:16:41PM -0700, Srihari Vijayaraghavan wrote:
> Once again thanks for your responses. I really appreciate that.
>
> OK. IMHO sys.stdin doesn't work as stated in PLR (Python Library
> Reference), i.e., it doesn't work like a _real_ file object,
> particularly not supporting seek() related operations. While your
> technical explanation sounds OK to me, but I am still not convinced
> why PLR advertises that sys.stdin is treated as a file object. Please
> correct me if I am wrong here (as I am still a newbie user :-).
Please try the following C program with STDIN both as a terminal and as a
file:
cat > test_seek.c <<EOF
#include <stdio.h> /* perror() */
#include <sys/types.h> /* lseek() */
#include <unistd.h> /* lseek() */
#include <errno.h> /* errno */
int main(void) {
errno = 0;
lseek(0, 0, SEEK_SET);
perror("lseek");
return 0;
}
EOF
cc test_seek.c -o test_seek
./test_seek # fails 'lseek: Illegal seek'
./test_seek < /dev/null # succeeds 'lseek: Success'
or this Perl program:
perl -e 'seek STDIN, 0, 0 or die $!' # fails: Illegal seek at -e line 1.'
perl -e 'seek STDIN, 0, 0 or die $!' < /dev/null # sicceeds
Not all files are seekable. On Unix, notable exceptions are terminals,
pipes, and sockets.
If you don't know in advance whether a particular "file" is seekable, you
can test it without any side-effects by
try:
f.seek(0, 1)
except IOError:
f is not seekable (wrap with CStringIO or temporary file if
seeking is required)
else:
f is seekable
f.seek(0, 1) seeks 0 bytes from the current position. This should succeed
without changing anything on a normal file, and fail without changing
anything on a non-seekable file.
A note to people coming from a DOS background: In DOS, a pipeline "a|b"
writes the output from a to a temporary file, then invokes b with its input
from that temporary file. In Unix, a pipeline "a|b" executes a and b at
the same time with a "pipe" connecting the two processes. This difference
can be noticed when trying to seek, and sometimes when there are buffering
effects in the pipe between A and B.
One last note -- the file descriptor returned by popen*() is also
non-seekable.
Jeff
More information about the Python-list
mailing list