unix_exec_piper 0.1.4

unix_exec_piper helps you to exec multiple commands where STDOUT of one process is connected to STDIN of the next process. This is what a shell (like bash) does internally.
Documentation
# unix_exec_piper: A library written in Rust that execs multiple commands and connects them with pipes.

## TL;DR;
My library basically does the functionality that happens when you type `cat file.txt | grep -i | wc -l` 
into a shell like bash. **unix_exec_piper** does no parsing, but only the actual execution and connection
between the (child) processes via **unix pipes**.

Important main parts of the library are `pipe.rs` and `lib.rs :: execute_piped_cmd_chain()`.

**The main purpose of this library is educational and to show people who are interested in this how it's done.**

You might build a shell around this library (if it gets more functionality in the future).

## Basics you need to know
Please make yourself familiar with the `UNIX/Posix` concepts:
- `pipe()`
- `fork()`
- `file descriptors` and *"Everything is a file"*
- `exec()`

## Supported features
- Creating pipes between processes where `STDOUT` of one process gets connected to 
`STDIN` of the next process. \
  (`$ cat file.txt | grep -i | wc -l`) 
- I/O redirection into files \
  `$ cat < file.txt | grep -i | wc -l > out.txt`

## not (yet) supported features
- I/O redirection with `STDERR`
- a lot of other redirection primitives listed here: https://tldp.org/LDP/abs/html/io-redirection.html

## example
See `src/bin/example.rs`.

## Basic idea
The parent process loops `n` times (for `n` commands) and creates `n-1` `Pipe`s. Therefore `n` child processes
are created through `fork()`. Each child process has two variables in its address space:

    let mut pipe_to_current: Option<Pipe>;
    let mut pipe_to_next: Option<Pipe>;

Pipes communicates across process boundaries in the following way:

    child process 0    child process 1    child process n
    _______________    _______________    _________
    | cat foo.txt |    | grep -i abc |    | wc -l |
    ---------------    ---------------    ---------
                ^        ^         ^        ^
          WRITE |--------|  R / W  |--------| READ
          END               E   E             END
                       (current child)
            -Pipe to Current-   -Pipe to Next-
            
Each process uses `pipe_to_current` (if present) as "read end" (as it's `stdin`) and
`pipe_to_current` (if present) as "write end" 
(duplicate it's `STDOUT` `file descriptor` into the write end of the pipe).