From 315af1d822941f5bdb71e857abf6feac92f14372 Mon Sep 17 00:00:00 2001 From: Yash Srivastav Date: Tue, 26 Mar 2019 01:55:07 +0530 Subject: [PATCH] Implement --lock-now for instantly calling primary timer --- Cargo.lock | 10 +++++++++ Cargo.toml | 1 + src/main.rs | 60 +++++++++++++++++++++++++++++++++++++++-------------- 3 files changed, 56 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 74e656c..ea0160f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -300,6 +300,14 @@ name = "unicode-xid" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "users" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "vec_map" version = "0.8.1" @@ -366,6 +374,7 @@ dependencies = [ "libpulse-sys 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", "nix 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", + "users 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "x11 2.18.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -407,6 +416,7 @@ dependencies = [ "checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6" "checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" +"checksum users 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c72f4267aea0c3ec6d07eaabea6ead7c5ddacfafc5e22bcf8d186706851fb4cf" "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 winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" diff --git a/Cargo.toml b/Cargo.toml index 18d99c4..cad7877 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ version = "0.6.2" clap = "2.32.0" failure = "0.1.5" mio = "0.6.16" +users = "0.9.1" [dependencies.libpulse-sys] optional = true diff --git a/src/main.rs b/src/main.rs index 691e1df..ea311a1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,6 +3,7 @@ #[macro_use] extern crate clap; #[macro_use] extern crate failure; extern crate mio; +extern crate users; extern crate x11; #[cfg(feature = "pulse")] use std::sync::mpsc; @@ -16,19 +17,21 @@ use nix::sys::{ }; use std::{ collections::HashMap, + env::temp_dir, fs, io::{self, prelude::*}, mem, os::{ unix::{ io::AsRawFd, - net::UnixListener + net::{UnixListener, UnixStream}, } }, path::Path, process::Command, time::Duration }; +use users::get_current_uid; use x11::xss::{XScreenSaverAllocInfo, XScreenSaverInfo}; #[cfg(feature = "pulse")] mod pulse; @@ -79,6 +82,12 @@ fn main() -> Result<(), Error> { .help("Print the idle time to standard output. This is similar to xprintidle.") .long("print") ) + .arg( + Arg::with_name("lock-now") + .help("Execute the primary timer immediately.") + .long("lock-now") + .conflicts_with("print") + ) .arg( Arg::with_name("not-when-fullscreen") .long_help("\ @@ -88,15 +97,17 @@ fn main() -> Result<(), Error> { ") .long("not-when-fullscreen") .conflicts_with("print") + .conflicts_with("lock-now") ) .arg( Arg::with_name("once") .long_help("\ Exit after timer command has been invoked once. \ - This does not include manual invoking using the socket. \ + This does not include manual invoking using the socket or --lock-now. \ ") .long("once") .conflicts_with("print") + .conflicts_with("lock-now") ) // Options .arg( @@ -123,6 +134,7 @@ fn main() -> Result<(), Error> { .multiple(true) .required_unless("print") .conflicts_with("print") + .conflicts_with("lock-now") ) .arg( Arg::with_name("socket") @@ -146,6 +158,7 @@ fn main() -> Result<(), Error> { .help("Don't invoke the timer when any audio is playing (PulseAudio specific)") .long("not-when-audio") .conflicts_with("print") + .conflicts_with("lock-now") ); } let matches = clap_app.get_matches(); @@ -160,6 +173,31 @@ fn main() -> Result<(), Error> { return Ok(()); } + let mut temp_file; + let socket = match matches.value_of("socket") { + None => { + let uid = get_current_uid(); + temp_file = temp_dir(); + temp_file.push(format!("xidlehook{}", uid)); + fs::create_dir(&temp_file).or_else(|err| { + if err.kind() == io::ErrorKind::AlreadyExists { + Ok(()) + } else { + Err(err) + } + })?; + temp_file.push("socket"); + temp_file.to_str().ok_or(io::Error::new(io::ErrorKind::Other, "Unable to get socket file location!")) + }, + Some(socket) => Ok(socket) + }?; + + if matches.is_present("lock-now") { + let mut socket = UnixStream::connect(&socket)?; + socket.write_all(b"\x02")?; + return Ok(()); + } + #[cfg(feature = "nix")] let mut signal = { let mut mask = SigSet::empty(); @@ -247,19 +285,11 @@ fn main() -> Result<(), Error> { #[cfg(feature = "nix")] poll.register(&EventedFd(&signal.as_raw_fd()), TOKEN_SIGNAL, Ready::readable(), PollOpt::edge())?; - let mut _socket = None; - let mut listener = match matches.value_of("socket") { - None => None, - Some(socket) => { - let mut listener = UnixListener::bind(&socket)?; - _socket = Some(DeferRemove(socket)); // remove file when exiting - - listener.set_nonblocking(true)?; + let listener = UnixListener::bind(&socket)?; + let _socket = DeferRemove(socket); // remove file when exiting + listener.set_nonblocking(true)?; + poll.register(&EventedFd(&listener.as_raw_fd()), TOKEN_SERVER, Ready::readable(), PollOpt::edge())?; - poll.register(&EventedFd(&listener.as_raw_fd()), TOKEN_SERVER, Ready::readable(), PollOpt::edge())?; - Some(listener) - } - }; let mut clients = HashMap::new(); let mut next_client = TOKEN_CLIENT.into(); @@ -286,7 +316,7 @@ fn main() -> Result<(), Error> { match event.token() { #[cfg(feature = "nix")] TOKEN_SIGNAL => if signal.read_signal()?.is_some() { break 'main; }, - TOKEN_SERVER => if let Some(listener) = listener.as_mut() { + TOKEN_SERVER => { let (mut socket, _) = match maybe(listener.accept())? { Some(socket) => socket, None => continue