From 5200d2a133b50b0ce9bfe79ec59177d3a0ccc595 Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Fri, 3 Jul 2020 21:05:04 -0400 Subject: prepare for ttyname from nix --- Cargo.lock | 1 - Cargo.toml | 1 - src/bin/rbw/actions.rs | 45 +++++++++++++++++++++++++++------------------ 3 files changed, 27 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7aa796e..70e254c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1146,7 +1146,6 @@ dependencies = [ "humantime 2.0.1", "libc", "log", - "memchr", "nix", "openssl", "paw", diff --git a/Cargo.toml b/Cargo.toml index 8b8c33d..df4e62c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,7 +25,6 @@ env_logger = "0.7" humantime = "2.0" libc = "0.2" log = "0.4" -memchr = "2.3" nix = "0.17" openssl = "0.10" paw = "1.0" diff --git a/src/bin/rbw/actions.rs b/src/bin/rbw/actions.rs index f9d48de..9e64bbf 100644 --- a/src/bin/rbw/actions.rs +++ b/src/bin/rbw/actions.rs @@ -1,5 +1,6 @@ use anyhow::Context as _; use std::io::Read as _; +use std::os::unix::ffi::OsStringExt as _; pub fn login() -> anyhow::Result<()> { simple_action(rbw::protocol::Action::Login) @@ -25,7 +26,9 @@ pub fn quit() -> anyhow::Result<()> { std::fs::File::open(pidfile)?.read_to_string(&mut pid)?; let pid = nix::unistd::Pid::from_raw(pid.parse()?); sock.send(&rbw::protocol::Request { - tty: ttyname(), + tty: ttyname(0) + .ok() + .and_then(|p| p.to_str().map(|s| s.to_string())), action: rbw::protocol::Action::Quit, })?; wait_for_exit(pid)?; @@ -47,7 +50,9 @@ pub fn decrypt( ) -> anyhow::Result { let mut sock = connect()?; sock.send(&rbw::protocol::Request { - tty: ttyname(), + tty: ttyname(0) + .ok() + .and_then(|p| p.to_str().map(|s| s.to_string())), action: rbw::protocol::Action::Decrypt { cipherstring: cipherstring.to_string(), org_id: org_id.map(std::string::ToString::to_string), @@ -70,7 +75,9 @@ pub fn encrypt( ) -> anyhow::Result { let mut sock = connect()?; sock.send(&rbw::protocol::Request { - tty: ttyname(), + tty: ttyname(0) + .ok() + .and_then(|p| p.to_str().map(|s| s.to_string())), action: rbw::protocol::Action::Encrypt { plaintext: plaintext.to_string(), org_id: org_id.map(std::string::ToString::to_string), @@ -90,7 +97,9 @@ pub fn encrypt( pub fn version() -> anyhow::Result { let mut sock = connect()?; sock.send(&rbw::protocol::Request { - tty: ttyname(), + tty: ttyname(0) + .ok() + .and_then(|p| p.to_str().map(|s| s.to_string())), action: rbw::protocol::Action::Version, })?; @@ -108,7 +117,9 @@ fn simple_action(action: rbw::protocol::Action) -> anyhow::Result<()> { let mut sock = connect()?; sock.send(&rbw::protocol::Request { - tty: ttyname(), + tty: ttyname(0) + .ok() + .and_then(|p| p.to_str().map(|s| s.to_string())), action, })?; @@ -134,25 +145,23 @@ fn connect() -> anyhow::Result { }) } -// TODO: it'd be great if ttyname_r was exposed via nix, so i didn't have to -// manually deal with unsafe here -fn ttyname() -> Option { +// XXX copied (with small modifications) from the as-yet-unreleased nix +// version, should use that directly once 0.18 is released +fn ttyname( + fd: std::os::unix::io::RawFd, +) -> anyhow::Result { const PATH_MAX: usize = libc::PATH_MAX as usize; - let mut buf = [0_u8; PATH_MAX]; + let mut buf = vec![0_u8; PATH_MAX]; let c_buf = buf.as_mut_ptr() as *mut libc::c_char; - let ret = unsafe { libc::ttyname_r(0, c_buf, PATH_MAX) }; + let ret = unsafe { libc::ttyname_r(fd, c_buf, buf.len()) }; if ret != 0 { - return None; + return Err(anyhow::anyhow!("ttyname_r failed: {}", ret)); } - let nul = memchr::memchr(b'\0', &buf)?; - if nul == 0 { - return None; - } - - let s = std::str::from_utf8(&buf[..nul]).ok()?; - Some(s.to_string()) + let nul = buf.iter().position(|c| *c == b'\0').unwrap(); + buf.truncate(nul); + Ok(std::ffi::OsString::from_vec(buf).into()) } fn wait_for_exit(pid: nix::unistd::Pid) -> anyhow::Result<()> { -- cgit v1.2.3-54-g00ecf