使用fork和pipe实现管道

时间:2014-04-16 13:40:03

标签: c linux fork pipe

我需要使用fork为我的操作系统类实现无名管道,但我无法让它工作。它是一个简单的代码,并没有什么特别的,但我只是没有得到任何东西。我想跑 ls -l | wc -l但我每次都得到0。

#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h> // for open flags
#include <time.h> // for time measurement
#include <assert.h>
#include <errno.h>
#include <string.h>

int pid,status;
int pipefd[2];

void my_exec(char* cmd, char** argv)
{
    pipe(pipefd);     // Fixed
    pid = fork();
    // pipe(pipefd);  // Original

    if(pid==0){
        close(pipefd[0]);
        dup2(pipefd[1],fileno(stdout));
        close(pipefd[1]);
        execvp(cmd, argv);


    }
    else {
        close(pipefd[1]);
        dup2(pipefd[0],fileno(stdin));
        while(wait(&status)!=-1);
        close(pipefd[0]);
        return; 
    }

}

int main(int argc, char** argv)
{
    assert(strcmp(argv[argc-1], "-"));

    int i;
    for (i = 1; i < argc; ++i) {
        if (!strcmp(argv[i], "-")) {
            argv[i] = NULL;
            my_exec(argv[1], &argv[1]);
            argv = &argv[i];
            argc -= i;
            i = 0;
        }

    }

    char* args[argc];
    args[argc-1] = NULL;
    for (i = 1; i < argc; ++i) {
        args[i-1] = argv[i];

    }

    if (execvp(args[0], args) == -1)
        perror("execvp failed");
    return;
}

btw命令的输入我尝试的是ls -l - wc -l(而不是| type - )

OK鸭解决了它:我应该在fork之前创建管道,更新。

1 个答案:

答案 0 :(得分:0)

你最大的问题是你的叉子在管道前面。这将有效地拥有fork调用pipe()的每个分支,因此您将最终得到两个不同的pipefd集,而不是同一个集合。反转fork()和pipe()的调用顺序,然后你在每个fork中的文件描述符都是一样的。

作为旁注,您可以在每个printf()语句组件中进行if()调试,以确保您永远不会看到两个以上的描述符号。