Реализация труб в оболочке - PullRequest
       3

Реализация труб в оболочке

0 голосов
/ 03 сентября 2011

Я пытаюсь реализовать каналы в простой оболочке, но не могу заставить их работать. Кто-нибудь может подсказать, пожалуйста, что я могу делать не так. Читайте другие подобные посты, но применяемая логика отличается в других постах. Когда я запускаю программу, которая дает команду вроде: 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 голосов
/ 03 сентября 2011

Когда цикл while завершается, родительский процесс возвращается назад и снова разветвляется, проблема в том, что вы уже закрыли конец канала в родительском процессе, поэтому он будет закрыт в дочернем процессе. Чтобы исправить это, убедитесь, что обе трубы закрыты в конце цикла, и повторно вызовите функцию канала внутри цикла.

...