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:

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:

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:

To receive 100% credit: