diff options
Diffstat (limited to 'winpty')
-rw-r--r-- | winpty/Cargo.lock | 577 | ||||
-rw-r--r-- | winpty/Cargo.toml | 16 | ||||
-rw-r--r-- | winpty/build.rs | 12 | ||||
-rw-r--r-- | winpty/src/lib.rs | 476 |
4 files changed, 1081 insertions, 0 deletions
diff --git a/winpty/Cargo.lock b/winpty/Cargo.lock new file mode 100644 index 00000000..4ef9a7de --- /dev/null +++ b/winpty/Cargo.lock @@ -0,0 +1,577 @@ +[[package]] +name = "aho-corasick" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ansi_term" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "arrayvec" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "atty" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", + "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "bindgen" +version = "0.33.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cexpr 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "clang-sys 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "which 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "bitflags" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cc" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "cexpr" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "nom 3.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "cfg-if" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "clang-sys" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", + "libloading 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "clap" +version = "2.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "crossbeam-deque" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "crossbeam-utils" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "either" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "env_logger" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "fuchsia-zircon" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "fuchsia-zircon-sys" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "glob" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "humantime" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "kernel32-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "lazy_static" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "libc" +version = "0.2.42" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "libloading" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cc 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "log" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "memchr" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "memchr" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "memoffset" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "named_pipe" +version = "0.3.0" +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)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "nodrop" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "nom" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num_cpus" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "peeking_take_while" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "quick-error" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "quote" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rand" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rayon" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon-core 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rayon-core" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "redox_syscall" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "redox_termios" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "aho-corasick 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", + "thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "aho-corasick 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex-syntax" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex-syntax" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "scopeguard" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "strsim" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "termcolor" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "wincolor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "termion" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "textwrap" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "thread_local" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ucd-util" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "unicode-width" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "unreachable" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "utf8-ranges" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "vec_map" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "which" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "widestring" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi-build" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "wincolor" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winpty" +version = "0.1.0" +dependencies = [ + "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "named_pipe 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "widestring 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "winpty-sys 1.1.0 (git+https://github.com/zacps/winpty?branch=rust)", +] + +[[package]] +name = "winpty-sys" +version = "1.1.0" +source = "git+https://github.com/zacps/winpty?branch=rust#be5fd7323b588b81294b1d0a670d2dbd5322ff00" +dependencies = [ + "bindgen 0.33.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[metadata] +"checksum aho-corasick 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f0ba20154ea1f47ce2793322f049c5646cc6d0fa9759d5f333f286e507bf8080" +"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +"checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef" +"checksum atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "2fc4a1aa4c24c0718a250f0681885c1af91419d242f29eb8f2ab28502d80dbd1" +"checksum bindgen 0.33.2 (registry+https://github.com/rust-lang/crates.io-index)" = "603ed8d8392ace9581e834e26bd09799bf1e989a79bd1aedbb893e72962bdc6e" +"checksum bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d0c54bb8f454c567f21197eefcdbf5679d0bd99f2ddbe52e84c77061952e6789" +"checksum cc 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)" = "49ec142f5768efb5b7622aebc3fdbdbb8950a4b9ba996393cb76ef7466e8747d" +"checksum cexpr 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "42aac45e9567d97474a834efdee3081b3c942b2205be932092f53354ce503d6c" +"checksum cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "efe5c877e17a9c717a0bf3613b2709f723202c4e4675cc8f12926ded29bcb17e" +"checksum clang-sys 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)" = "939a1a34310b120d26eba35c29475933128b0ec58e24b43327f8dbe6036fc538" +"checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e" +"checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3" +"checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150" +"checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9" +"checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0" +"checksum env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0e6e40ebb0e66918a37b38c7acab4e10d299e0463fe2af5d29b9cc86710cfd2a" +"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 glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" +"checksum humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0484fda3e7007f2a4a0d9c3a703ca38c71c54c55602ce4660c419fd32e188c9e" +"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +"checksum lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e6412c5e2ad9584b0b8e979393122026cdd6d2a80b933f890dcd694ddbe73739" +"checksum libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)" = "b685088df2b950fccadf07a7187c8ef846a959c142338a48f9dc0b94517eb5f1" +"checksum libloading 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3ad660d7cb8c5822cd83d10897b0f1f1526792737a179e73896152f85b88c2" +"checksum log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "61bd98ae7f7b754bc53dca7d44b604f733c6bba044ea6f41bc8d89272d8161d2" +"checksum memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "148fab2e51b4f1cfc66da2a7c32981d1d3c083a803978268bb11fe4b86925e7a" +"checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d" +"checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" +"checksum named_pipe 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ed10a5ac4f5f7e5d75552b12c1d5d542debca81e573279dd1e4c19fde6efa6d" +"checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2" +"checksum nom 3.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05aec50c70fd288702bcd93284a8444607f3292dbdf2a30de5ea5dcdbe72287b" +"checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30" +"checksum peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" +"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" +"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" +"checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5" +"checksum rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "80e811e76f1dbf68abf87a759083d34600017fc4e10b6bd5ad84a700f9dba4b1" +"checksum rayon-core 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d24ad214285a7729b174ed6d3bcfcb80177807f959d95fafd5bfc5c4f201ac8" +"checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1" +"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" +"checksum regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9329abc99e39129fcceabd24cf5d85b4671ef7c29c50e972bc5afe32438ec384" +"checksum regex 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "13c93d55961981ba9226a213b385216f83ab43bd6ac53ab16b2eeb47e337cf4e" +"checksum regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d707a4fa2637f2dca2ef9fd02225ec7661fe01a53623c1e6515b6916511f7a7" +"checksum regex-syntax 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05b06a75f5217880fc5e905952a42750bf44787e56a6c6d6852ed0992f5e1d54" +"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" +"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" +"checksum termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "adc4587ead41bf016f11af03e55a624c06568b5a19db4e90fde573d805074f83" +"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" +"checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6" +"checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963" +"checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d" +"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" +"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" +"checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" +"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" +"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" +"checksum which 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e84a603e7e0b1ce1aa1ee2b109c7be00155ce52df5081590d1ffb93f4f515cb2" +"checksum widestring 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7157704c2e12e3d2189c507b7482c52820a16dfa4465ba91add92f266667cadb" +"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" +"checksum winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "773ef9dcc5f24b7d850d0ff101e542ff24c3b090a9768e03ff889fdef41f00fd" +"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" +"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +"checksum wincolor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "eeb06499a3a4d44302791052df005d5232b927ed1a9658146d842165c4de7767" +"checksum winpty-sys 1.1.0 (git+https://github.com/zacps/winpty?branch=rust)" = "<none>" diff --git a/winpty/Cargo.toml b/winpty/Cargo.toml new file mode 100644 index 00000000..b19a8e6b --- /dev/null +++ b/winpty/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "winpty" +version = "0.1.0" +authors = ["Zac Pullar-Strecker <zacmps@gmail.com>"] +license = "MIT" +description = "Safe rust bindings for winpty" + +[dependencies] +# TODO: Replace with official repo +winpty-sys = { git = "https://github.com/zacps/winpty", branch = "rust" } +bitflags = "1.0" +widestring = "0.2.2" + +[dev-dependencies] +named_pipe = "0.3" +winapi = { version = "0.3", features = ["winnt", "processthreadsapi"] } diff --git a/winpty/build.rs b/winpty/build.rs new file mode 100644 index 00000000..90d81803 --- /dev/null +++ b/winpty/build.rs @@ -0,0 +1,12 @@ +use std::fs::copy; +use std::path::Path; + +fn main() { + // The working directory for `cargo test` is in the deps folder, not the debug/release root + if cfg!(test) && Path::new("target").exists() { + #[cfg(debug_assertions)] + copy("../assets/windows/x86_64/winpty-agent.exe", "target/debug/deps/winpty-agent.exe").unwrap(); + #[cfg(not(debug_assertions))] + copy("../assets/windows/x86_64/winpty-agent.exe", "target/release/deps/winpty-agent.exe").unwrap(); + } +} diff --git a/winpty/src/lib.rs b/winpty/src/lib.rs new file mode 100644 index 00000000..3effb939 --- /dev/null +++ b/winpty/src/lib.rs @@ -0,0 +1,476 @@ +#![cfg_attr(feature = "cargo-clippy", deny(clippy, if_not_else, enum_glob_use, wrong_pub_self_convention))] + +#[macro_use] +extern crate bitflags; +extern crate widestring; +extern crate winpty_sys; + +use std::error::Error; +use std::fmt; +use std::path::PathBuf; +use std::result::Result; +use std::os::windows::io::RawHandle; +use std::ptr::{null, null_mut}; +use fmt::{Display, Formatter}; + +use winpty_sys::*; + +use widestring::WideCString; + +pub enum ErrorCodes { + Success, + OutOfMemory, + SpawnCreateProcessFailed, + LostConnection, + AgentExeMissing, + Unspecified, + AgentDied, + AgentTimeout, + AgentCreationFailed, +} +pub enum MouseMode { + None, + Auto, + Force, +} +bitflags!( + pub struct SpawnFlags: u64 { + const AUTO_SHUTDOWN = 0x1; + const EXIT_AFTER_SHUTDOWN = 0x2; + } +); +bitflags!( + pub struct ConfigFlags: u64 { + const CONERR = 0x1; + const PLAIN_OUTPUT = 0x2; + const COLOR_ESCAPES = 0x4; + } +); + +#[derive(Debug)] +pub struct Err<'a> { + ptr: &'a mut winpty_error_t, + code: u32, + message: String, +} + +// Check to see whether winpty gave us an error +fn check_err<'a>(e: *mut winpty_error_t) -> Option<Err<'a>> { + let err = unsafe { + let raw = winpty_error_msg(e); + Err { + ptr: &mut *e, + code: winpty_error_code(e), + message: String::from_utf16_lossy(std::slice::from_raw_parts(raw, wcslen(raw))), + } + }; + if err.code == 0 { + None + } else { + Some(err) + } +} + +impl<'a> Drop for Err<'a> { + fn drop(&mut self) { + unsafe { + winpty_error_free(self.ptr); + } + } +} +impl<'a> Display for Err<'a> { + fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> { + write!(f, "Code: {}, Message: {}", self.code, self.message) + } +} +impl<'a> Error for Err<'a> { + fn description(&self) -> &str { + &self.message + } +} + +#[derive(Debug)] +/// Winpty agent config +pub struct Config<'a>(&'a mut winpty_config_t); + +impl<'a, 'b> Config<'a> { + pub fn new(flags: ConfigFlags) -> Result<Self, Err<'b>> { + let mut err = null_mut() as *mut winpty_error_t; + let config = unsafe { winpty_config_new(flags.bits(), &mut err) }; + + if let Some(err) = check_err(err) { + Result::Err(err) + } else { + unsafe { Ok(Config(&mut *config)) } + } + } + + /// Set the initial size of the console window + pub fn set_initial_size(&mut self, cols: i32, rows: i32) { + unsafe { + winpty_config_set_initial_size(self.0, cols, rows); + } + } + + /// Set the mouse mode + pub fn set_mouse_mode(&mut self, mode: &MouseMode) { + let m = match mode { + MouseMode::None => 0, + MouseMode::Auto => 1, + MouseMode::Force => 2, + }; + unsafe { + winpty_config_set_mouse_mode(self.0, m); + } + } + + /// Amount of time to wait for the agent to startup and to wait for any given + /// agent RPC request. Must be greater than 0. Can be INFINITE. + // Might be a better way to represent this while still retaining infinite capability? + // Enum? + pub fn set_agent_timeout(&mut self, timeout: u32) { + unsafe { + winpty_config_set_agent_timeout(self.0, timeout); + } + } +} + +impl<'a> Drop for Config<'a> { + fn drop(&mut self) { + unsafe { + winpty_config_free(self.0); + } + } +} + +#[derive(Debug)] +/// A struct representing the winpty agent process +pub struct Winpty<'a>(&'a mut winpty_t); + +impl<'a, 'b> Winpty<'a> { + /// Starts the agent. This process will connect to the agent + /// over a control pipe, and the agent will open data pipes + /// (e.g. CONIN and CONOUT). + pub fn open(cfg: &Config) -> Result<Self, Err<'b>> { + let mut err = null_mut() as *mut winpty_error_t; + unsafe { + let winpty = winpty_open(cfg.0, &mut err); + let err = check_err(err); + if let Some(err) = err { + Result::Err(err) + } else { + Ok(Winpty(&mut *winpty)) + } + } + } + + /// Returns the handle to the winpty agent process + pub fn raw_handle(&mut self) -> RawHandle { + unsafe { winpty_agent_process(self.0) } + } + + /// Returns the name of the input pipe. + /// Pipe is half-duplex. + pub fn conin_name(&mut self) -> PathBuf { + unsafe { + let raw = winpty_conin_name(self.0); + PathBuf::from(&String::from_utf16_lossy(std::slice::from_raw_parts( + raw, + wcslen(raw), + ))) + } + } + + /// Returns the name of the output pipe. + /// Pipe is half-duplex. + pub fn conout_name(&mut self) -> PathBuf { + unsafe { + let raw = winpty_conout_name(self.0); + PathBuf::from(&String::from_utf16_lossy(std::slice::from_raw_parts( + raw, + wcslen(raw), + ))) + } + } + + /// Returns the name of the error pipe. + /// The name will only be valid if ConfigFlags::CONERR was specified. + /// Pipe is half-duplex. + pub fn conerr_name(&mut self) -> PathBuf { + unsafe { + let raw = winpty_conerr_name(self.0); + PathBuf::from(&String::from_utf16_lossy(std::slice::from_raw_parts( + raw, + wcslen(raw), + ))) + } + } + + /// Change the size of the Windows console window. + /// + /// cols & rows MUST be greater than 0 + pub fn set_size(&mut self, cols: usize, rows: usize) -> Result<(), Err> { + assert!(cols > 0 && rows > 0); + let mut err = null_mut() as *mut winpty_error_t; + + unsafe { + winpty_set_size(self.0, cols as i32, rows as i32, &mut err); + } + + if let Some(err) = check_err(err) { + Result::Err(err) + } else { + Ok(()) + } + } + + /// Get the list of processses running in the winpty agent. Returns <= count processes + /// + /// `count` must be greater than 0. Larger values cause a larger allocation. + // TODO: This should return Vec<Handle> instead of Vec<i32> + pub fn console_process_list(&mut self, count: usize) -> Result<Vec<i32>, Err> { + assert!(count > 0); + + let mut err = null_mut() as *mut winpty_error_t; + let mut process_list = Vec::with_capacity(count); + + unsafe { + let len = winpty_get_console_process_list(self.0, process_list.as_mut_ptr(), count as i32, &mut err) as usize; + process_list.set_len(len); + } + + if let Some(err) = check_err(err) { + Result::Err(err) + } else { + Ok(process_list) + } + } + + /// Spawns the new process. + /// + /// spawn can only be called once per Winpty object. If it is called + /// before the output data pipe(s) is/are connected, then collected output is + /// buffered until the pipes are connected, rather than being discarded. + /// (https://blogs.msdn.microsoft.com/oldnewthing/20110107-00/?p=11803) + // TODO: Support getting the process and thread handle of the spawned process (Not the agent) + // TODO: Support returning the error from CreateProcess + pub fn spawn( + &mut self, + cfg: &SpawnConfig, + ) -> Result<(), Err> { + let mut err = null_mut() as *mut winpty_error_t; + + unsafe { + let ok = winpty_spawn( + self.0, + cfg.0 as *const winpty_spawn_config_s, + null_mut(), // Process handle + null_mut(), // Thread handle + null_mut(), // Create process error + &mut err, + ); + if ok == 0 { return Ok(());} + } + + if let Some(err) = check_err(err) { + Result::Err(err) + } else { + Ok(()) + } + } +} + +// winpty_t is thread-safe +unsafe impl<'a> Sync for Winpty<'a> {} +unsafe impl<'a> Send for Winpty<'a> {} + +impl<'a> Drop for Winpty<'a> { + fn drop(&mut self) { + unsafe { + winpty_free(self.0); + } + } +} + +#[derive(Debug)] +/// Information about a process for winpty to spawn +pub struct SpawnConfig<'a>(&'a mut winpty_spawn_config_t); + +impl<'a, 'b> SpawnConfig<'a> { + /// Creates a new spawnconfig + pub fn new( + spawnflags: SpawnFlags, + appname: Option<&str>, + cmdline: Option<&str>, + cwd: Option<&str>, + end: Option<&str>, + ) -> Result<Self, Err<'b>> { + let mut err = null_mut() as *mut winpty_error_t; + let (appname, cmdline, cwd, end) = ( + appname.map_or(null(), |s| WideCString::from_str(s).unwrap().into_raw()), + cmdline.map_or(null(), |s| WideCString::from_str(s).unwrap().into_raw()), + cwd.map_or(null(), |s| WideCString::from_str(s).unwrap().into_raw()), + end.map_or(null(), |s| WideCString::from_str(s).unwrap().into_raw()), + ); + + let spawn_config = unsafe { + winpty_spawn_config_new(spawnflags.bits(), appname, cmdline, cwd, end, &mut err) + }; + + // Required to free the strings + unsafe { + if !appname.is_null() { + WideCString::from_raw(appname as *mut u16); + } + if !cmdline.is_null() { + WideCString::from_raw(cmdline as *mut u16); + } + if !cwd.is_null() { + WideCString::from_raw(cwd as *mut u16); + } + if !end.is_null() { + WideCString::from_raw(end as *mut u16); + } + } + + if let Some(err) = check_err(err) { + Result::Err(err) + } else { + unsafe { Ok(SpawnConfig(&mut *spawn_config)) } + } + } +} +impl<'a> Drop for SpawnConfig<'a> { + fn drop(&mut self) { + unsafe { + winpty_spawn_config_free(self.0); + } + } +} + +#[cfg(test)] +mod tests { + extern crate named_pipe; + extern crate winapi; + + use self::named_pipe::PipeClient; + use self::winapi::um::processthreadsapi::OpenProcess; + use self::winapi::um::winnt::READ_CONTROL; + + use std::ptr::null_mut; + + use {Config, ConfigFlags, SpawnConfig, SpawnFlags, Winpty}; + + #[test] + // Test that we can start a process in winpty + fn spawn_process() { + let mut winpty = Winpty::open( + &Config::new(ConfigFlags::empty()).expect("failed to create config") + ).expect("failed to create winpty instance"); + + winpty.spawn( + &SpawnConfig::new( + SpawnFlags::empty(), + None, + Some("cmd"), + None, + None + ).expect("failed to create spawn config") + ).unwrap(); + } + + #[test] + // Test that pipes connected before winpty is spawned can be connected to + fn valid_pipe_connect_before() { + let mut winpty = Winpty::open( + &Config::new(ConfigFlags::empty()).expect("failed to create config") + ).expect("failed to create winpty instance"); + + // Check we can connect to both pipes + PipeClient::connect_ms(winpty.conout_name(), 1000).expect("failed to connect to conout pipe"); + PipeClient::connect_ms(winpty.conin_name(), 1000).expect("failed to connect to conin pipe"); + + winpty.spawn( + &SpawnConfig::new( + SpawnFlags::empty(), + None, + Some("cmd"), + None, + None + ).expect("failed to create spawn config") + ).unwrap(); + } + + #[test] + // Test that pipes connected after winpty is spawned can be connected to + fn valid_pipe_connect_after() { + let mut winpty = Winpty::open( + &Config::new(ConfigFlags::empty()).expect("failed to create config") + ).expect("failed to create winpty instance"); + + winpty.spawn( + &SpawnConfig::new( + SpawnFlags::empty(), + None, + Some("cmd"), + None, + None + ).expect("failed to create spawn config") + ).unwrap(); + + // Check we can connect to both pipes + PipeClient::connect_ms(winpty.conout_name(), 1000).expect("failed to connect to conout pipe"); + PipeClient::connect_ms(winpty.conin_name(), 1000).expect("failed to connect to conin pipe"); + } + + #[test] + fn resize() { + let mut winpty = Winpty::open( + &Config::new(ConfigFlags::empty()).expect("failed to create config") + ).expect("failed to create winpty instance"); + + winpty.spawn( + &SpawnConfig::new( + SpawnFlags::empty(), + None, + Some("cmd"), + None, + None + ).expect("failed to create spawn config") + ).unwrap(); + + winpty.set_size(1, 1).unwrap(); + } + + #[test] + // Test that each id returned by cosole_process_list points to an actual process + fn console_process_list_valid() { + let mut winpty = Winpty::open( + &Config::new(ConfigFlags::empty()).expect("failed to create config") + ).expect("failed to create winpty instance"); + + winpty.spawn( + &SpawnConfig::new( + SpawnFlags::empty(), + None, + Some("cmd"), + None, + None + ).expect("failed to create spawn config") + ).unwrap(); + + let processes = winpty.console_process_list(1000).expect("failed to get console process list"); + + // Check that each id is valid + processes.iter().for_each(|id| { + let handle = unsafe { + OpenProcess( + READ_CONTROL, // permissions + false as i32, // inheret + *id as u32 + ) + }; + assert!(handle != null_mut()); + }); + } +} |