[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: fstat() on a pipe or socketpair descriptor always shows size / lengt
From: |
Paul Jarc |
Subject: |
Re: fstat() on a pipe or socketpair descriptor always shows size / length of 0 (zero) |
Date: |
Thu, 11 Sep 2003 12:06:56 -0400 |
User-agent: |
Gnus/5.1003 (Gnus v5.10.3) Emacs/21.3 (gnu/linux) |
address@hidden wrote:
> When I call fstat() on a pipe or socketpair descriptor that is NOT
> empty, the stat struct that fstat() fills in always reports a size of
> 0 (zero). To the best of my knowledge the system is supposed to
> provide the length/size of data that is ready to be read.
POSIX/SUSv3 makes no such requirement.
<URL:http://www.opengroup.org/onlinepubs/007904975/basedefs/sys/stat.h.html>:
off_t st_size For regular files, the file size in bytes.
For symbolic links, the length in bytes of the
pathname contained in the symbolic link.
[SHM] For a shared memory object, the length in bytes.
[TYM] For a typed memory object, the length in bytes.
For other file types, the use of this field is
unspecified.
> Here is the pseudo code that, keep in mind, has worked before:
Luck. You can use select() or poll() to see whether there is data to
read, but you can't tell how much.
> close STDIN_FILENO
> close STDOUT_FILENO
> close STDERR_FILENO
> create pipe
> duplicate a pipe descriptor so that the pipe makes up file descriptors
> 0, 1, and 2
> call system() with command line command 'ls'
> call fstat() to determine the size of data the 'ls' produced
> create buffer the size of waiting data
> read data into buffer
> display data
If you wait for ls to exit before reading any data, then you'll hang
if ls's output happens to be larger than the kernel's fixed-size
buffer for pipes. The reliable way to do this is:
create the pipe
fork
in the child:
close the pipe's input side
shuffle the pipe's output side to the appropriate descriptor(s)
exec ls
in the parent:
close the pipe's output side
read data as it comes, growing your buffer as necessary
when you get EOF or a read error, wait() for the child
You can't use system() if you want to be reliable.
paul