tags:

views:

1231

answers:

12

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 dosent work on file descriptors. Another option would be to read the pipe then write the data back but would like to avoid this if possibe, any suggestions ?

+1  A: 

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.

moonshadow
+2  A: 

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.

Alexey Feldgendler
A: 

I don't think it is possible, isn't the point of a pipe to provide interprocess communication between the two ends (in one direction). If I'm correct in that assertion, the send may not yet have finished pushing data into the pipe -- so it'd be impossible to determine the length.

What platform are you using?

Ray Hayes
+4  A: 

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.

Leigh Caldwell
+1  A: 

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.

CL
A: 

I do not think it's possible. Pipes present stream-oriented protocol rather than packet-oriented one. IOW, if you write to a pipe twice, once with,say, 250 bytes and once with, say, 520 bytes, there is no way to tell how many bytes you'll get from the other end in one read request. You could get 256, 256, and then the rest.

If you need to impose packets on a pipe, you need to do it yourself by writing pre-determined (or delimited) number of bytes as packet length, and then the rest of teh packet. Use select() to find out if there is data to read, use read() to get a reasonably-sized buffer. When you have your buffer, it's your responsibility to determine the packet boundary.

Arkadiy
A: 

If you want to know the amount of data that it's expected to arrive, you could always write at the begining of every msg sent by the pipes the size of the msg. So write for example 4 bytes at the start of every msg with the length of your data, and then only read the first 4 bytes.

João Augusto
+4  A: 
VolkerK
+1  A: 

It's almost never necessary to know how many bytes are in the pipe: perhaps you just want to do a non-blocking read() on the pipe, ie. to check if there are any bytes ready, and if so, read them, but never stop and wait for the pipe to be ready.

You can do that in two steps. First, use the select() system call to find out whether data is available or not. An example is here: http://www.developerweb.net/forum/showthread.php?t=2933

Second, if select tells you data is available, call read() once, and only once, with a large block size. It will read only as many bytes are available, or up to the size of your block, whichever is smaller. If select() returns true, read() will always return right away.

apenwarr
A: 

There is no portable way to tell the amount of data coming from a pipe. The only thing you could do is to read and process data as it comes.

For that you could use something like a circular buffer

Iulian Şerbănoiu
A: 

On Windows you can always use PeekNamedPipe, but I doubt that's what you want to do anyway.

MSN

MSN
A: 

You can wrap it in object with buffering that can be rewinded. This would be feasible only for small amounts of data.

One way to do this in C is to define stuct and wrap all functions operating on pipes for your struct.

devdimi