1

我对 C 语言非常陌生,并且正在尝试学习如何在 Unix 环境中使用管道将数据从父进程传输到子进程,反之亦然。在下面的代码中,我收到一个命令行参数并根据参数的值构建一个 char 数组。然后,我使用管道将 char 数组传递给将执行名为 vc 的程序的子级。该程序根据 char 数组返回一个数字结果。我的问题是如何使用第二个管道将结果返回给父级?另外,一旦父母拥有它,由于父母被设置为将输出发送给孩子,我该如何将其打印到屏幕上?谢谢你。

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

int main(int argc,char *argv[])
{
    int 
        pfildes[2],
        pid,
        argNumber;
    char
        buffer[256],
        charString[1024]; 
    //Check for arguments 
    if(argc != 2) {
        printf("No command line arguements given.\n");
        argNumber=10; //default
    }
    else
       argNumber=atoi(argv[1]);

    //***********************************
    //Build charString based on argNumber
    //***********************************       

    //create pipes
    if(pipe(pfildes) == -1) {
        //error occured when creating pipe
        perror("demo");
        exit(1);
    }
    //create child process
    if((pid=fork()) < 0) {
        //error occured when forking child
        perror("demo");
        exit(1);
    }
    else if(pid > 0) {
        //parent process
        close(pfildes[0]);
        dup2(pfildes[1],1);
        printf("%s", charString);

        close(pfildes[1]);

        perror("demo");
        _exit(1);
    }
    else {
        //child process
        close(pfildes[1]);
        dup2(pfildes[0],0);
        execlp("/usr/bin/vc","vc", NULL);
        close(pfildes[0]);

        perror("demo");
        exit(1);
    }

    while(wait(NULL) >0);
    return 0;
}
4

1 回答 1

1

您可以使用socketpair()而不是pipe()在父进程和子进程之间生成双向通信通道:

//...
if (socketpair(PF_UNIX, SOCK_STREAM, 0, pfildes) == -1) {
    //error occured when socket pair
    perror("demo: socketpair");
    exit(1);
}
//..

在子进程中,您可以dup()在调用之前将一对中的一个同时输入和输出exec()

//...
else {
    //child process
    close(pfildes[1]);
    dup2(pfildes[0],0);
    dup2(pfildes[0],1);
    dup2(pfildes[0],2);
    close(pfildes[0]);
    execlp("/usr/bin/vc","vc", NULL);
    perror("demo: child exec");
    exit(1);
}
//...

在父进程中,您可以使用FILE *从文件描述符创建一个fdopen(),因此您不需要dup()覆盖现有的stdout文件描述符:

//...
else if(pid > 0) {
    //parent process
    close(pfildes[0]);
    FILE *to_child = fdopen(dup(pfildes[1]), "w");
    FILE *from_child = fdopen(dup(pfildes[1]), "r");
    close(pfildes[1]);
    fprintf(to_child, "%s", charString);
    while (fgets(buf, sizeof(buf), from_child) != NULL) {
        //...do something with output
    }
    //...
} else { //...
于 2013-09-10T22:00:40.113 回答