Determine the size of a pipe without calling read()

14,464

Solution 1

Depending on your unix implementation ioctl/FIONREAD might do the trick

err = ioctl(pipedesc, FIONREAD, &bytesAvailable);

Unless this returns the error code for "invalid argument" (or any other error) bytesAvailable contains the amount of data available for unblocking read operations at that time.

Solution 2

Some UNIX implementations return the number of bytes that can be read in the st_size field after calling fstat(), but this is not portable.

Solution 3

Unfortunately the system cannot always know the size of a pipe - for example if you are piping a long-running process into another command, the source process may not have finished running yet. In this case there is no possible way (even in theory) to know how much more data is going to come out of it.

If you want to know the amount of data currently available to read out of the pipe that might be possible, but it will depend on OS buffering and other factors which are hard to control. The most common approach here is just to keep reading until there's nothing left to come (if you don't get an EOF then the source process hasn't finished yet). However I don't think this is what you are looking for.

So I'm afraid there is no general solution.

Solution 4

There is no generic, portable way to tell how much data is available in a pipe without reading it. At least not under POSIX specifications.

Pipes are not seekable, and neither is it possible to put the data back into the reading end of a pipe.

Platform-specific tricks might be possible, though. If your question is platform-specific, editing your question to say so might improve your chances to get a working answer.

Solution 5

It's not in general possible to know the amount of data you can read from a pipe just from the pipe handle alone. The data may be coming in across a network, or being dynamically generated by another process. If you need to know up front, you should arrange for the information to be sent to you - through the pipe, or out of band - by whatever process is at the other end of the pipe.

Share:
14,464
Admin
Author by

Admin

Updated on June 13, 2022

Comments

  • Admin
    Admin almost 2 years

    I need a function called SizeOfPipe() which should return the size of a pipe - I only want to know how much data is in the pipe and not actually read data off the pipe itself.

    I thought the following code would work:

    fseek (pPipe, 0 , SEEK_END);
    *pBytes = ftell (pPipe);
    rewind (pPipe);
    

    but fseek() doesn't work on file descriptors. Another option would be to read the pipe then write the data back but would like to avoid this if possible. Any suggestions?

  • Thomas Guyot-Sionnest
    Thomas Guyot-Sionnest over 3 years
    To do a select() on the pipe you must open it with O_RDWR. Also why not use O_NONBLOCK and keep reading until you get EAGAIN?