Note that there are some explanatory texts on larger screens.

plurals
  1. POUsing poll function with buffered streams
    text
    copied!<p>I am trying to implement a client-server type of communication system using the <a href="http://man7.org/linux/man-pages/man2/poll.2.html" rel="nofollow">poll</a> function in C. The flow is as follows:</p> <ol> <li>Main program forks a sub-process</li> <li>Child process calls the <code>exec</code> function to execute <code>some_binary</code></li> <li>Parent and child send messages to each other alternately, each message that is sent depends on the last message received.</li> </ol> <p>I tried to implement this using <code>poll</code>, but ran into problems because the child process buffers its output, causing my <code>poll</code> calls to timeout. Here's my code:</p> <pre><code>int main() { char *buffer = (char *) malloc(1000); int n; pid_t pid; /* pid of child process */ int rpipe[2]; /* pipe used to read from child process */ int wpipe[2]; /* pipe used to write to child process */ pipe(rpipe); pipe(wpipe); pid = fork(); if (pid == (pid_t) 0) { /* child */ dup2(wpipe[0], STDIN_FILENO); dup2(rpipe[1], STDOUT_FILENO); close(wpipe[0]); close(rpipe[0]); close(wpipe[1]); close(rpipe[1]); if (execl("./server", "./server", (char *) NULL) == -1) { fprintf(stderr, "exec failed\n"); return EXIT_FAILURE; } return EXIT_SUCCESS; } else { /* parent */ /* close the other ends */ close(wpipe[0]); close(rpipe[1]); /* poll to check if write is good to go This poll succeeds, write goes through */ struct pollfd pfds[1]; pfds[0].fd = wpipe[1]; pfds[0].events = POLLIN | POLLOUT; int pres = poll(pfds, (nfds_t) 1, 1000); if (pres &gt; 0) { if (pfds[0].revents &amp; POLLOUT) { printf("Writing data...\n"); write(wpipe[1], "hello\n", 6); } } /* poll to check if there's something to read. This poll times out because the child buffers its stdout stream. */ pfds[0].fd = rpipe[0]; pfds[0].events = POLLIN | POLLOUT; pres = poll(pfds, (nfds_t) 1, 1000); if (pres &gt; 0) { if (pfds[0].revents &amp; POLLIN) { printf("Reading data...\n"); int n = read(rpipe[0], buffer, 1000); buffer[n] = '\0'; printf("child says:\n%s\n", buffer); } } kill(pid, SIGTERM); return EXIT_SUCCESS; } } </code></pre> <p>The server code is simply:</p> <pre><code>int main() { char *buffer = (char *) malloc(1000); while (scanf("%s", buffer) != EOF) { printf("I received %s\n", buffer); } return 0; } </code></pre> <p>How do I prevent <code>poll</code> calls from timing out because of buffering?</p> <p>EDIT:</p> <p>I would like the program to work even when the <code>exec</code>ed binary is external, i.e., I have no control over the code - like a unix command, e.g., <code>cat</code> or <code>ls</code>.</p>
 

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