unix_exec_piper

Crates.iounix_exec_piper
lib.rsunix_exec_piper
version0.1.4
sourcesrc
created_at2020-09-20 12:55:52.829034
updated_at2020-09-20 21:06:34.374171
descriptionunix_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.
homepagehttps://github.com/phip1611/unix_exec_piper
repositoryhttps://github.com/phip1611/unix_exec_piper
max_upload_size
id290778
size105,536
Philipp Schuster (phip1611)

documentation

https://docs.rs/unix_exec_piper/

README

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

example

See src/bin/example.rs.

Basic idea

The parent process loops n times (for n commands) and creates n-1 Pipes. 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).

Commit count: 15

cargo fmt