aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2019-10-28 13:28:06 -0400
committerJesse Luehrs <doy@tozt.net>2019-10-28 13:28:06 -0400
commit1a2bc078ef06b3a28d5c8ca5f2f495d63c3afbd8 (patch)
treeedaaa8ac2f545f3694b386f2baefc8312f0dfb52
parent607e9a1f1cbaa3f08d2d4c109821c6e987fa5a7e (diff)
downloadnbsh-old-1a2bc078ef06b3a28d5c8ca5f2f495d63c3afbd8.tar.gz
nbsh-old-1a2bc078ef06b3a28d5c8ca5f2f495d63c3afbd8.zip
move to tokio-pty-process-stream
-rw-r--r--Cargo.lock135
-rw-r--r--Cargo.toml2
-rw-r--r--src/async_stdin.rs88
-rw-r--r--src/builtins.rs22
-rw-r--r--src/eval.rs32
-rw-r--r--src/lib.rs2
-rw-r--r--src/process.rs256
-rw-r--r--src/repl.rs15
-rw-r--r--src/tui.rs20
9 files changed, 242 insertions, 330 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 67825a7..d7daa8a 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -77,6 +77,14 @@ dependencies = [
]
[[package]]
+name = "component-future"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "crossbeam-deque"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -200,6 +208,11 @@ dependencies = [
]
[[package]]
+name = "doc-comment"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
name = "fnv"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -225,7 +238,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "futures"
-version = "0.1.27"
+version = "0.1.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -233,7 +246,7 @@ name = "futures01"
version = "0.1.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -329,12 +342,12 @@ name = "nbsh"
version = "0.1.0"
dependencies = [
"crossterm 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)",
"nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)",
"snafu 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "tokio 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
- "tokio-pty-process 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-pty-process-stream 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -591,6 +604,17 @@ dependencies = [
]
[[package]]
+name = "snafu"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "backtrace 0.3.30 (registry+https://github.com/rust-lang/crates.io-index)",
+ "doc-comment 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures01 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
+ "snafu-derive 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "snafu-derive"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -601,6 +625,16 @@ dependencies = [
]
[[package]]
+name = "snafu-derive"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.15.35 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "stable_deref_trait"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -616,12 +650,22 @@ dependencies = [
]
[[package]]
+name = "term_size"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "tokio"
-version = "0.1.21"
+version = "0.1.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
- "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -634,7 +678,6 @@ dependencies = [
"tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-threadpool 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "tokio-trace-core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-udp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -645,7 +688,7 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
- "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -654,7 +697,7 @@ name = "tokio-current-thread"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -664,7 +707,7 @@ version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -672,7 +715,7 @@ name = "tokio-fs"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-threadpool 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -683,7 +726,7 @@ version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
- "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -693,21 +736,35 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
- "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)",
- "tokio 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-signal 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
+name = "tokio-pty-process-stream"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "component-future 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "snafu 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-pty-process 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-terminal-resize 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "tokio-reactor"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -724,7 +781,7 @@ name = "tokio-signal"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)",
"mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -741,7 +798,7 @@ version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -750,7 +807,7 @@ version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
- "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -758,6 +815,18 @@ dependencies = [
]
[[package]]
+name = "tokio-terminal-resize"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
+ "snafu 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "term_size 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-signal 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "tokio-threadpool"
version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -765,7 +834,7 @@ dependencies = [
"crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -779,26 +848,18 @@ version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
-name = "tokio-trace-core"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
name = "tokio-udp"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
- "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -812,7 +873,7 @@ version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
- "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -883,6 +944,7 @@ dependencies = [
"checksum cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)" = "39f75544d7bbaf57560d2168f28fd649ff9c76153874db88bdbdfd839b1a7e7d"
"checksum cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b486ce3ccf7ffd79fdeb678eac06a9e6c09fc88d33836340becb8fffe87c5e33"
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
+"checksum component-future 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "043c4e1cef116e0ac3a60ef19f19f7448e5166543d1426af8e66ab68f9442d62"
"checksum crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b18cd2e169ad86297e6bc0ad9aa679aee9daa4f19e8163860faf7c164e4f5a71"
"checksum crossbeam-epoch 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "04c9e3102cc2d69cd681412141b390abd55a362afc1540965dad0ad4d34280b4"
"checksum crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b"
@@ -895,11 +957,12 @@ dependencies = [
"checksum crossterm_terminal 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "18792c97c5cdcc5fd3582df58188a793bf290af4a53d5fc8442c7d17e003b356"
"checksum crossterm_utils 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8321d40908d0ee77cb29335f591eae2b4f7225152f81b9dfa35a161ca3b077dc"
"checksum crossterm_winapi 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c061e4a1c47a53952ba0f2396c00a61cd7ab74482eba99b9c9cc77fdca71932"
+"checksum doc-comment 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "923dea538cea0aa3025e8685b20d6ee21ef99c4f77e954a30febbaac5ec73a97"
"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
-"checksum futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)" = "a2037ec1c6c1c4f79557762eab1f7eae1f64f6cb418ace90fae88f0942b60139"
+"checksum futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)" = "1b980f2816d6ee8673b6517b52cb0e808a180efc92e5c19d02cdda79066703ef"
"checksum futures01 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)" = "289b17fb9d2d82f689a3ef11b11d402da2c583c30bb142d529bd06f0ecff1a4e"
"checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
@@ -941,23 +1004,27 @@ dependencies = [
"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
"checksum smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c4488ae950c49d403731982257768f48fada354a5203fe81f9bb6f43ca9002be"
"checksum snafu 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5712353226e5ccb06c8f9b1cab819654b25514479523755ffa94703ceeb00e4f"
+"checksum snafu 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d0bf93d08d6a44363b47d737f1f5bebbf5e6a1eaaa3d4c128ceeaca6b718292"
"checksum snafu-derive 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "78178fb0042da2d70bba6e3fb26b6412c4824a22b7fe434f5e082d2ca0b894ee"
+"checksum snafu-derive 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "624e94bd38e471f67883b467711e7a7ad7dbe284f5fb7e661dc8a671fc5b26a0"
"checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8"
"checksum syn 0.15.35 (registry+https://github.com/rust-lang/crates.io-index)" = "641e117d55514d6d918490e47102f7e08d096fdde360247e4a10f7a91a8478d3"
-"checksum tokio 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)" = "ec2ffcf4bcfc641413fa0f1427bf8f91dfc78f56a6559cbf50e04837ae442a87"
+"checksum term_size 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9e5b9a66db815dcfd2da92db471106457082577c3c278d4138ab3e3b4e189327"
+"checksum tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)" = "5a09c0b5bb588872ab2f09afa13ee6e9dac11e10a0ec9e8e3ba39a5a5d530af6"
"checksum tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5c501eceaf96f0e1793cf26beb63da3d11c738c4a943fdf3746d81d64684c39f"
"checksum tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "d16217cad7f1b840c5a97dfb3c43b0c871fef423a6e8d2118c604e843662a443"
"checksum tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "83ea44c6c0773cc034771693711c35c677b4b5a4b21b9e7071704c54de7d555e"
"checksum tokio-fs 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "3fe6dc22b08d6993916647d108a1a7d15b9cd29c4f4496c62b92c45b5041b7af"
"checksum tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "5090db468dad16e1a7a54c8c67280c5e4b544f3d3e018f0b913b400261f85926"
"checksum tokio-pty-process 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b9e3193b62e8c2277534e195d8f8ec4cb43d28a92f89494dd755686026795175"
+"checksum tokio-pty-process-stream 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "87c73e73b3907c8a3142162c28ca75a4a941f1f737f3bd31e3faeb6608f2d9f8"
"checksum tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "6af16bfac7e112bea8b0442542161bfc41cbfa4466b580bdda7d18cb88b911ce"
"checksum tokio-signal 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "dd6dc5276ea05ce379a16de90083ec80836440d5ef8a6a39545a3207373b8296"
"checksum tokio-sync 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2162248ff317e2bc713b261f242b69dbb838b85248ed20bb21df56d60ea4cae7"
"checksum tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1d14b10654be682ac43efee27401d792507e30fd8d26389e1da3b185de2e4119"
+"checksum tokio-terminal-resize 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "901915a5bf94a2ae7189de1af32da3161a80efc4609dd36ec8eba570e5c04ec4"
"checksum tokio-threadpool 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "72558af20be886ea124595ea0f806dd5703b8958e4705429dd58b3d8231f72f2"
"checksum tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "f2106812d500ed25a4f38235b9cae8f78a09edf43203e16e59c3b769a342a60e"
-"checksum tokio-trace-core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a9c8a256d6956f7cb5e2bdfe8b1e8022f1a09206c6c2b1ba00f3b746b260c613"
"checksum tokio-udp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "66268575b80f4a4a710ef83d087fdfeeabdce9b74c797535fbac18a2cb906e92"
"checksum tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "037ffc3ba0e12a0ab4aca92e5234e0dedeb48fddf6ccd260f1f150a36a9f2445"
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
diff --git a/Cargo.toml b/Cargo.toml
index a7a6deb..185103f 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -17,4 +17,4 @@ mio = "0.6"
nix = "0.14"
snafu = { version = "0.4", features = ["futures-01"] }
tokio = "0.1"
-tokio-pty-process = "0.4"
+tokio-pty-process-stream = "0.2"
diff --git a/src/async_stdin.rs b/src/async_stdin.rs
new file mode 100644
index 0000000..e3b0ead
--- /dev/null
+++ b/src/async_stdin.rs
@@ -0,0 +1,88 @@
+struct EventedStdin;
+
+const STDIN: i32 = 0;
+
+impl std::io::Read for EventedStdin {
+ fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
+ let stdin = std::io::stdin();
+ let mut stdin = stdin.lock();
+ stdin.read(buf)
+ }
+}
+
+impl mio::Evented for EventedStdin {
+ fn register(
+ &self,
+ poll: &mio::Poll,
+ token: mio::Token,
+ interest: mio::Ready,
+ opts: mio::PollOpt,
+ ) -> std::io::Result<()> {
+ let fd = STDIN as std::os::unix::io::RawFd;
+ let eventedfd = mio::unix::EventedFd(&fd);
+ eventedfd.register(poll, token, interest, opts)
+ }
+
+ fn reregister(
+ &self,
+ poll: &mio::Poll,
+ token: mio::Token,
+ interest: mio::Ready,
+ opts: mio::PollOpt,
+ ) -> std::io::Result<()> {
+ let fd = STDIN as std::os::unix::io::RawFd;
+ let eventedfd = mio::unix::EventedFd(&fd);
+ eventedfd.reregister(poll, token, interest, opts)
+ }
+
+ fn deregister(&self, poll: &mio::Poll) -> std::io::Result<()> {
+ let fd = STDIN as std::os::unix::io::RawFd;
+ let eventedfd = mio::unix::EventedFd(&fd);
+ eventedfd.deregister(poll)
+ }
+}
+
+pub struct Stdin {
+ input: tokio::reactor::PollEvented2<EventedStdin>,
+}
+
+impl Stdin {
+ pub fn new() -> Self {
+ Self {
+ input: tokio::reactor::PollEvented2::new(EventedStdin),
+ }
+ }
+}
+
+impl std::io::Read for Stdin {
+ fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
+ self.input.read(buf)
+ }
+}
+
+impl tokio::io::AsyncRead for Stdin {
+ fn poll_read(
+ &mut self,
+ buf: &mut [u8],
+ ) -> std::result::Result<futures::Async<usize>, tokio::io::Error> {
+ // XXX this is why i had to do the EventedFd thing - poll_read on its
+ // own will block reading from stdin, so i need a way to explicitly
+ // check readiness before doing the read
+ let ready = mio::Ready::readable();
+ match self.input.poll_read_ready(ready)? {
+ futures::Async::Ready(_) => {
+ let res = self.input.poll_read(buf);
+
+ // XXX i'm pretty sure this is wrong (if the single poll_read
+ // call didn't return all waiting data, clearing read ready
+ // state means that we won't get the rest until some more data
+ // beyond that appears), but i don't know that there's a way
+ // to do it correctly given that poll_read blocks
+ self.input.clear_read_ready(ready)?;
+
+ res
+ }
+ futures::Async::NotReady => Ok(futures::Async::NotReady),
+ }
+ }
+}
diff --git a/src/builtins.rs b/src/builtins.rs
index d1f5b61..eb7989d 100644
--- a/src/builtins.rs
+++ b/src/builtins.rs
@@ -60,17 +60,17 @@ impl Builtin {
#[must_use = "streams do nothing unless polled"]
impl futures::stream::Stream for Builtin {
- type Item = crate::eval::CommandEvent;
+ type Item = tokio_pty_process_stream::Event;
type Error = Error;
fn poll(&mut self) -> futures::Poll<Option<Self::Item>, Self::Error> {
if !self.started {
self.started = true;
Ok(futures::Async::Ready(Some(
- crate::eval::CommandEvent::CommandStart(
- self.cmd.clone(),
- self.args.clone(),
- ),
+ tokio_pty_process_stream::Event::CommandStart {
+ cmd: self.cmd.clone(),
+ args: self.args.clone(),
+ },
)))
} else if !self.done {
self.done = true;
@@ -82,17 +82,17 @@ impl futures::stream::Stream for Builtin {
};
res.map(|_| {
futures::Async::Ready(Some(
- crate::eval::CommandEvent::CommandExit(
- std::process::ExitStatus::from_raw(0),
- ),
+ tokio_pty_process_stream::Event::CommandExit {
+ status: std::process::ExitStatus::from_raw(0),
+ },
))
})
.or_else(|e| match e {
Error::UnknownBuiltin { .. } => Err(e),
_ => Ok(futures::Async::Ready(Some(
- crate::eval::CommandEvent::CommandExit(
- std::process::ExitStatus::from_raw(256),
- ),
+ tokio_pty_process_stream::Event::CommandExit {
+ status: std::process::ExitStatus::from_raw(256),
+ },
))),
})
} else {
diff --git a/src/eval.rs b/src/eval.rs
index a7e09c4..e29d10f 100644
--- a/src/eval.rs
+++ b/src/eval.rs
@@ -12,7 +12,7 @@ pub enum Error {
#[snafu(display("failed to find command `{}`: {}", cmd, source))]
Command {
cmd: String,
- source: crate::process::Error,
+ source: tokio_pty_process_stream::Error,
},
#[snafu(display("failed to run builtin command `{}`: {}", cmd, source))]
@@ -24,7 +24,7 @@ pub enum Error {
#[snafu(display("failed to run executable `{}`: {}", cmd, source))]
ProcessExecution {
cmd: String,
- source: crate::process::Error,
+ source: tokio_pty_process_stream::Error,
},
}
@@ -35,18 +35,14 @@ pub fn eval(line: &str) -> Eval {
Eval::new(line)
}
-pub enum CommandEvent {
- CommandStart(String, Vec<String>),
- Output(Vec<u8>),
- CommandExit(std::process::ExitStatus),
-}
-
pub struct Eval {
line: String,
stream: Option<
Box<
- dyn futures::stream::Stream<Item = CommandEvent, Error = Error>
- + Send,
+ dyn futures::stream::Stream<
+ Item = tokio_pty_process_stream::Event,
+ Error = Error,
+ > + Send,
>,
>,
manage_screen: bool,
@@ -69,7 +65,7 @@ impl Eval {
#[must_use = "streams do nothing unless polled"]
impl futures::stream::Stream for Eval {
- type Item = CommandEvent;
+ type Item = tokio_pty_process_stream::Event;
type Error = Error;
fn poll(&mut self) -> futures::Poll<Option<Self::Item>, Self::Error> {
@@ -80,17 +76,19 @@ impl futures::stream::Stream for Eval {
let builtin_stream = crate::builtins::Builtin::new(&cmd, &args);
let stream: Box<
dyn futures::stream::Stream<
- Item = CommandEvent,
+ Item = tokio_pty_process_stream::Event,
Error = Error,
> + Send,
> = if let Ok(s) = builtin_stream {
Box::new(s.context(BuiltinExecution { cmd }))
} else {
- let process_stream =
- crate::process::Process::new(&cmd, &args)
- .context(Command { cmd: cmd.clone() })?
- .set_raw(self.manage_screen);
- Box::new(process_stream.context(ProcessExecution { cmd }))
+ let input = crate::async_stdin::Stdin::new();
+ let process = tokio_pty_process_stream::ResizingProcess::new(
+ tokio_pty_process_stream::Process::new(
+ &cmd, &args, input,
+ ),
+ );
+ Box::new(process.context(ProcessExecution { cmd }))
};
self.stream = Some(stream);
}
diff --git a/src/lib.rs b/src/lib.rs
index e79c17a..1d51a3c 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -13,11 +13,11 @@
#![allow(clippy::single_match)]
#![allow(clippy::write_with_newline)]
+mod async_stdin;
mod builtins;
mod eval;
mod key_reader;
mod parser;
-mod process;
mod readline;
pub mod repl;
diff --git a/src/process.rs b/src/process.rs
deleted file mode 100644
index 9993be7..0000000
--- a/src/process.rs
+++ /dev/null
@@ -1,256 +0,0 @@
-use futures::future::Future as _;
-use snafu::ResultExt as _;
-use std::io::{Read as _, Write as _};
-use tokio::io::AsyncRead as _;
-use tokio_pty_process::CommandExt as _;
-
-#[derive(Debug, snafu::Snafu)]
-pub enum Error {
- #[snafu(display("failed to open a pty: {}", source))]
- OpenPty { source: std::io::Error },
-
- #[snafu(display("failed to spawn process for `{}`: {}", cmd, source))]
- SpawnProcess { cmd: String, source: std::io::Error },
-
- #[snafu(display("failed to resize pty: {}", source))]
- ResizePty { source: std::io::Error },
-
- #[snafu(display("failed to write to pty: {}", source))]
- WriteToPty { source: std::io::Error },
-
- #[snafu(display("failed to read from terminal: {}", source))]
- ReadFromTerminal { source: std::io::Error },
-
- #[snafu(display(
- "failed to clear ready state on pty for reading: {}",
- source
- ))]
- PtyClearReadReady { source: std::io::Error },
-
- #[snafu(display("failed to poll for process exit: {}", source))]
- ProcessExitPoll { source: std::io::Error },
-
- #[snafu(display(
- "failed to put the terminal into raw mode: {}",
- source
- ))]
- IntoRawMode { source: std::io::Error },
-}
-
-pub type Result<T> = std::result::Result<T, Error>;
-
-pub struct Process {
- pty: tokio_pty_process::AsyncPtyMaster,
- process: tokio_pty_process::Child,
- // TODO: tokio::io::Stdin is broken
- // input: tokio::io::Stdin,
- input: tokio::reactor::PollEvented2<EventedStdin>,
- cmd: String,
- args: Vec<String>,
- buf: Vec<u8>,
- started: bool,
- output_done: bool,
- exit_done: bool,
- manage_screen: bool,
- raw_screen: Option<crossterm::RawScreen>,
-}
-
-struct Resizer<'a, T> {
- rows: u16,
- cols: u16,
- pty: &'a T,
-}
-
-impl<'a, T: tokio_pty_process::PtyMaster> futures::future::Future
- for Resizer<'a, T>
-{
- type Item = ();
- type Error = std::io::Error;
-
- fn poll(&mut self) -> futures::Poll<Self::Item, Self::Error> {
- self.pty.resize(self.rows, self.cols)
- }
-}
-
-impl Process {
- pub fn new(cmd: &str, args: &[String]) -> Result<Self> {
- let pty =
- tokio_pty_process::AsyncPtyMaster::open().context(OpenPty)?;
-
- let process = std::process::Command::new(cmd)
- .args(args)
- .spawn_pty_async(&pty)
- .context(SpawnProcess { cmd })?;
-
- let (cols, rows) = crossterm::terminal().terminal_size();
- Resizer {
- rows: rows + 1,
- cols: cols + 1,
- pty: &pty,
- }
- .wait()
- .context(ResizePty)?;
-
- // TODO: tokio::io::stdin is broken (it's blocking)
- // let input = tokio::io::stdin();
- let input = tokio::reactor::PollEvented2::new(EventedStdin);
-
- Ok(Self {
- pty,
- process,
- input,
- cmd: cmd.to_string(),
- args: args.to_vec(),
- buf: Vec::with_capacity(4096),
- started: false,
- output_done: false,
- exit_done: false,
- manage_screen: true,
- raw_screen: None,
- })
- }
-
- #[allow(dead_code)]
- pub fn set_raw(mut self, raw: bool) -> Self {
- self.manage_screen = raw;
- self
- }
-}
-
-#[must_use = "streams do nothing unless polled"]
-impl futures::stream::Stream for Process {
- type Item = crate::eval::CommandEvent;
- type Error = Error;
-
- fn poll(&mut self) -> futures::Poll<Option<Self::Item>, Self::Error> {
- if self.manage_screen && self.raw_screen.is_none() {
- self.raw_screen = Some(
- crossterm::RawScreen::into_raw_mode().context(IntoRawMode)?,
- );
- }
-
- if !self.started {
- self.started = true;
- return Ok(futures::Async::Ready(Some(
- crate::eval::CommandEvent::CommandStart(
- self.cmd.clone(),
- self.args.clone(),
- ),
- )));
- }
-
- let ready = mio::Ready::readable();
- let input_poll = self.input.poll_read_ready(ready);
- match input_poll {
- Ok(futures::Async::Ready(_)) => {
- let stdin = std::io::stdin();
- let mut stdin = stdin.lock();
- let mut buf = vec![0; 4096];
- // TODO: async
- let n = stdin.read(&mut buf).context(ReadFromTerminal)?;
- if n > 0 {
- let bytes = buf[..n].to_vec();
-
- // TODO: async
- self.pty.write_all(&bytes).context(WriteToPty)?;
- }
- }
- _ => {}
- }
- // TODO: this could lose pending bytes if there is stuff to read in
- // the buffer but we don't read it all in the previous read call,
- // since i think we won't get another notification until new bytes
- // actually arrive even if there are bytes in the buffer
- self.input
- .clear_read_ready(ready)
- .context(PtyClearReadReady)?;
-
- if !self.output_done {
- self.buf.clear();
- let output_poll = self.pty.read_buf(&mut self.buf);
- match output_poll {
- Ok(futures::Async::Ready(n)) => {
- let bytes = self.buf[..n].to_vec();
- let bytes: Vec<_> = bytes
- .iter()
- // replace \n with \r\n
- .fold(vec![], |mut acc, &c| {
- if c == b'\n' {
- acc.push(b'\r');
- acc.push(b'\n');
- } else {
- acc.push(c);
- }
- acc
- });
- return Ok(futures::Async::Ready(Some(
- crate::eval::CommandEvent::Output(bytes),
- )));
- }
- Ok(futures::Async::NotReady) => {
- return Ok(futures::Async::NotReady);
- }
- Err(_) => {
- // explicitly ignoring errors (for now?) because we
- // always read off the end of the pty after the process
- // is done
- self.output_done = true;
- }
- }
- }
-
- if !self.exit_done {
- let exit_poll = self.process.poll().context(ProcessExitPoll);
- match exit_poll {
- Ok(futures::Async::Ready(status)) => {
- self.exit_done = true;
- return Ok(futures::Async::Ready(Some(
- crate::eval::CommandEvent::CommandExit(status),
- )));
- }
- Ok(futures::Async::NotReady) => {
- return Ok(futures::Async::NotReady);
- }
- Err(e) => {
- return Err(e);
- }
- }
- }
-
- Ok(futures::Async::Ready(None))
- }
-}
-
-struct EventedStdin;
-
-impl mio::Evented for EventedStdin {
- fn register(
- &self,
- poll: &mio::Poll,
- token: mio::Token,
- interest: mio::Ready,
- opts: mio::PollOpt,
- ) -> std::io::Result<()> {
- let fd = 0 as std::os::unix::io::RawFd;
- let eventedfd = mio::unix::EventedFd(&fd);
- eventedfd.register(poll, token, interest, opts)
- }
-
- fn reregister(
- &self,
- poll: &mio::Poll,
- token: mio::Token,
- interest: mio::Ready,
- opts: mio::PollOpt,
- ) -> std::io::Result<()> {
- let fd = 0 as std::os::unix::io::RawFd;
- let eventedfd = mio::unix::EventedFd(&fd);
- eventedfd.reregister(poll, token, interest, opts)
- }
-
- fn deregister(&self, poll: &mio::Poll) -> std::io::Result<()> {
- let fd = 0 as std::os::unix::io::RawFd;
- let eventedfd = mio::unix::EventedFd(&fd);
- eventedfd.deregister(poll)
- }
-}
diff --git a/src/repl.rs b/src/repl.rs
index 4188fbe..3ec7084 100644
--- a/src/repl.rs
+++ b/src/repl.rs
@@ -56,21 +56,24 @@ fn read() -> impl futures::future::Future<Item = String, Error = Error> {
fn eval(
line: &str,
-) -> impl futures::stream::Stream<Item = crate::eval::CommandEvent, Error = Error>
-{
+) -> impl futures::stream::Stream<
+ Item = tokio_pty_process_stream::Event,
+ Error = Error,
+> {
crate::eval::eval(line).context(Eval)
}
-fn print(event: &crate::eval::CommandEvent) -> Result<()> {
+fn print(event: &tokio_pty_process_stream::Event) -> Result<()> {
match event {
- crate::eval::CommandEvent::CommandStart(_, _) => {}
- crate::eval::CommandEvent::Output(out) => {
+ tokio_pty_process_stream::Event::CommandStart { .. } => {}
+ tokio_pty_process_stream::Event::Output { data: out } => {
let stdout = std::io::stdout();
let mut stdout = stdout.lock();
stdout.write(out).context(Print)?;
stdout.flush().context(Print)?;
}
- crate::eval::CommandEvent::CommandExit(_) => {}
+ tokio_pty_process_stream::Event::CommandExit { .. } => {}
+ tokio_pty_process_stream::Event::Resize { .. } => {}
}
Ok(())
}
diff --git a/src/tui.rs b/src/tui.rs
index 17b2eed..b74670f 100644
--- a/src/tui.rs
+++ b/src/tui.rs
@@ -66,18 +66,21 @@ impl Tui {
fn print(
&mut self,
idx: usize,
- event: crate::eval::CommandEvent,
+ event: tokio_pty_process_stream::Event,
) -> Result<()> {
match event {
- crate::eval::CommandEvent::CommandStart(cmd, args) => {
+ tokio_pty_process_stream::Event::CommandStart { cmd, args } => {
self.command_start(idx, &cmd, &args)
}
- crate::eval::CommandEvent::Output(out) => {
+ tokio_pty_process_stream::Event::Output { data: out } => {
self.command_output(idx, &out)
}
- crate::eval::CommandEvent::CommandExit(status) => {
+ tokio_pty_process_stream::Event::CommandExit { status } => {
self.command_exit(idx, status)
}
+ tokio_pty_process_stream::Event::Resize { size } => {
+ self.command_resize(idx, size)
+ }
}
}
@@ -126,6 +129,15 @@ impl Tui {
Ok(())
}
+ fn command_resize(
+ &mut self,
+ _idx: usize,
+ _size: (u16, u16),
+ ) -> Result<()> {
+ // TODO
+ Ok(())
+ }
+
fn poll_read(&mut self) {
if self.readline.is_none() && self.commands.is_empty() {
self.idx += 1;