简体   繁体   中英

Implementing pipes in shell

I am trying to implement pipes in a simple shell but unable to get it working. Can some one please suggest what I might be doing wrong. Read other similar posts but the logic applied is different in other posts. When i run the program giving a command like : cat shell.c | grep int it gives broken pipe error.

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

When your while loop finishes, the parent process loops back and forks again, the trouble is you have already closed an end of the pipe in the parent process, so it will be closed in the child process. To fix it, make sure both pipes are closed at the end of loop, and re-call the pipe function within the loop.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM