2017-04-24 69 views
0

我想用管道制作一个简单的外壳。 我觉得我几乎做到了,但它并没有回到主体。 我认为exec没有完成。 下面是我的代码的一部分。 我解析了如下定义的结构块的命令。 符号类型5表示它具有| 。 当我运行这个程序, this is result image.当我不使用管道,它返回并打印>再次,但是当我使用管道它不。在c中制作简单的外壳,同时在儿童之间实现管道

typedef struct Command { 
    char *file;    // file to execute 
    char **arglist;   // argument list to executable 
    SymbolType symbolType; // command seperator 

    int status;    // exit code of the commnad 

    struct Command *next, *prev; 
} Command; 


void GetPipe(Command *command, int *fd){ 
    SymbolType symbol = command->symbolType; 
    if(symbol==5){ 
     close(1); 
     close(fd[0]); 
     dup2(fd[1],1); 
} 

    if((command->prev)!=NULL) symbol=command->prev->symbolType; 
    if(symbol==5){ 
    close(0); 
    close(fd[1]); 
    dup2(fd[0],0); 
    } 
} 

void ExecuteCommand(Command *command){ 
    int fd[2]; 
    pipe(fd); 
    for(;command!=NULL;command=command->next){ 
    pid_t pid = fork(); 
    if(pid<0) exit(1); 
    else if(pid==0){ 
     GetPipe(command, fd); 
     if (execvp(command->file, command->arglist)==-1){ 
     command->status=status_failure; exit(1);}} 
    else { 
     int status; 
     //waitpid(pid, &status, 0); 
     wait(&status); 
    } 
    } 

    close(fd[0]); 
    close(fd[1]); 

} 

int main(void){ 

Command *head = NULL; 
int should_run = 1; 

    while (should_run){ 
    printf("> "); 
    fflush(stdout); 
    GetCommandChain(&head); 
    ExecuteCommand(head); 
    DeleteCommandChain(head); 
    } 
} 
+0

你为什么认为'exec'没有完成?您是否使用调试程序浏览了代码?如果没有,请这样做,并发布你发现的内容。 –

回答

2

。我认为执行没​​有完成。

exec家庭系统调用替换的命令是exec“d新的地址空间的整个进程的地址空间。它不会返回。说了这么多,你的孩子的代码看起来很好。

一个潜在的问题是父进程不会对管道的读取结束做任何事情。因此,命令会将其输出写入管道,然后当缓冲区满时,它将阻止写入,等待某些内容读取某些数据。

另一个潜在的问题是,你永远不会写任何东西给命令的stdin。如果它期待输入,它会在阅读时永远阻止。

我认为你需要做的是将链中每个命令的标准输出管理到链中下一个命令的标准输入(也可能根据它是什么将第一个命令放入一些输入)。