Question

I use a function (L) to execute another program (K) through execlp(). In the K program, the result is written into stream 1:

write(1, (char *)&o, sizeof(int));

Since after execlp(), the remaining part of L won't be executed, how could I get the result written in stream 1?

Don't ask me why I need to do it this way. It's the requirement for a project.

I followed your guys advices, but now the problem is, the way the K program get the arguments are from streams(one standard stream, one other stream), I'm using pipes to write arguments into corresponding streams (it's done by the parent).

After the child exec, in the parent part, I read from stream 0 (the K program writes its result back in stream 1). But what I could get is what the parent wrote into the stream, not what the K program write back. What's wrong? Do I need to add another pipe?

Thanks!!

Was it helpful?

Solution

The key insight, which Jonathan Leffler mentioned in his comment, is that you need to fork the program which is running L before you call execlp().

After the fork, the parent continues to execute the rest of L, and the child morphs into the program K by calling execlp(), which should never return unless there is an error.

Thus, the assertion that "the remaining part of L won't be executed" is incorrect. It will get executed, in the parent process if you write the function L correctly.

Update: Since the OP made his question more specific, I am appending to this answer.

If you want to retrieve what the child process wrote to stdout (fd 1), you need to create a new pipe before the fork, and copy the writing end of this pipe into the child's stdout.

Here is an example program, slightly modified from the pipe man page.

#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

int
main(int argc, char *argv[])
{
    int pipefd[2];
    pid_t cpid;
    char buf;

    if (pipe(pipefd) == -1) {
        perror("pipe");
        exit(EXIT_FAILURE);
    }

    cpid = fork();
    if (cpid == -1) {
        perror("fork");
        exit(EXIT_FAILURE);
    }

    if (cpid == 0) {    /* Child writes into the pipe */
        close(pipefd[0]);          /* Close unused read end */

        // Copy the writing end of the pipe into STDOUT for the child.
        dup2(pipefd[1], STDOUT_FILENO);

        // Execute your program L here, and its stdout will be captured by the pipe.
        const char* message = "Child is speaking to stdout!";
        write(STDOUT_FILENO, message, strlen(message));
        write(STDOUT_FILENO, "\n", 1);


        close(pipefd[1]);
        _exit(EXIT_SUCCESS);

    } else {            /* Parent reads child's stdout  from the pipe */
        close(pipefd[1]);          /* Close unused write end */

        // Here the parent process is reading the child's stdout.
        while (read(pipefd[0], &buf, 1) > 0)
            write(STDOUT_FILENO, &buf, 1);
        wait(NULL);                /* Wait for child */
        exit(EXIT_SUCCESS);
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top