Andreas Pakulat
Andreas Pakulat

Reputation:

Communication problem between Java and C++ app on stdin

I have a java app here that starts a C++ app via the java.lang.Process API and then tries to send commands to it via the stdin pipe:

process.getOutputStream().write("foo\n");
process.getOutputStream().flush();

On the C++ side there's a loop running that checks for input in stdin and if there is some it reads it. Unfortunately the checking always returns 0, hence it never tries to read. If I remove the check then it'll suddenly start to see the commands and process them. This is on linux.

The C++ apps code to check and read from stdin is this:

fd_set fds;
FD_ZERO ( &fds );
FD_SET ( 0, &fds );

struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 0;


if( select ( 1, &fds, 0, 0, &tv ) > 0 ) {
    char buf[16384];
    buf[16383] = '\0';
    if ( fgets ( buf, sizeof ( buf ) - 1, stdin ) == 0 )
        return;
}

As I said, removing the if clause makes it work, but of course thats not so nice as the loop around it also does some other things. Anybody got an idea what I'm doing wrong here?

Update: Meanwhile I was able to reproduce the problem with two very small sample apps. The problem seems to be related to the Qt framework here, as soon as I create the QCoreApplication instance needed for the framework then select() for stdin doesn't seem to work anymore.

Upvotes: 1

Views: 546

Answers (5)

Vijay Angelo
Vijay Angelo

Reputation: 762

Is the below inside the while loop? If not, it should be.

FD_ZERO ( &fds );
FD_SET ( 0, &fds );

struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 0;

If the answer for my first question is yes, then please try this timeout:

tv.tv_sec = 0;
tv.tv_usec = 1;

If the above doesn't work, try this:

while(fgets(buf, sizeof ( buf ) - 1, stdin) !=NULL) 
{ 
}

Upvotes: 0

Andreas Pakulat
Andreas Pakulat

Reputation:

Turns out its not the QCoreApplication as I could now reproduce the problem twice with out. Seems like the problem is the fgets() that I'm using, replacing that with read() fixes it.

Upvotes: 0

Jay
Jay

Reputation: 14461

I remember there being a lot of argument about the semantics and operation of select() and a couple of replacements for it. You might look at those.

How is the stream you're reading being created/opened? Is it a buffered stream? Perhaps you get nothing because it's not been written to the stream until the writing process flushes it?

The other thing you might try is putting it on a thread with blocking I/O instead of polling.

Good luck with it

Upvotes: 0

lavinio
lavinio

Reputation: 24299

You have two if's; removing which one makes it work?

Doesn't fgets() wait for a newline, buffer full, or EOF before it returns? I don't see you writing a newline, "foo" doesn't fill the buffer, and since the stream isn't closed, does it see an EOF?

Upvotes: 1

Martin Cote
Martin Cote

Reputation: 29842

I may be wrong, but does having a timeout of 0 for the select call makes sense? I would try to increase the timeout value.

Upvotes: 0

Related Questions