在shell中实现管道

时间:2011-09-03 08:29:41

标签: c pipe

我正在尝试在简单的shell中实现管道但无法使其正常工作。有人可以建议我可能做错了什么。阅读其他类似的帖子,但应用的逻辑在其他帖子中是不同的。当我运行程序时给出如下命令:cat shell.c | grep int它给出了管道错误。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#define BUFFER_SIZE 1<<16
#define ARR_SIZE 1<<16

void parse_args(char *buffer, char** args, 
            size_t args_size, size_t *nargs)
{
char *buf_args[args_size]; /* You need C99 */
char **cp;
char *wbuf;
size_t i, j;

wbuf=buffer;
buf_args[0]=buffer; 
args[0] =buffer;

for(cp=buf_args; (*cp=strsep(&wbuf, " \n\t")) != NULL ;){
    if ((*cp != '\0') && (++cp >= &buf_args[args_size]))
        break;
}

for (j=i=0; buf_args[i]!=NULL; i++){
    if(strlen(buf_args[i])>0)
        args[j++]=buf_args[i];
}

*nargs=j;
args[j]=NULL;
}


int main(int argc, char *argv[], char *envp[]){
char buffer[BUFFER_SIZE];
char *args[ARR_SIZE];

int *ret_status;
size_t nargs;
pid_t pid;
size_t j;
int pipe_fd[2];
      pipe(pipe_fd); // should pipe be placed here?    
while(1){
    printf("$ ");
    fgets(buffer, BUFFER_SIZE, stdin);
    parse_args(buffer, args, ARR_SIZE, &nargs); 

    if (nargs==0) continue;
    if (!strcmp(args[0], "exit" ) ) exit(0);       
    pid = fork();
    if(pid==0)
     {
     dup2(pipe_fd[0],0);
       close(pipe_fd[1]);

        j=execvp(args[0], args);
        if(j)
        {
            puts(strerror(errno));
            exit(127);
        }

    }else{
            dup2(pipe_fd[1],1);
           close(pipe_fd[0]);
          pid = wait(ret_status);
         }
  }    
 return 0;
}

1 个答案:

答案 0 :(得分:0)

当你的while循环结束时,父进程循环返回并再次分叉,问题是你已经关闭了父进程中管道的一端,所以它将在子进程中关闭。要修复它,确保在循环结束时关闭两个管道,并在循环内重新调用管道函数。