Note that there are some explanatory texts on larger screens.

plurals
  1. POBi-directional inter-process communication using two pipes
    text
    copied!<p>I am trying to write code that forks a subprocess and communicates with it using pipes. I am using two pipes - one for writing to, and the other for reading from the standard streams of the subprocess. Here's what I have so far:</p> <pre><code>#include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; #include &lt;unistd.h&gt; #include &lt;signal.h&gt; #include &lt;string.h&gt; void read_move(int fd) { FILE *stream = fdopen(fd, "r"); char c; setvbuf(stream, NULL, _IONBF, BUFSIZ); while ((c = fgetc(stream)) != EOF) { putchar(c); } fclose(stream); } void write_move(int fd, const char *move) { FILE *stream = fdopen(fd, "w"); setvbuf(stream, NULL, _IONBF, BUFSIZ); fprintf(stream, "%s", move); fclose(stream); } int main() { pid_t pid; int wpipe[2]; int rpipe[2]; if (pipe(wpipe) || pipe(rpipe)) { fprintf(stderr, "Pipe creation failed.\n"); return EXIT_FAILURE; } pid = fork(); if (pid == 0) { /* gnuchess process */ setvbuf(stdin, NULL, _IONBF, BUFSIZ); setvbuf(stdout, NULL, _IONBF, BUFSIZ); setvbuf(stderr, NULL, _IONBF, BUFSIZ); dup2(wpipe[0], STDIN_FILENO); dup2(rpipe[1], STDOUT_FILENO); dup2(rpipe[1], STDERR_FILENO); close(wpipe[0]); close(wpipe[1]); close(rpipe[0]); close(rpipe[1]); if (execl("/usr/games/gnuchess", "gnuchess", "-x", NULL) == -1) { fprintf(stderr, "Exec failed.\n"); return EXIT_FAILURE; } return EXIT_SUCCESS; } /* parent process */ printf("Sending move to GNU Chess... \n"); close(wpipe[0]); /* Close other end */ write_move(wpipe[1], "c3\n"); printf("Reading response... \n"); close(rpipe[1]); /* Close other end */ read_move(rpipe[0]); /* clean up */ close(wpipe[1]); close(rpipe[0]); /* kill gnuchess */ kill(pid, SIGTERM); return EXIT_SUCCESS; } </code></pre> <p>The output of the above program is</p> <pre><code>Sending move to GNU Chess... Reading response... </code></pre> <p>It gets stuck at the <code>getline</code> call in the <code>read_move</code> function, waiting for input. But I don't understand how that's possible, since I have closed the other end.</p> <p>What am I doing wrong?</p> <p>EDIT: I changed the <code>read_move</code> method and closed the pipe ends in the child process after the <code>dup2</code> calls.</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