Skip to content

Commit 0aac94d

Browse files
authored
chore: Enforce tmux session ID existence (#24)
* chore: Enforce tmux session ID existence * fix lint warnings * fix integration test * fix test? * format * is feature flag change necessary
1 parent 4f711bf commit 0aac94d

File tree

2 files changed

+34
-21
lines changed

2 files changed

+34
-21
lines changed

src/daemon.rs

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use anyhow::bail;
12
use chrono::{DateTime, Local};
23
use clap::{Parser, Subcommand};
34
use nix::sys::signal;
@@ -59,14 +60,12 @@ impl Drop for FileGuard {
5960
}
6061

6162
struct DaemonState {
62-
tmux_session_id: String,
6363
start_ts: DateTime<Local>,
6464
}
6565

6666
impl DaemonState {
67-
fn new(tmux_session_id: String) -> Self {
67+
fn new() -> Self {
6868
Self {
69-
tmux_session_id,
7069
start_ts: Local::now(),
7170
}
7271
}
@@ -79,8 +78,11 @@ async fn start_daemon() -> anyhow::Result<()> {
7978
.init();
8079

8180
print_info("Starting daemon...");
82-
let session_id = get_tmux_session_id();
83-
let daemon_state = Arc::new(DaemonState::new(session_id));
81+
if get_tmux_session_id().is_none() {
82+
print_error("Must be run within a tmux session.");
83+
bail!("Not in a tmux session");
84+
}
85+
let daemon_state = Arc::new(DaemonState::new());
8486
// TODO: check instance, socket
8587
let pid_path = PathBuf::from(get_pid_file_path());
8688
if pid_path.exists() {
@@ -117,8 +119,13 @@ async fn start_daemon() -> anyhow::Result<()> {
117119
}
118120
_ = main_loop_interval.tick() => {
119121
// TODO: state management
120-
let session_info_clone = session_info.clone();
121-
get_agent_locations(session_info_clone, daemon_state.as_ref()).await?;
122+
if let Some(tmux_session_id) = get_tmux_session_id() {
123+
let session_info_clone = session_info.clone();
124+
get_agent_locations(session_info_clone, &tmux_session_id).await?;
125+
} else {
126+
print_error("tmux session no longer exists, assuming it's already closed. Exiting.");
127+
break;
128+
}
122129
}
123130
_ = tokio::signal::ctrl_c() => {
124131
print_info("Received SIGINT, shutting down...");
@@ -260,7 +267,7 @@ async fn stop_daemon() -> anyhow::Result<()> {
260267
#[cfg(feature = "test-mode")]
261268
async fn get_agent_locations(
262269
_session_info: Arc<RwLock<HashMap<String, AgentSessionInfo>>>,
263-
_daemon_state: &DaemonState,
270+
_session_id: &str,
264271
) -> anyhow::Result<()> {
265272
print_info("Test mode: skipping agent location detection");
266273
Ok(())
@@ -269,7 +276,7 @@ async fn get_agent_locations(
269276
#[cfg(not(feature = "test-mode"))]
270277
async fn get_agent_locations(
271278
session_info: Arc<RwLock<HashMap<String, AgentSessionInfo>>>,
272-
daemon_state: &DaemonState,
279+
tmux_session_id: &str,
273280
) -> anyhow::Result<()> {
274281
// TODO: clean up, consolidate, etc.
275282
let tmux_ls_output = tokio::process::Command::new("tmux")
@@ -287,7 +294,7 @@ async fn get_agent_locations(
287294
.filter_map(|s| {
288295
let segs: Vec<&str> = s.split_whitespace().collect();
289296
// Only fetch ones within the same tmux session
290-
if segs[0] != daemon_state.tmux_session_id {
297+
if segs[0] != tmux_session_id {
291298
return None;
292299
}
293300
segs[3].strip_prefix("/dev/").map(|stripped_tty| {

src/unix.rs

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
pub fn get_pid_file_path() -> String {
2-
let session_id = get_tmux_session_id();
2+
let session_id = get_tmux_session_id().unwrap();
33
// TODO: XDG_RUNTIME_DIR?
44
format!(
55
"/tmp/tmux-botdomo-{}-{}.pid",
@@ -9,26 +9,32 @@ pub fn get_pid_file_path() -> String {
99
}
1010

1111
pub fn get_socket_path() -> String {
12-
let session_id = get_tmux_session_id();
13-
std::env::var("TMUX_BOTDOMO_SOCK_PATH").unwrap_or(format!(
14-
"/tmp/tmux-botdomo-{}-{}.sock",
15-
std::env::var("USER").unwrap_or_else(|_| "unknown".to_string()),
16-
session_id,
17-
))
12+
std::env::var("TMUX_BOTDOMO_SOCK_PATH").unwrap_or_else(|_| {
13+
let session_id = get_tmux_session_id().unwrap();
14+
format!(
15+
"/tmp/tmux-botdomo-{}-{}.sock",
16+
std::env::var("USER").unwrap_or_else(|_| "unknown".to_string()),
17+
session_id,
18+
)
19+
})
1820
}
1921

2022
#[cfg(feature = "test-mode")]
21-
pub fn get_tmux_session_id() -> String {
22-
"test".to_string()
23+
pub fn get_tmux_session_id() -> Option<String> {
24+
Some("test".to_string())
2325
}
2426

27+
// Retrives the tmux session ID of the calling process is running on in.
2528
#[cfg(not(feature = "test-mode"))]
26-
pub fn get_tmux_session_id() -> String {
29+
pub fn get_tmux_session_id() -> Option<String> {
30+
if std::env::var("TMUX").is_err() {
31+
return None;
32+
}
33+
2734
std::process::Command::new("tmux")
2835
.args(["display-message", "-p", "#{session_id}"])
2936
.output()
3037
.ok()
3138
.and_then(|output| String::from_utf8(output.stdout).ok())
3239
.map(|s| s.trim().to_string())
33-
.unwrap_or("none".to_string())
3440
}

0 commit comments

Comments
 (0)