Fix screensaver idle timeout overflow by using 1s poll intervals with deadline tracking instead of direct millisecond conversion
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -573,7 +573,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "shed"
|
name = "shed"
|
||||||
version = "0.6.1"
|
version = "0.6.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ariadne",
|
"ariadne",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
name = "shed"
|
name = "shed"
|
||||||
description = "A linux shell written in rust"
|
description = "A linux shell written in rust"
|
||||||
publish = false
|
publish = false
|
||||||
version = "0.6.1"
|
version = "0.6.2"
|
||||||
|
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
{
|
{
|
||||||
packages.default = pkgs.rustPlatform.buildRustPackage {
|
packages.default = pkgs.rustPlatform.buildRustPackage {
|
||||||
pname = "shed";
|
pname = "shed";
|
||||||
version = "0.6.1";
|
version = "0.6.2";
|
||||||
|
|
||||||
src = self;
|
src = self;
|
||||||
|
|
||||||
|
|||||||
17
src/main.rs
17
src/main.rs
@@ -23,6 +23,7 @@ pub mod testutil;
|
|||||||
use std::os::fd::BorrowedFd;
|
use std::os::fd::BorrowedFd;
|
||||||
use std::process::ExitCode;
|
use std::process::ExitCode;
|
||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
use nix::errno::Errno;
|
use nix::errno::Errno;
|
||||||
use nix::poll::{PollFd, PollFlags, PollTimeout, poll};
|
use nix::poll::{PollFd, PollFlags, PollTimeout, poll};
|
||||||
@@ -255,6 +256,8 @@ fn shed_interactive(args: ShedArgs) -> ShResult<()> {
|
|||||||
|
|
||||||
readline.writer.flush_write("\x1b[?2004h")?; // enable bracketed paste mode
|
readline.writer.flush_write("\x1b[?2004h")?; // enable bracketed paste mode
|
||||||
|
|
||||||
|
let mut screensaver_deadline: Option<Instant> = None;
|
||||||
|
|
||||||
// Main poll loop
|
// Main poll loop
|
||||||
loop {
|
loop {
|
||||||
write_meta(|m| {
|
write_meta(|m| {
|
||||||
@@ -317,8 +320,15 @@ fn shed_interactive(args: ShedArgs) -> ShResult<()> {
|
|||||||
let screensaver_idle_time = read_shopts(|o| o.prompt.screensaver_idle_time);
|
let screensaver_idle_time = read_shopts(|o| o.prompt.screensaver_idle_time);
|
||||||
if screensaver_idle_time > 0 && !screensaver_cmd.is_empty() {
|
if screensaver_idle_time > 0 && !screensaver_cmd.is_empty() {
|
||||||
exec_if_timeout = Some(screensaver_cmd);
|
exec_if_timeout = Some(screensaver_cmd);
|
||||||
PollTimeout::from((screensaver_idle_time * 1000) as u16)
|
if screensaver_deadline.is_none() {
|
||||||
|
screensaver_deadline = Some(Instant::now() + Duration::from_secs(screensaver_idle_time as u64));
|
||||||
|
}
|
||||||
|
// We unfortunately cant just set the PollTimeout to use 'idle_time * 1000' as the timeout
|
||||||
|
// because u16 overflows after 65 seconds (65535 ms).
|
||||||
|
// So we set a one second timeout and check against the Instant in 'screensaver_deadline'
|
||||||
|
PollTimeout::from(1000u16)
|
||||||
} else {
|
} else {
|
||||||
|
screensaver_deadline = None;
|
||||||
PollTimeout::MAX
|
PollTimeout::MAX
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -328,7 +338,9 @@ fn shed_interactive(args: ShedArgs) -> ShResult<()> {
|
|||||||
match poll(&mut fds, timeout) {
|
match poll(&mut fds, timeout) {
|
||||||
Ok(0) => {
|
Ok(0) => {
|
||||||
// We timed out.
|
// We timed out.
|
||||||
if let Some(cmd) = exec_if_timeout {
|
if let Some(cmd) = exec_if_timeout
|
||||||
|
&& screensaver_deadline.is_some_and(|d| Instant::now() >= d) {
|
||||||
|
screensaver_deadline = None;
|
||||||
let prepared = ReadlineEvent::Line(cmd.clone());
|
let prepared = ReadlineEvent::Line(cmd.clone());
|
||||||
let saved_hist_opt = read_shopts(|o| o.core.auto_hist);
|
let saved_hist_opt = read_shopts(|o| o.core.auto_hist);
|
||||||
let _guard = scopeguard::guard(saved_hist_opt, |opt| {
|
let _guard = scopeguard::guard(saved_hist_opt, |opt| {
|
||||||
@@ -420,6 +432,7 @@ fn shed_interactive(args: ShedArgs) -> ShResult<()> {
|
|||||||
}
|
}
|
||||||
Ok(n) => {
|
Ok(n) => {
|
||||||
readline.feed_bytes(&buffer[..n]);
|
readline.feed_bytes(&buffer[..n]);
|
||||||
|
screensaver_deadline = None;
|
||||||
}
|
}
|
||||||
Err(Errno::EINTR) => {
|
Err(Errno::EINTR) => {
|
||||||
// Interrupted, continue to handle signals
|
// Interrupted, continue to handle signals
|
||||||
|
|||||||
Reference in New Issue
Block a user