From 1a2bc078ef06b3a28d5c8ca5f2f495d63c3afbd8 Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Mon, 28 Oct 2019 13:28:06 -0400 Subject: move to tokio-pty-process-stream --- Cargo.lock | 135 +++++++++++++++++++++------- Cargo.toml | 2 +- src/async_stdin.rs | 88 ++++++++++++++++++ src/builtins.rs | 22 ++--- src/eval.rs | 32 ++++--- src/lib.rs | 2 +- src/process.rs | 256 ----------------------------------------------------- src/repl.rs | 15 ++-- src/tui.rs | 20 ++++- 9 files changed, 242 insertions(+), 330 deletions(-) create mode 100644 src/async_stdin.rs delete mode 100644 src/process.rs diff --git a/Cargo.lock b/Cargo.lock index 67825a7..d7daa8a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -76,6 +76,14 @@ dependencies = [ "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[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" @@ -199,6 +207,11 @@ dependencies = [ "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[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" @@ -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]] @@ -590,6 +603,17 @@ dependencies = [ "snafu-derive 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[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" @@ -600,6 +624,16 @@ dependencies = [ "syn 0.15.35 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[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" @@ -615,13 +649,23 @@ dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[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,13 +807,25 @@ 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)", "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[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" @@ -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 { + 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, +} + +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 { + self.input.read(buf) + } +} + +impl tokio::io::AsyncRead for Stdin { + fn poll_read( + &mut self, + buf: &mut [u8], + ) -> std::result::Result, 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, 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), - Output(Vec), - CommandExit(std::process::ExitStatus), -} - pub struct Eval { line: String, stream: Option< Box< - dyn futures::stream::Stream - + 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, 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 = std::result::Result; - -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, - cmd: String, - args: Vec, - buf: Vec, - started: bool, - output_done: bool, - exit_done: bool, - manage_screen: bool, - raw_screen: Option, -} - -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.pty.resize(self.rows, self.cols) - } -} - -impl Process { - pub fn new(cmd: &str, args: &[String]) -> Result { - 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, 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 { fn eval( line: &str, -) -> impl futures::stream::Stream -{ +) -> 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; -- cgit v1.2.3-54-g00ecf