How to write to the pipe fork?

2019-07-10 19:45发布

I have the following function which execute command via fork and execvp. my script that I launch in fork is listening for input data. How I can send data to 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?
}

标签: c linux fork
3条回答
不美不萌又怎样
2楼-- · 2019-07-10 20:16

A pipe is unidirectional. Call pipe twice, to get one pair of file descriptors for reading data from the child (as you already have) and another to sent data to the child (which will be new). You'll need to do the same sort of dup2 and close magic as you're already doing, in order to set up that new pipe as stdin for the child.

查看更多
劳资没心,怎么记你
3楼-- · 2019-07-10 20:31

I guess you mean that you want to write to the child process stdin from the parent process? For that you need to create two pipes. One that is used as stdout in the child, like you have now, and the other have to be used for stdin is much the same fashion as you do now (but with the indexes reversed of course).

Of course, you can't wait for the child before you write to it, as then you might have a deadlock if the child needs input to continue.

查看更多
劳资没心,怎么记你
4楼-- · 2019-07-10 20:31

basics of a pipe

please study this bit of code so you learn what you are doing

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]);
}

in this case the parent process(father) read() information from the new(son) process

if you want BI-directional read() write() create 2 pipes(fd1[2],fd2[2])

use the same logic as above, father reads, close the write end fd1[1], son writes, close the read end fd1[0]

vice-versa to the other direction

father writes, close the read end fd2[0], son reads, close the write end fd2[1]

查看更多
登录 后发表回答