在c之间实现简单的shell,同时实现子项之间的管道

时间:2017-04-24 14:38:42

标签: c pipe dup

我想用管做一个简单的shell。 我想我几乎做到了,但它没有回到主要。 我认为执行官没有完成。 以下是我的代码的一部分。 我将命令解析为如下定义的struct块。 符号类型5表示它具有| 。 当我运行这个程序时, this is result image.当我不使用烟斗时,它返回并打印>再次,但当我使用管道时它不会。

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

1 个答案:

答案 0 :(得分:2)

  

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

exec系列调用用一个新的地址空间替换进程的整个地址空间,命令为exec&#d; d。它不会回来。话虽如此,您的子代码看起来还不错。

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

另一个潜在的问题是,你永远不会在命令的标准输入中写任何东西。如果期望输入,它将永远阻止读取。

我认为你需要做的是将链中每个命令的stdout传递给链中下一个命令的stdin(也可能根据它的含义将一些输入放入第一个命令)。