简体   繁体   中英

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.

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?

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.

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

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.

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) 
{ 
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM