Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>The code provided by eerpini does not work as written. Note, for example, that the pipe ends that are closed in the parent are used afterwards. Look at </p> <pre><code>close(wpipefd[1]); </code></pre> <p>and the subsequent write to that closed descriptor. This is just transposition, but it shows this code has never been used. Below is a version that I have tested. Unfortunately, I changed the code style, so this was not accepted as an edit of eerpini's code. </p> <p>The only structural change is that I only redirect the I/O in the child (note the dup2 calls are only in the child path.) This is very important, because otherwise the parent's I/O gets messed up. Thanks to eerpini for the initial answer, which I used in developing this one.</p> <pre><code>#include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; #include &lt;unistd.h&gt; #include &lt;errno.h&gt; #define PIPE_READ 0 #define PIPE_WRITE 1 int createChild(const char* szCommand, char* const aArguments[], char* const aEnvironment[], const char* szMessage) { int aStdinPipe[2]; int aStdoutPipe[2]; int nChild; char nChar; int nResult; if (pipe(aStdinPipe) &lt; 0) { perror("allocating pipe for child input redirect"); return -1; } if (pipe(aStdoutPipe) &lt; 0) { close(aStdinPipe[PIPE_READ]); close(aStdinPipe[PIPE_WRITE]); perror("allocating pipe for child output redirect"); return -1; } nChild = fork(); if (0 == nChild) { // child continues here // redirect stdin if (dup2(aStdinPipe[PIPE_READ], STDIN_FILENO) == -1) { exit(errno); } // redirect stdout if (dup2(aStdoutPipe[PIPE_WRITE], STDOUT_FILENO) == -1) { exit(errno); } // redirect stderr if (dup2(aStdoutPipe[PIPE_WRITE], STDERR_FILENO) == -1) { exit(errno); } // all these are for use by parent only close(aStdinPipe[PIPE_READ]); close(aStdinPipe[PIPE_WRITE]); close(aStdoutPipe[PIPE_READ]); close(aStdoutPipe[PIPE_WRITE]); // run child process image // replace this with any exec* function find easier to use ("man exec") nResult = execve(szCommand, aArguments, aEnvironment); // if we get here at all, an error occurred, but we are in the child // process, so just exit exit(nResult); } else if (nChild &gt; 0) { // parent continues here // close unused file descriptors, these are for child only close(aStdinPipe[PIPE_READ]); close(aStdoutPipe[PIPE_WRITE]); // Include error check here if (NULL != szMessage) { write(aStdinPipe[PIPE_WRITE], szMessage, strlen(szMessage)); } // Just a char by char read here, you can change it accordingly while (read(aStdoutPipe[PIPE_READ], &amp;nChar, 1) == 1) { write(STDOUT_FILENO, &amp;nChar, 1); } // done with these in this example program, you would normally keep these // open of course as long as you want to talk to the child close(aStdinPipe[PIPE_WRITE]); close(aStdoutPipe[PIPE_READ]); } else { // failed to create child close(aStdinPipe[PIPE_READ]); close(aStdinPipe[PIPE_WRITE]); close(aStdoutPipe[PIPE_READ]); close(aStdoutPipe[PIPE_WRITE]); } return nChild; } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

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