Advanced
UNIX Programming (CS510)
Final Project : A simulation of C
shell:
Final Project Requirement:
CS510B Project Part IV
In project part IV, you are required to
implement the pipe “|” support.
For simplicity, only 1 pipe is required.
This part of code should be added to the existing code
from project part I, II, and III.
Let us look at command “ls | grep fi”.
Two processes should execute this command.
A pipe connects these 2 processes.
One process executes “ls”, and writes the output to
the pipe; the other executes “grep fi”, and reads input
from the pipe. They
should have parent/child or sibling relationship.
The output of process “ls” is the input of process
“grep fi”.
Processes connected by pipes form a
process group. That
process group could be foreground or background.
So foreground/background (“&”) should be
handled before pipe (“|”).
By default, a UNIX program reads input from
STDIN_FILENO, and writes output to STDOUT_FILENO.
So the process writing output to the pipe should dup
pipe_fd[1] (write end of pipe) to STDOUT_FILENO; the process
reading input from the pipe should dup pipe_fd[0] (read end of
pipe) to STDIN_FILENO. Your
program should also check I/O redirect with pipe.
When a process writes to a pipe, it should not have
output redirect (“>”).
When a process reads from a pipe, it should not have
input redirect (“<”).
I prefer parent/child relationship to
execute “ls | grep fi”.
Then which process should be the parent?
This is a foreground command.
If we let “ls” executed by parent process, and
“grep fi” executed by the child process, “ls” finishes
before “grep fi”. The
shell process, which is the parent of “ls”, waits for “ls”.
The shell process returns from wait() and prints
the shell prompt before “grep fi” finishes.
Then the output will be like this:
Shell_prompt > ls | grep fi
Shell prompt >
File1 file2 file3
Instead of standard format of a UNIX
shell:
Shell_prompt > ls | grep fi
File1 file2 file3
Shell_prompt >
So process executing “grep fi” should
the parent and process executing “ls” should be the child
of it. And
process for “grep fi” should be child of the shell
process. So the
shell process waits for “grep fi” process.
When “grep fi” process finishes, it prints the
output. Then shell process prints the shell prompt.
Did you see the advantage using parent/child
relationship over sibling relationship?
If sibling processes are used to execute “ls” and
“grep fi”, there is no guarantee that shell process
returns from wait() after “grep fi” finishes.
The shell process may return from wait() and print the
shell prompt before “grep fi” prints the result.
Reference program:
Program 14.1, 14.2 and 14.5
System calls to use:
fork(), pipe(), dup2(), close()
Challenge:
How to implement multiple pipes? For example, “ls | grep fi | sort –r | tee file”.
Shell process forks process for “tee file”; process
for “tee file” forks process for “sort –r”; process
for “sort –r” forks process for “grep fi”; process
for “grep fi” forks process for “ls”.
Final
Project: mysh4 -- a simulation of C shell
LINKS:
Book:
Advanced Programming in the UNIX Environment
Links
|