C - 具有嵌套fgets循环的分叉和管道

时间:2014-04-27 09:40:25

标签: c exec pipe fgets

我一直试图让这个工作,并开始认为不可能以这种方式使用管道。

这可能吗?在父进程使用fgets while循环将输入推送到子进程时保持管道打开?然后,子进程将检测输入(通过标准输入)并将其打印到屏幕上。

如果不可能,为什么不呢?

pipe.c:

#define MAXINPUTLINE 10240

int pid, p[2];
char input[MAXINPUTLINE];

int main(void)
{
    char* arguments[] = {"./bin/child_program", "arg1", NULL};

    if(pipe(p) == -1) {
        printf("Pipe Failed\n");
        exit(1);
    }
    pid = fork();
    if(pid == -1) {
        printf("Fork Failed\n");
        exit(1);
    }

    int status;

    if(pid == 0) {  //child
        close(p[1]); //close stdout
        dup2(p[0],0); //open stdin
        execvp(arguments[0],arguments);
    }
    else { //parent
        close(p[0]);
        while (fgets(input, sizeof(input), stdin))
            write(p[1],input,strlen(input)+1);
        wait(&status);
    }

    return 0;
}

child_program:

    #define MAXINPUTLINE 

    int main(int argc, char *argv[])
    {   
        char input[MAXINPUTLINE];

        while (fgets(input, sizeof(input), stdin)) { 
            printf(" Input Recieved: %s :",input);
        }

        return 0;
    }

1 个答案:

答案 0 :(得分:0)

我有一个工作代码,用于解决您在此处尝试实现的目标:

https://sourceware.org/git/?p=netresolve.git;a=blob;f=backends/exec.c;h=026b137973b35a7232b0554a7e7b8dfc1a023051;hb=HEAD#l45

static bool
start_subprocess(char *const command[], int *pid, int *infd, int *outfd)
{
    int p1[2], p2[2];

    if (!pid || !infd || !outfd)
            return false;

    if (pipe(p1) == -1)
            goto err_pipe1;
    if (pipe(p2) == -1)
            goto err_pipe2;
    if ((*pid = fork()) == -1)
            goto err_fork;

    if (*pid) {
            *infd = p1[1];
            *outfd = p2[0];
            close(p1[0]);
            close(p2[1]);
            return true;
    } else {
            dup2(p1[0], 0);
            dup2(p2[1], 1);
            close(p1[0]);
            close(p1[1]);
            close(p2[0]);
            close(p2[1]);
            execvp(*command, command);
            /* Subprocess error occured. */
            fprintf(stderr, "error running %s: %s\n", *command, strerror(errno));
            abort();
    }

err_fork:
    close(p2[1]);
    close(p2[0]);
err_pipe2:
    close(p1[1]);
    close(p1[0]);
err_pipe1:
    return false;
}

您可以将此功能视为公共领域。它接受以NULL结尾的命令行参数列表,包括命令本身,并设置进程ID 和文件描述符以与 stdin stdout 输出参数。

最重要的是,您将获得关于read / write POSIX样式函数(和系统调用),fgets / fputs和类似(缓冲)ANSI的一些知识风格的功能和它们之间的桥梁,如fdopen