From 9108e7d28de43264284a84b98ed99c3fe3ba0dc2 Mon Sep 17 00:00:00 2001 From: Michael Zhang Date: Sat, 7 Jan 2023 18:31:39 -0600 Subject: [PATCH] format --- Cargo.lock | 158 +++++++++++----------- flake.lock | 22 +++- flake.nix | 13 +- src/asciicast.rs | 88 ++++++------- src/errors.rs | 16 +-- src/main.rs | 22 ++-- src/pty.rs | 333 +++++++++++++++++++++++------------------------ src/recorder.rs | 38 +++--- src/writer.rs | 46 +++---- 9 files changed, 377 insertions(+), 359 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fbc0431..37d5474 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,9 +13,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.57" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc" +checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61" [[package]] name = "asciinema" @@ -43,7 +43,7 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "hermit-abi", + "hermit-abi 0.1.19", "libc", "winapi", ] @@ -68,9 +68,9 @@ checksum = "e0dcbc35f504eb6fc275a6d20e4ebcda18cf50d40ba6fabff8c711fa16cb3b16" [[package]] name = "cc" -version = "1.0.73" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" +checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d" [[package]] name = "cfg-if" @@ -95,9 +95,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.21" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e" +checksum = "38390104763dc37a5145a53c29c63c1290b5d316d6086ec32c293f6736051bb0" dependencies = [ "futures-channel", "futures-core", @@ -110,9 +110,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.21" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" +checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed" dependencies = [ "futures-core", "futures-sink", @@ -120,15 +120,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.21" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" +checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" [[package]] name = "futures-executor" -version = "0.3.21" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" +checksum = "7acc85df6714c176ab5edf386123fafe217be88c0840ec11f199441134a074e2" dependencies = [ "futures-core", "futures-task", @@ -137,15 +137,15 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.21" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" +checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb" [[package]] name = "futures-macro" -version = "0.3.21" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" +checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d" dependencies = [ "proc-macro2", "quote", @@ -154,21 +154,21 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.21" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" +checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9" [[package]] name = "futures-task" -version = "0.3.21" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" +checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea" [[package]] name = "futures-util" -version = "0.3.21" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" +checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6" dependencies = [ "futures-channel", "futures-core", @@ -200,6 +200,15 @@ dependencies = [ "libc", ] +[[package]] +name = "hermit-abi" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" +dependencies = [ + "libc", +] + [[package]] name = "instant" version = "0.1.12" @@ -211,9 +220,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.1" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" +checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440" [[package]] name = "lazy_static" @@ -223,15 +232,15 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.125" +version = "0.2.139" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5916d2ae698f6de9bfb891ad7a8d65c09d232dc58cc4ac433c7da3b2fd84bc2b" +checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" [[package]] name = "lock_api" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" +checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" dependencies = [ "autocfg", "scopeguard", @@ -297,19 +306,19 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.13.1" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" dependencies = [ - "hermit-abi", + "hermit-abi 0.2.6", "libc", ] [[package]] name = "once_cell" -version = "1.10.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" +checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66" [[package]] name = "parking_lot" @@ -324,9 +333,9 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" +checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" dependencies = [ "cfg-if", "instant", @@ -374,36 +383,36 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.38" +version = "1.0.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9027b48e9d4c9175fa2218adf3557f91c1137021739951d4932f5f8268ac48aa" +checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5" dependencies = [ - "unicode-xid", + "unicode-ident", ] [[package]] name = "quote" -version = "1.0.18" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" +checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" dependencies = [ "proc-macro2", ] [[package]] name = "redox_syscall" -version = "0.2.13" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ "bitflags", ] [[package]] name = "ryu" -version = "1.0.9" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" +checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde" [[package]] name = "scopeguard" @@ -413,15 +422,15 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "serde" -version = "1.0.137" +version = "1.0.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1" +checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb" [[package]] name = "serde_derive" -version = "1.0.137" +version = "1.0.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be" +checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e" dependencies = [ "proc-macro2", "quote", @@ -430,9 +439,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.81" +version = "1.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c" +checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883" dependencies = [ "itoa", "ryu", @@ -460,15 +469,18 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32" +checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +dependencies = [ + "autocfg", +] [[package]] name = "smallvec" -version = "1.8.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" [[package]] name = "strsim" @@ -502,13 +514,13 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.92" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ff7c592601f11445996a06f8ad0c27f094a58857c2f89e97974ab9235b92c52" +checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" dependencies = [ "proc-macro2", "quote", - "unicode-xid", + "unicode-ident", ] [[package]] @@ -531,18 +543,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.31" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a" +checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.31" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" +checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" dependencies = [ "proc-macro2", "quote", @@ -597,22 +609,22 @@ dependencies = [ ] [[package]] -name = "unicode-segmentation" -version = "1.9.0" +name = "unicode-ident" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99" +checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" + +[[package]] +name = "unicode-segmentation" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fdbf052a0783de01e944a6ce7a8cb939e295b1e7be835a1112c3b9a7f047a5a" [[package]] name = "unicode-width" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" - -[[package]] -name = "unicode-xid" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04" +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" [[package]] name = "vec_map" diff --git a/flake.lock b/flake.lock index 0c5b225..a35d60c 100644 --- a/flake.lock +++ b/flake.lock @@ -2,9 +2,7 @@ "nodes": { "fenix": { "inputs": { - "nixpkgs": [ - "nixpkgs" - ], + "nixpkgs": "nixpkgs", "rust-analyzer-src": "rust-analyzer-src" }, "locked": { @@ -36,6 +34,22 @@ } }, "nixpkgs": { + "locked": { + "lastModified": 1672953546, + "narHash": "sha256-oz757DnJ1ITvwyTovuwG3l9cX6j9j6/DH9eH+cXFJmc=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "a518c77148585023ff56022f09c4b2c418a51ef5", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { "locked": { "lastModified": 1667629849, "narHash": "sha256-P+v+nDOFWicM4wziFK9S/ajF2lc0N2Rg9p6Y35uMoZI=", @@ -53,7 +67,7 @@ "inputs": { "fenix": "fenix", "flake-utils": "flake-utils", - "nixpkgs": "nixpkgs" + "nixpkgs": "nixpkgs_2" } }, "rust-analyzer-src": { diff --git a/flake.nix b/flake.nix index 58bb100..0ee3612 100644 --- a/flake.nix +++ b/flake.nix @@ -1,8 +1,5 @@ { - inputs = { - fenix.url = "github:nix-community/fenix"; - fenix.inputs.nixpkgs.follows = "nixpkgs"; - }; + inputs = { fenix.url = "github:nix-community/fenix"; }; outputs = { self, nixpkgs, flake-utils, fenix }: flake-utils.lib.eachDefaultSystem (system: @@ -12,7 +9,7 @@ overlays = [ fenix.overlays.default ]; }; - toolchain = pkgs.fenix.default; + toolchain = pkgs.fenix.stable; flakePkgs = { asciinema = pkgs.callPackage ./. { inherit toolchain; }; @@ -23,9 +20,9 @@ devShell = pkgs.mkShell { inputsFrom = with packages; [ asciinema ]; - packages = - (with pkgs; [ cargo-watch cargo-deny cargo-edit sqlx-cli sqlite ]) - ++ (with toolchain; [ cargo rustc ]); + packages = (with pkgs; [ cargo-watch cargo-deny cargo-edit ]) + ++ (with toolchain; [ cargo rustc rustfmt ]); + CARGO_UNSTABLE_SPARSE_REGISTRY = "true"; }; }); } diff --git a/src/asciicast.rs b/src/asciicast.rs index cbdcb67..e700830 100644 --- a/src/asciicast.rs +++ b/src/asciicast.rs @@ -4,66 +4,66 @@ use serde::ser::{Serialize, SerializeSeq, Serializer}; #[derive(Serialize)] pub struct Header { - version: u32, - width: u32, - height: u32, + version: u32, + width: u32, + height: u32, - timestamp: Option, - duration: Option, - idle_time_limit: Option, - command: Option, - title: Option, - env: Option>, - theme: Option, + timestamp: Option, + duration: Option, + idle_time_limit: Option, + command: Option, + title: Option, + env: Option>, + theme: Option, } #[derive(Serialize)] pub struct Theme { - fg: String, - bg: String, - palette: String, + fg: String, + bg: String, + palette: String, } pub struct Event<'a>(pub f64, pub EventKind<'a>); pub enum EventKind<'a> { - Output(&'a [u8]), - Input(&'a [u8]), + Output(&'a [u8]), + Input(&'a [u8]), } impl<'a> Serialize for Event<'a> { - fn serialize( - &self, - s: S, - ) -> std::result::Result { - let mut seq = s.serialize_seq(Some(3))?; - seq.serialize_element(&self.0)?; - match &self.1 { - EventKind::Output(s) => { - seq.serialize_element("o")?; - seq.serialize_element(std::str::from_utf8(s).unwrap())?; - } - EventKind::Input(s) => { - seq.serialize_element("i")?; - seq.serialize_element(std::str::from_utf8(s).unwrap())?; - } - } - seq.end() + fn serialize( + &self, + s: S, + ) -> std::result::Result { + let mut seq = s.serialize_seq(Some(3))?; + seq.serialize_element(&self.0)?; + match &self.1 { + EventKind::Output(s) => { + seq.serialize_element("o")?; + seq.serialize_element(std::str::from_utf8(s).unwrap())?; + } + EventKind::Input(s) => { + seq.serialize_element("i")?; + seq.serialize_element(std::str::from_utf8(s).unwrap())?; + } } + seq.end() + } } fn build_header(width: u32, height: u32) -> Header { - Header { - version: 2, - width, - height, + Header { + version: 2, + width, + height, - timestamp: None, - duration: None, - idle_time_limit: None, - command: None, - title: None, - env: None, - theme: None, - } + timestamp: None, + duration: None, + idle_time_limit: None, + command: None, + title: None, + env: None, + theme: None, + } } diff --git a/src/errors.rs b/src/errors.rs index c9c88a1..61e5b8b 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -2,15 +2,15 @@ pub type Result = std::result::Result; #[derive(Debug, Error)] pub enum Error { - #[error("generic nix error: {0}")] - Nix(#[from] nix::Error), + #[error("generic nix error: {0}")] + Nix(#[from] nix::Error), - #[error("write(3) error (fd={1}, data={2:?}): {0}")] - NixWrite(nix::Error, i32, Vec), + #[error("write(3) error (fd={1}, data={2:?}): {0}")] + NixWrite(nix::Error, i32, Vec), - #[error("generic io error: {0}")] - Io(#[from] std::io::Error), + #[error("generic io error: {0}")] + Io(#[from] std::io::Error), - #[error("generic serde_json error: {0}")] - SerdeJson(#[from] serde_json::Error), + #[error("generic serde_json error: {0}")] + SerdeJson(#[from] serde_json::Error), } diff --git a/src/main.rs b/src/main.rs index 2fe1804..a979b2c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -19,22 +19,22 @@ use crate::writer::FileWriter; #[derive(StructOpt)] enum Command { - /// Record terminal session. - #[structopt(name = "rec")] - Record, + /// Record terminal session. + #[structopt(name = "rec")] + Record, } fn record() -> Result<()> { - let file = File::create("output.cast")?; - pty::record(&["sh", "-c", "/usr/bin/zsh"], FileWriter::new(file))?; - Ok(()) + let file = File::create("output.cast")?; + pty::record(&["sh", "-c", "/usr/bin/zsh"], FileWriter::new(file))?; + Ok(()) } fn main() -> Result<()> { - match Command::from_args() { - Command::Record => { - record()?; - } + match Command::from_args() { + Command::Record => { + record()?; } - Ok(()) + } + Ok(()) } diff --git a/src/pty.rs b/src/pty.rs index 4a8a4a7..612c2b8 100644 --- a/src/pty.rs +++ b/src/pty.rs @@ -5,15 +5,15 @@ use std::os::unix::io::RawFd; use std::time::Instant; use nix::{ - fcntl::{fcntl, FcntlArg, OFlag}, - ioctl_write_buf, - pty::{forkpty, Winsize}, - sys::{ - select::{select, FdSet}, - termios::{tcsetattr, SetArg, Termios}, - wait::waitpid, - }, - unistd::{execvpe, isatty, pipe, read, write, ForkResult}, + fcntl::{fcntl, FcntlArg, OFlag}, + ioctl_write_buf, + pty::{forkpty, Winsize}, + sys::{ + select::{select, FdSet}, + termios::{tcsetattr, SetArg, Termios}, + wait::waitpid, + }, + unistd::{execvpe, isatty, pipe, read, write, ForkResult}, }; use signal_hook::SigId; @@ -24,181 +24,180 @@ const STDIN_FILENO: RawFd = 0; const STDOUT_FILENO: RawFd = 1; pub fn record(args: &[&str], writer: impl Writer + Send) -> Result<()> { - let forkpty_result = forkpty(None, None)?; - let master_fd = forkpty_result.master; - let start_time = Instant::now(); + let forkpty_result = forkpty(None, None)?; + let master_fd = forkpty_result.master; + let start_time = Instant::now(); - let set_pty_size = || -> Result<()> { - ioctl_write_buf!(helper_write, libc::TIOCGWINSZ, 104, Winsize); - let winsize = Winsize { - ws_row: 24, - ws_col: 80, - ws_xpixel: 0, - ws_ypixel: 0, - }; - if isatty(STDOUT_FILENO)? {} - unsafe { helper_write(master_fd, &[winsize]) }?; - Ok(()) + let _set_pty_size = || -> Result<()> { + ioctl_write_buf!(helper_write, libc::TIOCGWINSZ, 104, Winsize); + let winsize = Winsize { + ws_row: 24, + ws_col: 80, + ws_xpixel: 0, + ws_ypixel: 0, }; - - let write_stdout = |data: &[u8]| -> Result<()> { - write(STDOUT_FILENO, &data)?; - Ok(()) - }; - - let mut master_writer = writer.clone(); - let mut handle_master_read = move |data: &[u8]| -> Result<()> { - let elapsed = (Instant::now() - start_time).as_secs_f64(); - master_writer.write_stdout(elapsed, data)?; - write_stdout(data)?; - Ok(()) - }; - - let write_master = |data: &[u8]| -> Result<()> { - let mut offset = 0; - while offset < data.len() { - let len = write(master_fd, data).map_err(|err| { - Error::NixWrite(err, master_fd, data.to_vec()) - })?; - offset += len; - } - Ok(()) - }; - - let mut stdin_writer = writer.clone(); - let mut handle_stdin_read = |data: &[u8]| -> Result<()> { - write_master(data)?; - let elapsed = (Instant::now() - start_time).as_secs_f64(); - stdin_writer.write_stdin(elapsed, data)?; - Ok(()) - }; - - let mut copy = |signal_fd: RawFd| -> Result<()> { - let mut fdset = FdSet::new(); - let mut buf = [0; 1024]; - - loop { - fdset.clear(); - fdset.insert(master_fd); - fdset.insert(STDIN_FILENO); - fdset.insert(signal_fd); - - select(None, &mut fdset, None, None, None)?; - - if fdset.contains(master_fd) { - let len = read(master_fd, &mut buf)?; - if len == 0 { - fdset.remove(master_fd); - } else { - handle_master_read(&buf[..len])?; - } - } else if fdset.contains(STDIN_FILENO) { - let len = read(STDIN_FILENO, &mut buf)?; - if len == 0 { - fdset.remove(STDIN_FILENO); - } else { - handle_stdin_read(&buf[..len])?; - } - } else if fdset.contains(signal_fd) { - // TODO - } - } - }; - - let child_pid = match forkpty_result.fork_result { - ForkResult::Parent { child } => child, - ForkResult::Child => { - let cstr_args: Vec<_> = args - .into_iter() - .map(|s| CString::new(*s).unwrap()) - .collect(); - let args: Vec<_> = cstr_args.iter().map(|s| s.as_ref()).collect(); - let cstr_env: Vec<_> = env::vars() - .map(|(k, v)| CString::new(format!("{}={}", k, v)).unwrap()) - .collect(); - let env: Vec<_> = cstr_env.iter().map(|s| s.as_ref()).collect(); - execvpe(&args[0], &args, &env)?; - unreachable!(); - } - }; - - let (pipe_r, pipe_w) = pipe()?; - let mut flags = fcntl(pipe_w, FcntlArg::F_GETFL)?; - flags |= libc::O_NONBLOCK; - fcntl(pipe_w, FcntlArg::F_SETFL(OFlag::from_bits(flags).unwrap()))?; - - let old_handlers = set_signals( - [ - signal_hook::SIGWINCH, - signal_hook::SIGCHLD, - signal_hook::SIGHUP, - signal_hook::SIGTERM, - signal_hook::SIGQUIT, - ] - .iter() - .map(|sig| (*sig, move || eprintln!("HIT SIGNAL {:?}", *sig))), - )?; - - // set_pty_size()?; - - { - let _term = RawTerm::init(STDIN_FILENO)?; - copy(pipe_r)?; - } - unset_signals(old_handlers)?; - - waitpid(child_pid, None)?; - + if isatty(STDOUT_FILENO)? {} + unsafe { helper_write(master_fd, &[winsize]) }?; Ok(()) + }; + + let write_stdout = |data: &[u8]| -> Result<()> { + write(STDOUT_FILENO, &data)?; + Ok(()) + }; + + let mut master_writer = writer.clone(); + let mut handle_master_read = move |data: &[u8]| -> Result<()> { + let elapsed = (Instant::now() - start_time).as_secs_f64(); + master_writer.write_stdout(elapsed, data)?; + write_stdout(data)?; + Ok(()) + }; + + let write_master = |data: &[u8]| -> Result<()> { + let mut offset = 0; + while offset < data.len() { + let len = write(master_fd, data) + .map_err(|err| Error::NixWrite(err, master_fd, data.to_vec()))?; + offset += len; + } + Ok(()) + }; + + let mut stdin_writer = writer.clone(); + let mut handle_stdin_read = |data: &[u8]| -> Result<()> { + write_master(data)?; + let elapsed = (Instant::now() - start_time).as_secs_f64(); + stdin_writer.write_stdin(elapsed, data)?; + Ok(()) + }; + + let mut copy = |signal_fd: RawFd| -> Result<()> { + let mut fdset = FdSet::new(); + let mut buf = [0; 1024]; + + loop { + fdset.clear(); + fdset.insert(master_fd); + fdset.insert(STDIN_FILENO); + fdset.insert(signal_fd); + + select(None, &mut fdset, None, None, None)?; + + if fdset.contains(master_fd) { + let len = read(master_fd, &mut buf)?; + if len == 0 { + fdset.remove(master_fd); + } else { + handle_master_read(&buf[..len])?; + } + } else if fdset.contains(STDIN_FILENO) { + let len = read(STDIN_FILENO, &mut buf)?; + if len == 0 { + fdset.remove(STDIN_FILENO); + } else { + handle_stdin_read(&buf[..len])?; + } + } else if fdset.contains(signal_fd) { + // TODO + } + } + }; + + let child_pid = match forkpty_result.fork_result { + ForkResult::Parent { child } => child, + ForkResult::Child => { + let cstr_args: Vec<_> = args + .into_iter() + .map(|s| CString::new(*s).unwrap()) + .collect(); + let args: Vec<_> = cstr_args.iter().map(|s| s.as_ref()).collect(); + let cstr_env: Vec<_> = env::vars() + .map(|(k, v)| CString::new(format!("{}={}", k, v)).unwrap()) + .collect(); + let env: Vec<_> = cstr_env.iter().map(|s| s.as_ref()).collect(); + execvpe(&args[0], &args, &env)?; + unreachable!(); + } + }; + + let (pipe_r, pipe_w) = pipe()?; + let mut flags = fcntl(pipe_w, FcntlArg::F_GETFL)?; + flags |= libc::O_NONBLOCK; + fcntl(pipe_w, FcntlArg::F_SETFL(OFlag::from_bits(flags).unwrap()))?; + + let old_handlers = set_signals( + [ + signal_hook::SIGWINCH, + signal_hook::SIGCHLD, + signal_hook::SIGHUP, + signal_hook::SIGTERM, + signal_hook::SIGQUIT, + ] + .iter() + .map(|sig| (*sig, move || eprintln!("HIT SIGNAL {:?}", *sig))), + )?; + + // set_pty_size()?; + + { + let _term = RawTerm::init(STDIN_FILENO)?; + copy(pipe_r)?; + } + unset_signals(old_handlers)?; + + waitpid(child_pid, None)?; + + Ok(()) } fn set_signals(signals_list: I) -> Result, io::Error> where - I: Iterator, - F: Fn() + Sync + Send + 'static, + I: Iterator, + F: Fn() + Sync + Send + 'static, { - let mut old_handlers = Vec::new(); - for (sig, handler) in signals_list { - old_handlers.push(unsafe { signal_hook::register(sig, handler) }?); - } - Ok(old_handlers) + let mut old_handlers = Vec::new(); + for (sig, handler) in signals_list { + old_handlers.push(unsafe { signal_hook::register(sig, handler) }?); + } + Ok(old_handlers) } fn unset_signals(handlers_list: Vec) -> Result<(), io::Error> { - for handler in handlers_list { - signal_hook::unregister(handler); - } - Ok(()) + for handler in handlers_list { + signal_hook::unregister(handler); + } + Ok(()) } struct RawTerm(RawFd, Termios); impl RawTerm { - pub fn init(fd: RawFd) -> Result { - use nix::sys::termios::*; - let saved_mode = tcgetattr(fd)?; - let mut mode = saved_mode.clone(); - mode.input_flags &= !(InputFlags::BRKINT - | InputFlags::ICRNL - | InputFlags::INPCK - | InputFlags::ISTRIP - | InputFlags::IXON); - mode.output_flags &= !OutputFlags::OPOST; - mode.control_flags &= !(ControlFlags::CSIZE | ControlFlags::PARENB); - mode.control_flags |= ControlFlags::CS8; - mode.local_flags &= !(LocalFlags::ECHO - | LocalFlags::ICANON - | LocalFlags::IEXTEN - | LocalFlags::ISIG); - mode.control_chars[libc::VMIN] = 1; - mode.control_chars[libc::VTIME] = 0; - tcsetattr(fd, SetArg::TCSAFLUSH, &mode)?; - Ok(RawTerm(fd, saved_mode)) - } + pub fn init(fd: RawFd) -> Result { + use nix::sys::termios::*; + let saved_mode = tcgetattr(fd)?; + let mut mode = saved_mode.clone(); + mode.input_flags &= !(InputFlags::BRKINT + | InputFlags::ICRNL + | InputFlags::INPCK + | InputFlags::ISTRIP + | InputFlags::IXON); + mode.output_flags &= !OutputFlags::OPOST; + mode.control_flags &= !(ControlFlags::CSIZE | ControlFlags::PARENB); + mode.control_flags |= ControlFlags::CS8; + mode.local_flags &= !(LocalFlags::ECHO + | LocalFlags::ICANON + | LocalFlags::IEXTEN + | LocalFlags::ISIG); + mode.control_chars[libc::VMIN] = 1; + mode.control_chars[libc::VTIME] = 0; + tcsetattr(fd, SetArg::TCSAFLUSH, &mode)?; + Ok(RawTerm(fd, saved_mode)) + } } impl Drop for RawTerm { - fn drop(&mut self) { - tcsetattr(self.0, SetArg::TCSAFLUSH, &self.1).unwrap(); - } + fn drop(&mut self) { + tcsetattr(self.0, SetArg::TCSAFLUSH, &self.1).unwrap(); + } } diff --git a/src/recorder.rs b/src/recorder.rs index c8bd4d5..45018e3 100644 --- a/src/recorder.rs +++ b/src/recorder.rs @@ -1,34 +1,30 @@ -use std::collections::HashMap; use std::env; use std::path::PathBuf; -use crate::asciicast::Header; -use crate::term; - pub struct RecordOptions { - pub path: PathBuf, - pub append: Option, - pub command: Option, - pub capture_env: Option>, - pub title: Option, + pub path: PathBuf, + pub append: Option, + pub command: Option, + pub capture_env: Option>, + pub title: Option, } pub fn record(options: RecordOptions) { - let command = options - .command - .unwrap_or_else(|| env::var("SHELL").unwrap_or_else(|_| "sh".to_string())); + let _command = options + .command + .unwrap_or_else(|| env::var("SHELL").unwrap_or_else(|_| "sh".to_string())); - let command_env = env::vars(); + let _command_env = env::vars(); - // let header_env = HashMap::new(); + // let header_env = HashMap::new(); - // let (width, height) = term::get_size(); + // let (width, height) = term::get_size(); - // let header = Header { - // version: 2, - // width, - // height, + // let header = Header { + // version: 2, + // width, + // height, - // title: options.title, - // }; + // title: options.title, + // }; } diff --git a/src/writer.rs b/src/writer.rs index 704cf3f..3f215a0 100644 --- a/src/writer.rs +++ b/src/writer.rs @@ -8,38 +8,38 @@ use crate::asciicast::{Event, EventKind}; use crate::errors::Result; pub trait Writer: Clone { - fn write_line(&mut self, line: String) -> Result<(), io::Error>; + fn write_line(&mut self, line: String) -> Result<(), io::Error>; - fn write_stdin(&mut self, time: f64, data: &[u8]) -> Result<()> { - let output = EventKind::Input(data); - let event = Event(time, output); - self.write_line(serde_json::to_string(&event)?)?; - Ok(()) - } + fn write_stdin(&mut self, time: f64, data: &[u8]) -> Result<()> { + let output = EventKind::Input(data); + let event = Event(time, output); + self.write_line(serde_json::to_string(&event)?)?; + Ok(()) + } - fn write_stdout(&mut self, time: f64, data: &[u8]) -> Result<()> { - let output = EventKind::Output(data); - let event = Event(time, output); - self.write_line(serde_json::to_string(&event)?)?; - Ok(()) - } + fn write_stdout(&mut self, time: f64, data: &[u8]) -> Result<()> { + let output = EventKind::Output(data); + let event = Event(time, output); + self.write_line(serde_json::to_string(&event)?)?; + Ok(()) + } } #[derive(Clone)] pub struct FileWriter(Arc>); impl FileWriter { - pub fn new(file: File) -> Self { - FileWriter(Arc::new(Mutex::new(file))) - } + pub fn new(file: File) -> Self { + FileWriter(Arc::new(Mutex::new(file))) + } } impl Writer for FileWriter { - fn write_line(&mut self, line: String) -> Result<(), io::Error> { - let mut writer = self.0.lock(); - writer.write_all(line.as_bytes())?; - writer.write(b"\n")?; - writer.flush()?; - Ok(()) - } + fn write_line(&mut self, line: String) -> Result<(), io::Error> { + let mut writer = self.0.lock(); + writer.write_all(line.as_bytes())?; + writer.write(b"\n")?; + writer.flush()?; + Ok(()) + } }