I have to write a shell that can run pipes. For example commands like ls -l | wc -l
". I have successfully parsed the command given by the user as below:
"ls" = firstcmd
"-l" = frsarg
"wc" = scmd
"-l" = secarg
Now I have to use two forks since the commands are two and a pipe. The code block that I wrote to exec the command is the following:
pid_t pid;
int fd[2];
pipe(fd);
pid = fork();
if(pid==0)
{
dup2(fd[WRITE_END], STDOUT_FILENO);
close(fd[READ_END]);
execlp(firstcmd, firstcmd, frsarg, (char*) NULL);
}
else
{
pid=fork();
if(pid==0)
{
dup2(fd[READ_END], STDIN_FILENO);
close(fd[WRITE_END]);
execlp(scmd, scmd, secarg, (char*) NULL);
}
}
So when I run my shell and I enter the command ls -l | wc -l
(for example) the result from the execs doesn't show up but the shell keeps running normally.
The strange thing is that the result of the command shows only when I terminate my shell with "exit" or "^C".
What is wrong with that output? Why doesn't it show up right after I enter the command?
You need to close all the pipe descriptors in both the parent process and the child process (after duplication in the child process). In your code the main issue is that, the
wc
process does not exit because there are still writers present (since the parent process has not closed the write end). Changes shown below. I have also added thewaitpid
in the parent process to wait for thewc
process.Hmm, close enough. You miss to handle close on some file descriptor after fork.
Here is some reference:
Here's my code: