Discussion:
Problem with buffers? IPC through pipes
(too old to reply)
Noah Roberts
2003-12-05 05:52:08 UTC
Permalink
I am having trouble getting two programs to communicate through pipes.
One of them simply reads from stdin and writes to stdout. The other
creates the pipes and sends commands to the other and reads results
(this is an xboard/engine type of system). I have done everything I can
think of to get rid of buffering in the engine:


#if BUF_STD_COMP // configure does the appropriate thing here.
cin.rdbuf()->pubsetbuf(NULL, 0);
#else
cin.rdbuf()->setbuf(NULL, 0); // Old gcc
#endif

I check for available input like this on Unix:


fd_set fds; // the file descriptors to check
struct timeval tv; // how long to wait
int sel_val; // select() return value

FD_ZERO(&fds);
FD_SET(0, &fds); // stdin
tv.tv_sec = 0; // don't wait at all...
tv.tv_usec = 0;

// The test...
sel_val = select(1, &fds, NULL, NULL, &tv);

if (sel_val) return true;
else return false;

Then the readLine function looks like this:

string final;

int c;
while (cin && (c = cin.get()) != '\n') // Read up to '\n' and append
it to final.
final += c;

cerr << "Data Read: *" << final << "*" << endl;

return final;

And finally my event gathering function:


while (Interface::readReady())
{
cerr << "Input ready.\n";
string input = Interface::readLine();
if (!CommandDispatcher::interpretAndDispatch(input))
Interface::printRaw(string("Error (unknown command): ") + input
+ "\n");
}

cout.flush() is called each and every time something is printed to stdout.

Now the problem:

When more than one command are sent rather quickly to the program it
only gets the first one. It appears that the readReady() function fails
even though to my understanding there should still be input available.
Later if another command is sent it gets everything that was sent
previously as well as the new but again if several where sent at once
only the first arrives.

I am not sure where the bug is, in the engine or the program talking to
it. I tried 'cat | myengine' and got similar results but is cat
flushing its output?

The program talking to my engine is written in Objective-C using gnustep
- I already tried them and got ignored. If someone knows that language
and library maybe they could tell me if my output is being buffered or
something when I use NSPipe. As far as I can tell the send() call is
being used to write to the pipe in this class and I don't know much
about that one - I always used write(). I could easily be mistaken here...

Otherwise if knowledgable people could look at what I have supplied and
see if it is being done correctly I would appreciate any pointers.

This is a class project that is very near due. This will burry me if I
can't figure it out soon and once figured out there is like 30 minutes
top left to do!

Thank you,
NR
Noah Roberts
2003-12-11 06:15:56 UTC
Permalink
Post by Noah Roberts
I am having trouble getting two programs to communicate through pipes.
One of them simply reads from stdin and writes to stdout. The other
creates the pipes and sends commands to the other and reads results
(this is an xboard/engine type of system). I have done everything I can
#if BUF_STD_COMP // configure does the appropriate thing here.
cin.rdbuf()->pubsetbuf(NULL, 0);
#else
cin.rdbuf()->setbuf(NULL, 0); // Old gcc
#endif
fd_set fds; // the file descriptors to check
struct timeval tv; // how long to wait
int sel_val; // select() return value
FD_ZERO(&fds);
FD_SET(0, &fds); // stdin
tv.tv_sec = 0; // don't wait at all...
tv.tv_usec = 0;
// The test...
sel_val = select(1, &fds, NULL, NULL, &tv);
if (sel_val) return true;
else return false;
string final;
int c;
while (cin && (c = cin.get()) != '\n') // Read up to '\n' and append
it to final.
final += c;
cerr << "Data Read: *" << final << "*" << endl;
return final;
while (Interface::readReady())
{
cerr << "Input ready.\n";
string input = Interface::readLine();
if (!CommandDispatcher::interpretAndDispatch(input))
Interface::printRaw(string("Error (unknown command): ") + input
+ "\n");
}
cout.flush() is called each and every time something is printed to stdout.
When more than one command are sent rather quickly to the program it
only gets the first one. It appears that the readReady() function fails
even though to my understanding there should still be input available.
Later if another command is sent it gets everything that was sent
previously as well as the new but again if several where sent at once
only the first arrives.
I am not sure where the bug is, in the engine or the program talking to
it. I tried 'cat | myengine' and got similar results but is cat
flushing its output?
The program talking to my engine is written in Objective-C using gnustep
- I already tried them and got ignored. If someone knows that language
and library maybe they could tell me if my output is being buffered or
something when I use NSPipe. As far as I can tell the send() call is
being used to write to the pipe in this class and I don't know much
about that one - I always used write(). I could easily be mistaken here...
Otherwise if knowledgable people could look at what I have supplied and
see if it is being done correctly I would appreciate any pointers.
This is a class project that is very near due. This will burry me if I
can't figure it out soon and once figured out there is like 30 minutes
top left to do!
Did this message ever make it into the world? At work I can't see it
and here it never got a responce. If you read this message could
someone reply and let me know that it is indeed being propogated?

Thanks,
NR

Loading...