您好我需要一些帮助我为我的c shell创建的管道方法。我试图让它运行一个简单的ls |厕所。
我编写了一个名为createPipe
的方法,它会分叉两个子进程,因为cmd1的标准输出成为cmd2的标准输入。
我还编写了一个名为execute()
的方法,它应该分割我们维护一个常量路径变量的路径)和execv
路径和命令,我必须使用{{ 1}},而不是execv
或execvp
等。
当我在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);
}
}
答案 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} }。
可能还有更多问题......