帮助我的c shell中的管道工作

时间:2015-04-18 20:57:58

标签: c linux shell

您好我需要一些帮助我为我的c shell创建的管道方法。我试图让它运行一个简单的ls |厕所。

我编写了一个名为createPipe的方法,它会分叉两个子进程,因为cmd1的标准输出成为cmd2的标准输入。

我还编写了一个名为execute()的方法,它应该分割我们维护一个常量路径变量的路径)和execv路径和命令,我必须使用{{ 1}},而不是execvexecvp等。

当我在execlp的{​​{1}}部分执行我的程序时,我会继续执行该程序。 wc是一个无效的命令。

如果我尝试createPipe方法execute(command)中的命令而不是execv方法,则会遇到我插入到方法中的错误,所以我得到:

createPipe

我不确定是什么问题。如果我的execute方法中的内容不正确,或者我的no exec child1: bad address 方法出现问题,或者我的createPipe程序中没有正确处理问题。另一种意见确实会有所帮助。

这是我的代码:

execute

Pipe.c

main

/* main.c */ #define NUM_ARGS 10 #define BUF_SIZE 128 void utility(char *array[]); void cleararray(char *array[]) { int i=0; while(array[i]!=NULL) { array[i]=NULL; i++; } } int main(void){ int redir_Flag=0; int i=0,j; char str[BUF_SIZE]; char *p; char *array[NUM_ARGS]; do { cleararray(array); printf("~MyShell $:"); i=0; fgets(str,sizeof(str),stdin); p=strtok(str," \n"); while(p!=NULL) { array[i]=(char*)malloc(sizeof(p)); strcpy(array[i],p); p=strtok (NULL," \n"); i++; array[i]=NULL; } for(j=0;j<i;j++){ if(strcmp(array[j],">")==0) { array[j]=NULL; redirect(array,array[j+1]); redir_Flag=1; break; } //printf("%s %d\n",array[j],j); } //printf("Before flag checking :%s\n",array[0]); ///////////////////////////////////////////// beginning of pipe check int q; for(q=0; q < i; q++){ if(strcmp(array[q], "|") == 0) { printf("%s %s\n", array[q-1], array[q+1]); //char **cmda=NULL; //char **cmdb=NULL; createPipe(array[q-1], array[q+1]); } } if(redir_Flag==1) { redir_Flag=0; continue; } else{} if(array[0]==NULL){continue;} else if(strcmp(array[0],"exit")==0) { break; } else if(strcmp(array[0],"cd")==0) { change_Dir(array[1]); } else if(strcmp(array[0],"path")==0) { if(array[1]==NULL) { print_path(); } else if(strcmp(array[1],"+")==0) { add_path(array[2]); } else if(strcmp(array[1],"-")==0) { remove_path(array[2]); } else {printf("invalid command\n");} } else if(array[0]==NULL){continue;} else { utility(array); } i=0; fflush(stdout); cleararray(array); }while(1); return 0; } 方法

void createPipe(char **cmd1, char **cmd2){

    pid_t pid1; 
    pid_t pid2;

    int newPipefd[2];

    if(pipe(newPipefd)== -1){
        perror("pipe error");
        exit(1);
    }
    pid1 = fork();
    if(pid1 == -1){
        perror("fork error");
    }
    else if(pid1==0){
        //first child process closes the read end dup write
        close(1);
        dup(newPipefd[1]);
        close(newPipefd[1]);
        close(newPipefd[0]);

        execute(cmd1);     ////////////////////////here is where I have issues
        execv(cmd1[0], cmd1);

        perror("no exec child1");
    }
    else{
        pid2 = fork();
        if(pid2 ==-1){
            perror("fork error");
    }
    else if (pid2 == 0){
        //second child process closes up write side of pipe and dup read
        close(0);
        dup(newPipefd[0]);
        close(newPipefd[0]);
        close(newPipefd[1]);

        execute(cmd2);
        execv(cmd2[0], cmd2);
    } else {
        //parent
        int status;
        close(newPipefd[0]);
        close(newPipefd[1]);
        waitpid(pid1, &status, WUNTRACED | WCONTINUED);
        waitpid(pid2, &status, WUNTRACED | WCONTINUED);
    }
}  

1 个答案:

答案 0 :(得分:2)

我可以在你的代码中看到一些问题。首先,这是一个错误:

 array[j]=(char*)malloc(sizeof(p));
 strcpy(array[j],p);

您为指针分配空间,而不是为字符串的副本分配空间。将这些行替换为:

 array[j] = strdup(p);

for循环中,您无法执行此操作:

 strcat(array[k],"/");
 strcat(array[k],arg[0]);

因为array[k]没有额外的空间容纳最后所用的字符串。你应该重新分配array[k],这意味着你需要分配所有的参数,这样你就不会泄漏内存,也不会混合分配的参数和未分配的参数,尽管这可能并不重要,因为你快速调用{{1} }。

可能还有更多问题......