bug-glibc
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]