2

我有以下通过 fork 和 execvp 执行命令的函数。我在 fork 中启动的脚本正在侦听输入数据。如何将数据发送到 myscript?

int external_command()
{

    int pfds[2];
    if (pipe(pfds) < 0)
        return -1;

    if ((uproc.pid = fork()) == -1)
        return -1;

    if (uproc.pid == 0) {
        /* child */

        const char *argv[4];
        int i = 0;
        argv[i++] = "/bin/sh";
        argv[i++] = "myscript.sh";
        argv[i++] = NULL;

        close(pfds[0]);
        dup2(pfds[1], 1);
        close(pfds[1]);

        execvp(argv[0], (char **) argv);
        exit(ESRCH);

    } else if (uproc.pid < 0)
        return -1;

    /* parent */
    close(pfds[1]);

    int status;
    while (wait(&status) != uproc.pid) {
        DD("waiting for child to exit");
    }

    char buffer[64];
    ssize_t rxed;
    char *c;
    int t;

    //read from fork pipe
    *value = NULL;
    while ((rxed = read(pfds[0], buffer, sizeof(buffer))) > 0) {
        if (*value)
            t = asprintf(&c, "%s%.*s", *value, (int) rxed, buffer);
        else
            t = asprintf(&c, "%.*s", (int) rxed, buffer);

        if (t == -1) return -1;

        free(*value);
        *value = strdup(c);
        free(c);
    }
    // how to write to the pipe fork?
}
4

3 回答 3

2

管道是单向的。调用pipe两次,以获取一对用于从子级读取数据的文件描述符(正如您已经拥有的那样),另一个用于向子级发送数据(这将是新的)。您需要像已经在做的那样做同样的事情dup2close以便将新管道设置为孩子的标准输入。

于 2013-07-09T08:38:30.207 回答
2

stdin我猜你的意思是你想从父进程写入子进程?为此,您需要创建两个管道。一个stdout在孩子身上使用,就像你现在一样,另一个必须用于stdin与你现在做的方式大致相同(但当然索引颠倒了)。

当然,您不能wait在给孩子写信之前为孩子写信,因为如果孩子需要输入才能继续,您可能会陷入僵局。

于 2013-07-09T08:40:32.233 回答
0

管道基础

请研究这段代码,以便您了解自己在做什么

int fd[2];  /*write(fd[1],buffer,strlen)
            / read(fd[0],buffer2,SIZE)*/
pid_t cpid;

if(pipe(fd)==-1){
    perror("pipe");
    exit(EXIT_FAILURE);
}
if((cpid=fork())<0){/*  FORK INIT  */
    printf("\n\tFORK ERROR\n");
    exit(1);
}
if(cpid==0){            /*SON*/
    close(fd[0]);
    /********CODE******/
    if((write(fd[1],final2,strlen(final2)))<0){
        perror("\n\tWRITE ERROR");
    }
    close(fd[1]);
}else{                  /*FATHER*/
    close(fd[1]);
    if((read(fd[0],aler,NN))<0){
        perror("\n\tREAD ERROR");   
    }
    wait(NULL);
    /********CODE******/
    close(fd[0]);
}

在这种情况下,父进程(父)从新(子)进程中读取()信息

如果你想要双向读取()写入()创建2个管道(fd1 [2],fd2 [2])

同上逻辑,父读,关闭写端fd1[1],子写,关闭读端fd1[0]

反之亦然

父亲写,关闭读端fd2[0],儿子读,关闭写端fd2[1]

于 2013-07-09T23:51:44.790 回答