5 releases
0.1.4 | Sep 20, 2020 |
---|---|
0.1.3 | Sep 20, 2020 |
0.1.2 | Sep 20, 2020 |
0.1.1 | Sep 20, 2020 |
0.1.0 | Sep 20, 2020 |
#913 in Unix APIs
38KB
536 lines
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 toSTDIN
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).
Dependencies
~230KB