SHELL与PIPE通信使用相同的父进程进行2个子进程

时间:2015-11-25 23:21:50

标签: c shell pipe

我想创建一个基于UNIX的shell,它支持带有1个管道的命令。 例如,命令ls | wc

我已经写了下面的代码但是当我尝试像上面这样的输入时,程序很奇怪并且无法弄清楚故障的位置。

更具体地说,fork()正确显示,然后exec()显示正确的参数,但只有管道(ls)之前的命令正确退出。管道(wc)之后的命令实际上从不退出,因此程序没有输出。

我已经放了一些printf来帮助我弄清楚代码中的错误在哪里。 功能fetch_inputstring_tokenizer已经过测试并且运行正常。

故障必须位于代码中指向的点之下。 任何帮助我找出错误的建议都将受到赞赏。

提前致谢。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

#define ANSI_COLOR_GREEN "\x1b[32m"
#define ANSI_COLOR_CYAN "\x1b[36m"
#define ANSI_COLOR_RESET "\x1b[0m"

char * fetch_input(char * buffer);
char * trim(char * string);
char ** string_tokenizer(char * string, char c);

int main(int arc, char * argv[]){

char *input, *init_input, **commands, **com1, **com2;
pid_t fork_pid_1, fork_pid_2, ret_pid;
int stat,i, fd[2];

init_input = (char *)malloc(sizeof(char)*256);

input = init_input;
input = fetch_input(input);

while(strcmp(input,"exit")!=0){

    commands = string_tokenizer(input,'|');
    com1 = string_tokenizer(commands[0],' ');

    if(commands[1]==0){
        fork_pid_1 = fork();
        if(fork_pid_1<0){
            printf("Fork Error!\n");
            _exit(1);
        }
        else if(fork_pid_1==0){
            execvp(com1[0],com1);
            printf("Exec Error!\n");
            _exit(1);
        }
        else{
            ret_pid=wait(&stat);

        }
    }
    else{                 //the fault is probably somewhere below that point
        if(pipe(fd)<0){ _exit(1);}

        fork_pid_1 = fork();

        if(fork_pid_1<0){
            printf("Fork Error!\n");
            _exit(1);
        }
        else if(fork_pid_1==0){

            printf("First command, ready to exec...(pid:%d)\n",getpid());       

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

            execvp(com1[0],com1);
            printf("Exec Error!\n");
            _exit(1);

        }
        else{
            com2 = string_tokenizer(commands[1],' ');

            fork_pid_2=fork();
            if(fork_pid_2<0){
                printf("Fork Error!\n");
                _exit(1);
            }
            else if(fork_pid_2==0){

                printf("Second command, ready to exec...(pid:%d)\n",getpid());

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

                execvp(com2[0],com2);
                printf("Exec Error!\n");
                _exit(1);


            }
            else{   
                printf("Now we 're in the parent process...(p_pid:%d)\n",getpid());
                while( (ret_pid=waitpid(-1,&stat,0)) >0 ){
                    printf("Child process (%d) exited with status:%d\n",ret_pid,stat);
                }

            }

        }


    }
    input = init_input;
    input = fetch_input(input);
}

return 0;
}

char * fetch_input(char * buffer){

int i, sum;

do{
    printf(ANSI_COLOR_CYAN "$" ANSI_COLOR_RESET);
    fflush(stdin);
    fgets(buffer,256,stdin);
    if(buffer[strlen(buffer)-1]=='\n'){
        buffer[strlen(buffer)-1]='\0';
    }
    sum=0;
    for(i=0;i<strlen(buffer);i++){
        if(buffer[i]==' '){sum++;}
    }
}while(strlen(buffer)==sum);

buffer = trim(buffer);

return buffer;

}

char * trim(char * string){

    int i;

    i=strlen(string);
    while(string[i-1]==' '){
        i--;
    }
    *(string+i)='\0';
    while(isspace(*string)){string++;}

    return string;
}

char ** string_tokenizer(char * string, char c){

     int j=0,k,i,done,found,first,last;
     char ** ret, *str;

     str=string;
     if( (str==0) || (strlen(str)==0) ) return NULL;
     ret = (char **)malloc(sizeof(char*));
     do{
        done=0;
        found=0;
        i=0;
        first=-1;
        last=-1;

        while( (str[i]!='\0') && (done==0) ){

               if( (str[i]==c) && (found==0) ){
                    i++;
               }
               else if( (str[i]!=c) && (found==0) ){
                    found=1;
                    first=i;
                    i++;
               }
               else if( (str[i]!=c) && (found!=0) ){
                    i++;
               }
               else if( (str[i]==c) && (found!=0) ){
                    done=1;
                    last=i;
               }

         }


         if(done!=0){


             *(ret+j) = (char *)malloc(sizeof(char)*(last-first+1));

             for(k=first;k<last;k++){
                 *(*(ret+j)+(k-first)) = str[k];
             }
             *(*(ret+j)+(k-first)) = '\0';
             *(ret+j) = trim(*(ret+j));
             j++;
             str=str+last;
         }


     }while(done!=0);

     if( (done==0) && (found==0) ){
         *(ret+j)=NULL;
     }
     else if( (done==0) && (found!=0) ){
          *(ret+j) = (char *)malloc(sizeof(char)*(i-first+1));
          for(k=first;k<i;k++){
              *(*(ret+j)+(k-first)) = str[k];
          }
          *(*(ret+j)+(k-first)) = '\0';
      *(ret+j)=trim(*(ret+j));
          *(ret+j+1) = NULL;
     }

     return ret;
}

0 个答案:

没有答案