Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Actually, after struggling with it a bit, it seems like the only solution to this problem is by making the 'parent' process pretending to be a terminal using the OS pseudo terminal API calls.</p> <p>One should call 'openpty()' before the fork(), and inside the child code, he should call 'login_tty(slave)' the slave is then becoming the stdin/out and stderr.</p> <p>By pretending to a terminal, the buffering of stdout is automatically set to 'line mode' (i.e. flush occurs when \n is encountered). The parent should use the 'master' descriptor for readin/writing with the child process.</p> <p>The modified parent code (in case anyone will ever need this):</p> <pre><code>#include &lt;unistd.h&gt; #include &lt;signal.h&gt; #include &lt;sys/types.h&gt; #include &lt;sys/select.h&gt; #include &lt;errno.h&gt; #include &lt;sys/wait.h&gt; #include &lt;string&gt; #include &lt;string.h&gt; #include &lt;cstdio&gt; #include &lt;pty.h&gt; #include &lt;utmp.h&gt; static int read_handle(-1); static pid_t pid; bool read_from_child(std::string&amp; buff) { fd_set rs; timeval timeout; memset(&amp;rs, 0, sizeof(rs)); FD_SET(read_handle, &amp;rs); timeout.tv_sec = 1; // 1 second timeout.tv_usec = 0; int rc = select(read_handle+1, &amp;rs, NULL, NULL, &amp;timeout); if ( rc == 0 ) { // timeout return true; } else if ( rc &gt; 0 ) { // there is something to read char buffer[1024*64]; // our read buffer memset(buffer, 0, sizeof(buffer)); if(read(read_handle, buffer, sizeof(buffer)) &gt; 0) { buff.clear(); buff.append( buffer ); return true; } return false; } else { /* == 0 */ if ( rc == EINTR || rc == EAGAIN ) { return true; } // Process terminated int status(0); waitpid(pid, &amp;status, 0); return false; } } void execute() { char *argv[] = {"/home/eran/devl/TestMain/Debug/TestMain", NULL}; int argc = 1; int master, slave; openpty(&amp;master, &amp;slave, NULL, NULL, NULL); int rc = fork(); if ( rc == 0 ) { login_tty(slave); close(master); // execute the process if(execvp(argv[0], argv) != 0) perror("execvp"); } else if ( rc &lt; 0 ) { perror("fork"); return; } else { // Parent std::string buf; close(slave); read_handle = master; while(read_from_child(buf)) { if(buf.empty() == false) { printf("Received: %s", buf.c_str()); } buf.clear(); } } } int main(int argc, char **argv) { execute(); return 0; } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload