💥 Sixth project in the 42 Common Core
I am . . . f i n e ( ._. )
Pipex is a reproduction of how Unix handles pipes (|
) in the shell.
You will build a program that mimics the shell behavior for piping commands like:
< infile cmd1 | cmd2 > outfile
Implemented in C using:
pipe()
fork()
dup2()
execve()
make
./pipex infile cmd1 cmd2 outfile
This is equivalent to:
< infile cmd1 | cmd2 > outfile
Example:
./pipex input.txt "grep hello" "wc -l" output.txt
File | Purpose |
---|---|
pipex.c |
Main logic for parsing and executing |
utils.c |
String splitting, path resolving |
pipex.h |
Header with macros and prototypes |
Makefile |
Builds your program |
In Unix:
- Files = text, devices, sockets, etc.
- You use file descriptors (FDs) to access them
A pipe sends the stdout of one command to the stdin of another.
Example:
echo "Hello" | wc -c # Outputs: 6
int fd[2];
pipe(fd);
if (fork() == 0)
{
close(fd[0]); // Close read end
dup2(fd[1], STDOUT_FILENO); // Redirect stdout
execve(cmd1_path, cmd1_args, envp);
}
else
{
close(fd[1]); // Close write end
dup2(fd[0], STDIN_FILENO); // Redirect stdin
execve(cmd2_path, cmd2_args, envp);
}
Every program is a process with:
- A PID
- A Parent
- Possibly Children
Creating a new process:
pid_t pid = fork();
pid == 0
→ childpid > 0
→ parent
Creates a pipe: fd[0]
for reading, fd[1]
for writing.
Creates a new process.
Redirects file descriptors.
dup2(fd[1], STDOUT_FILENO); // Redirect stdout to write end
Runs a command.
char *cmd[] = {"/bin/ls", NULL};
execve(cmd[0], cmd, envp);
./pipex infile "cat" "wc -l" outfile
diff <(./pipex in "grep hello" "wc -l" out) <( < in grep hello | wc -l > out )
- Support more than 2 commands (multi-pipe)
- Handle quotes and escaped characters
- Implement your own
split()
andget_path()
Pipex teaches core Unix concepts like:
- File descriptors
- Process control
- Inter-process communication
- Executing binaries
Plus, you'll get better at debugging with:
strace ./pipex ...
valgrind ./pipex ...
Use these to see what’s happening behind the scenes:
valgrind ./pipex input "ls -l" "wc -l" output
strace ./pipex input "ls" "wc" output
make fclean
$ cat infile
hello
hi there
$ ./pipex infile "grep h" "wc -l" outfile
$ cat outfile
2
This project is where you:
- Really understand how a shell works
- Learn the cost of forking badly
- Fall into
execve
segfault despair
But then... you emerge stronger 💪
Made with 🍝, 🧠, and a little bit of crying by your local wizard.
```