Results 1 to 10 of 13
Hey all,
I am writing my own shell and am trying to implement piping. The code should essentially perform command|command|command.
It works fine if instead of forking to execvp the ...
- 04-25-2008 #1Just Joined!
- Join Date
- Apr 2008
- Posts
- 7
Implementing Piping Problem(URGENT)
Hey all,
I am writing my own shell and am trying to implement piping. The code should essentially perform command|command|command.
It works fine if instead of forking to execvp the last command, I just do it and the shell exits, however I need to fork first. When i added that code, the shell hangs when i execute the command. I'm sure its something stupid and I just don't understand the file descriptors or wait() or something...
:
int pipe1[2], pipe2[2];
pipe(pipe1);//create first pipe
pid_t PID=fork();
if(PID==0){
close(1);
dup(pipe1[1]);
close(pipe1[0]);
close(pipe1[1]);
execvp(*argv,argv);
printf("operation failed");
} else {
pipe(pipe2);
pid_t PID2=fork();
if (PID2==0) {
close(0);
dup(pipe1[0]);
close(1);
dup(pipe2[1]);
close(pipe1[0]);
close(pipe1[1]);
close(pipe2[0]);
close(pipe2[1]);
execvp(*argv2, argv2);
} else {
pid_t PID3=fork();
waitpid(PID3,&status,0);<-----Not sure about this
if(PID3==0){
close(0);
dup(pipe2[0]);
close(pipe1[0]);
close(pipe1[1]);
close(pipe2[0]);
close(pipe2[1]);
execvp(*argv3, argv3);
}
}
}
- 04-25-2008 #2
I think your going around this the wrong way. But *nix/Linux allows you to do it a number of ways. The most simple being;
Generally you just write each individual process as a standalone shell script using input from fd0, output to fd1, errors to fd2. fd=file descriptor.
Test each individual script by themselves, then put them together like so:
At the command line you simply do "ProcessA | ProcessB | ProcessC"
Where ProcessA places its input from fd0 or a file or where ever [fd?] you want it take input from), and outputs to the pipeA;
ProcessB takes pipeA output as input, ProcessB outputs to pipeB input;
ProcessC takes input from pipeB output and output its own to std output (usually fd1 or fd2).
Pipes can be named pipes (i.e.: file on disk - but they are slow) or they are simply handles by your shell.
Enjoy.
- 04-25-2008 #3
wildpossum, you are suggesting ways he can use the shell to pipe his processes together. The problem is that he's not using the shell, he's writing his own shell, obviously as a homework assignment.
mtobin1897, look carefully at that final fork(). Suppose the return value of that fork() is zero, which means this is the parent process's final child. What does that final child do? Well, in your code, the first thing that child process does is a waitpid()! Since that child process has no children, the waitpid() will hang right there. I'm sure that's not your intent.
Hope this helps.--
Bill
Old age and treachery will overcome youth and skill.
- 04-25-2008 #4Just Joined!
- Join Date
- Apr 2008
- Posts
- 7
haha yea it is a hw assignment, and I had an idea the problem was in there, however I am sure I need some sort of wait because if I remove the wait altogether the shell returns nothing but a new prompt, and if I put a waitpid(PID3,&status,0); after the if(PID3==0), so the parent only runs it, than my shell hangs..
- 04-25-2008 #5English is hopelessy imprecise. Can you show us your complete code exactly as you describe it in the above English description?if I put a waitpid(PID3,&status,0); after the if(PID3==0), so the parent only runs it, than my shell hangs.--
Bill
Old age and treachery will overcome youth and skill.
- 04-25-2008 #6Just Joined!
- Join Date
- Apr 2008
- Posts
- 7
haha certainly,
else {
pid_t PID3=fork();
waitpid(PID3,&status,0);<-----MOVE THIS
if(PID3==0){
close(0);
dup(pipe2[0]);
close(pipe1[0]);
close(pipe1[1]);
close(pipe2[0]);
close(pipe2[1]);
execvp(*argv3, argv3);
}
else{
<----HERE
}
- 04-25-2008 #7
Um, I wasn't asking just "where", I was asking "what". :)
I need the complete code, please; in particular, everything you put inside that else clause. Not just the waitpid(), but everything else. I have some ideas, but I need to see what you have.--
Bill
Old age and treachery will overcome youth and skill.
- 04-25-2008 #8Just Joined!
- Join Date
- Apr 2008
- Posts
- 7
int pipe1[2], pipe2[2];
pipe(pipe1);//create first pipe
pid_t PID=fork();
if(PID==0){
close(1);
dup(pipe1[1]);
close(pipe1[0]);
close(pipe1[1]);
execvp(*argv,argv);
printf("operation failed");
} else {
pipe(pipe2);
pid_t PID2=fork();
if (PID2==0) {
close(0);
dup(pipe1[0]);
close(1);
dup(pipe2[1]);
close(pipe1[0]);
close(pipe1[1]);
close(pipe2[0]);
close(pipe2[1]);
execvp(*argv2, argv2);
} else {
pid_t PID3=fork();
if(PID3==0){
close(0);
dup(pipe2[0]);
close(pipe1[0]);
close(pipe1[1]);
close(pipe2[0]);
close(pipe2[1]);
execvp(*argv3, argv3);
}
else{
wait(PID3, &status, 0);
}
}
}
type=0;
numpipes=0;//random variable stuff
background=0;
do{cout<<"sish:>";//shell prompt
gets(line);
parse(line, argv, inputfileName,outputfileName, &type, &numpipes, argv2, argv3, &background);
}while(*line=='\0');
- 04-25-2008 #9Just Joined!
- Join Date
- Apr 2008
- Posts
- 7
so to simplify things, I reduced it to only one pipe with the following code:
int pipe1[2], pipe2[2];
pipe(pipe1);//create first pipe
pid_t PID=fork();
if(PID==0){
close(1);
dup(pipe1[1]);
close(pipe1[0]);
close(pipe1[1]);
execvp(*argv,argv);
/* sort failed */
printf("operation failed");
} else {
pipe(pipe2);
pid_t PID2=fork();
if (PID2==0) {
close(0);
dup(pipe1[0]);
//close(1);
//dup(pipe2[1]);
close(pipe1[0]);
close(pipe1[1]);
//close(pipe2[0]);
// close(pipe2[1]);
execvp(*argv2, argv2);
}else{
wait(NULL);
}
do{cout<<"sish:>";
gets(line);
parse(line, argv, inputfileName,outputfileName, &type, &numpipes, argv2, argv3, &background);
}while(*line=='\0');
now it will display the shell prompt immediatly, however if I exit the shell by typing 'exit', the output is displayed followed by the exiting of the shell...
- 04-25-2008 #10
Are you sure that this most recent post is a fresh copy of your entire source?
Because I can't get it to compile so I can play with it.
For example, you don't define any sort of "parse" function anywhere, even though you call it, and you don't show me your #includes, if you even used any.
I'm running out of time guessing what your code looks like. Maybe if you post the complete, accurate code, I'll have time to take a look at it. (I've taken too much time from other commitments as it is.) And before posting it, make sure that the version you post (a) compiles cleanly and (b) misbehaves the way you said it does. :)
Sorry to be snippy and impolite, but I have limited time resources here. I do hope I have time to get back to this.--
Bill
Old age and treachery will overcome youth and skill.


Reply With Quote