简体   繁体   English

Linux管道,fork和execlp:如何将值写入流1中

[英]Linux pipe, fork and execlp: how to get the value written into stream 1

I use a function (L) to execute another program (K) through execlp() . 我使用函数(L)通过execlp()执行另一个程序(K execlp() In the K program, the result is written into stream 1: 在K程序中,结果写入流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? 因为在execlp() ,L的剩余部分将不会被执行,我怎样才能得到在流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). 我跟着你们的建议,但现在的问题是,K程序获取参数的方式来自流(一个标准流,另一个流),我使用管道将参数写入相应的流(由父进程完成) )。

After the child exec, in the parent part, I read from stream 0 (the K program writes its result back in stream 1). 在子exec之后,在父部分中,我从流0读取(K程序将其结果写回流1中)。 But what I could get is what the parent wrote into the stream, not what the K program write back. 但我能得到的是父母写入流中的内容,而不是K程序写回的内容。 What's wrong? 怎么了? Do I need to add another pipe? 我需要添加另一个管道吗?

Thanks!! 谢谢!!

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() . Jonathan Leffler在评论中提到的关键见解是,在调用execlp()之前,需要fork运行L的程序。

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. 在fork之后,父execlp()继续执行L的其余部分,并且子execlp()通过调用execlp()变换到程序K ,除非出现错误,否则永远不会返回。

Thus, the assertion that "the remaining part of L won't be executed" is incorrect. 因此,“L的剩余部分将不会被执行”的断言是不正确的。 It will get executed, in the parent process if you write the function L correctly. 如果正确编写函数L它将在父进程中执行。

Update : Since the OP made his question more specific, I am appending to this answer. 更新 :由于OP提出了更具体的问题,我接着回答这个问题。

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 . 如果要检索子进程写入stdout (fd 1)的内容,则需要在fork之前创建一个新管道,并将此管道的写入端复制到子项的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);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM