Lab 8: Pipes
One of the core types of IPC on Unix system is pipes. You will be implementing pipe redirection in this lab, and of course there’s that awesome video of the ATT folks explaining it.
Your mission is to produce a super-amazing ‘l33tsp34k’ generator: given a file name, you will convert its text to lowercase and then perform character substitutions to 1337-ify it. While you are already an elite haxxor and could easily write this program in C, you realize that with the power of Unix you can be even lazier and just combine existing utilities.
To explain the purpose of this program better, let’s say you have an input file (input.txt):
Mechanic: Somebody set up us the bomb.
Operator: Main screen turn on.
CATS: All your base are belong to us.
CATS: You have no chance to survive make your time.
You will run:
./leetify input.txt
And out comes:
m3ch4n!c: 50m3b0dy 53t up u5 t3h b0mb.
0p3r4t0r: m4!n 5cr33n turn 0n.
c4t5: 411 y0ur b453 4r3 b310ng t0 u5.
c4t5: y0u h4v3 n0 ch4nc3 t0 5urv!v3 m4k3 y0ur t!m3.
If you run:
./leetify input.txt output.txt
The contents printed above will be written to a file named output.txt instead.
Truly groundbreaking.
We will use three Unix utilities to achieve this:
cat
– read the original input filetr
– convert the text to lowercasesed
– find and replace characters
Check the man pages for all three utilities. NOTE: you won’t write any code that actually does text manipulation. All text manipulation will be provided by outside utilities. You are only gluing these programs together using pipes!
One interesting thing about tr
is that it only reads files from standard input – you can’t pass in the name of a text file like you can with some Unix utilities. To solve this, we are going to use cat
to read the file… but this is actually considered a useless use of cat because most shells already support redirection of stdin
from a file like so:
tr '[:upper:]' '[:lower:]' < ./input.txt
This makes the standard input stream of tr
come from the file input.txt
. Nevertheless, we will use cat
to do this instead just for practice. The equivalent command that we will implement is:
cat ./input.txt | tr '[:upper:]' '[:lower:]'
The output of cat
will go into a pipe that we create, which is then read by tr
, output to a second pipe, read by sed
, and finally printed to its output stream (either stdout or an output file):
cat -> pipe -> tr -> pipe -> sed -> (output file descriptor)
To get started, you should refer to the pipe.c example – it shows you how to use pipe()
and dup2()
. The io-redir.c and execlp examples may help too; however, you should use execvp
to execute the commands since we are operating with an array. The command line equivalent of this program is:
tr '[:upper:]' '[:lower:]' < ./input.txt \
| sed 's|the|teh|g; s|a|4|g; s|e|3|g; s|i|!|g; s|l|1|g; s|o|0|g; s|s|5|g;' \
> output.txt
So the programs and command line arguments you will execute with execvp
are:
cat 'filename.txt'
tr '[:upper:]' '[:lower:]'
sed 's|the|teh|g; s|a|4|g; s|e|3|g; s|i|!|g; s|l|1|g; s|o|0|g; s|s|5|g;'
Here’s some starter code to get you going. Be sure to follow the implementation steps outlined in the file.
Grading and Submission
Once you are finished with the lab, check your code into a directory called lab8
in your lab repository.
To receive 90% credit:
- Implement the pipeline logic with output printed to
stdout
.
To receive 100% credit:
- Complete all previous requirements
- Implement output redirection to write the output to the optional 3rd argument supplied to the program.