Hi!
I'm writing a little shell that behaves like old Thompson shell. I've a big problem with the creation of pipe mechanism. I must create pipe mechanism like UNIX shell (cmd1 | cmd2 | ... | cmdn). Below there is a portion of my function:
Code:
int j=0;
for(i=0; i<res; ++i){
if((pid = fork()) < 0){
perror("fork error");
exit(FORK_ERR);
}
if(pid == 0){
if(args!=NULL){
free(args);
args=NULL;
}
args=(char **)calloc(MAX_ARGS,sizeof(char *));
if(do_I_launch_parse(commands[i]) == 1)
parse(commands[i],args);
else{
if(args[j]==NULL)
args[j]=(char *)calloc(strlen(commands[i])+1,sizeof(char));
args[j]=strtok(commands[i]," ");
++j;
while((s=strtok(NULL," ")) != NULL){
if(args[j]==NULL)
args[j]=(char *)calloc(strlen(commands[i])+1,sizeof(char));
strcpy(args[j],s);
++j;
}
}
if(i==0){
close(p1[0]);
close(p2[1]);
close(p2[0]);
if(dup2(p1[1],STDOUT_FILENO) == -1){
perror("dup error");
exit(DUP_ERR);
}
//close(p2[1]);
}
else if(i==res-1){
if(i%2==0){
close(p2[1]);
close(p1[0]);
close(p1[1]);
if(dup2(p2[0],STDIN_FILENO) == -1){
perror("dup error");
exit(DUP_ERR);
}
// close(p2[0]);
}
else{
close(p1[1]);
close(p2[0]);
close(p2[1]);
if(dup2(p1[0],STDIN_FILENO) == -1){
perror("dup error");
exit(DUP_ERR);
}
//close(p1[0]);
}
}
else if(i%2==0){
close(p2[1]);
close(p1[0]);
if(dup2(p2[0],STDIN_FILENO) == -1){
perror("dup error");
exit(DUP_ERR);
}
//close(p2[0]);
if(dup2(p1[1],STDOUT_FILENO) == -1){
perror("dup error");
exit(DUP_ERR);
}
//close(p1[1]);
}
else{
close(p2[0]);
close(p1[1]);
if(dup2(p1[0],STDIN_FILENO) == -1){
perror("dup error");
exit(DUP_ERR);
}
//close(p1[0]);
if(dup2(p2[1],STDOUT_FILENO) == -1){
perror("dup error");
exit(DUP_ERR);
}
//close(p2[1]);
}
((args[0]==NULL) ? execlp(commands[i],commands[i],NULL) : execvp(commands[i],args));
perror("exec failed");
exit(EXEC_ERR);
}
if(pid > 0){
if (waitpid(pid,&status,0) == -1){
if(errno!=EINTR){
perror("waitpid error");
exit(WAIT_ERR);
}
else{
kill(pid,SIGTERM);
do{
if (waitpid(pid,&status,0) != -1)
break;
}while(errno==EINTR);
}
}
}
}
Ignore all the strings management. The problem (I hope) is in the pipe. If i launch a command like "ls -l | grep *.h", I receive this output:
Code:
/home/manugal/Progetto $ ls -l | grep *.h
-rw-r--r-- 1 manugal manugal 3364 2007-01-11 13:28 functions.h
-rw-r--r-- 1 manugal manugal 3371 2007-01-11 13:10 functions.h~
and after the output of second command, it hangs and it returns at prompt only if I press CTRL-C (it seems like that wait any data on pipe), but I don't understand why.
In fact, in the code, if I add a line that set p[0] (that reads) in O_NONBLOCK mode, the output is:
Code:
/home/manugal/Progetto $ ls -l | grep *.h
-rw-r--r-- 1 manugal manugal 3364 2007-01-11 13:28 functions.h
-rw-r--r-- 1 manugal manugal 3371 2007-01-11 13:10 functions.h~
grep: (standard input): Resource temporarily not available
Why? I've tried also to create two pipes to resolve the problem but nothing. Please, help me
Thanks