You also need to look up the pipe(2) system call as well, along with close() and dup().
A pipe gives you two connected file descriptors, one for reading (will become a stdin), and one for writing (will become a stdout).
Essentially, you do this
- create a pipe
- call fork() to create a separate child process
--- in the child process (which will become say 'wc'
---- close stdin
---- dup() one end of the pipe to being the new stdin for the child process
---- close other fd's that are of no interest.
---- exec the 'wc' command
- call fork() again in the parent to create another child
--- in this child process, we will run 'ls'
---- close stdout
---- dup() the other end of the pipe to being stdout
---- close other fd's that are of no interest.
---- exec the 'ls' command
- wait() for both child processes to exit
Try using
strace with a command line version so you can see most (if not all) of this happening.