summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/main.rs61
-rw-r--r--src/sessions.rs13
-rw-r--r--zellij-server/src/lib.rs10
-rw-r--r--zellij-server/src/route.rs3
-rw-r--r--zellij-utils/src/cli.rs15
-rw-r--r--zellij-utils/src/errors.rs1
-rw-r--r--zellij-utils/src/ipc.rs1
7 files changed, 102 insertions, 2 deletions
diff --git a/src/main.rs b/src/main.rs
index 90eeb96b2..70734ae4f 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -5,8 +5,8 @@ mod tests;
use crate::install::populate_data_dir;
use sessions::{
- assert_session, assert_session_ne, get_active_session, get_sessions, list_sessions,
- print_sessions, session_exists, ActiveSession,
+ assert_session, assert_session_ne, get_active_session, get_sessions, kill_session,
+ list_sessions, print_sessions, session_exists, ActiveSession,
};
use std::process;
use zellij_client::{os_input_output::get_client_os_input, start_client, ClientInfo};
@@ -27,6 +27,63 @@ pub fn main() {
list_sessions();
}
+ if let Some(Command::Sessions(Sessions::KillAllSessions { yes })) = opts.command {
+ match get_sessions() {
+ Ok(sessions) => {
+ if sessions.is_empty() {
+ println!("No active zellij sessions found.");
+ process::exit(1);
+ } else {
+ let kill_all_sessions = |sessions: Vec<std::string::String>| {
+ for session in sessions.iter() {
+ kill_session(session);
+ }
+ process::exit(0)
+ };
+
+ if yes {
+ kill_all_sessions(sessions);
+ } else {
+ use std::io::{stdin, stdout, Write};
+
+ let mut answer = String::new();
+ println!("WARNING: this action will kill all sessions.");
+ print!("Do you want to continue? [y/N] ");
+ let _ = stdout().flush();
+ stdin().read_line(&mut answer).unwrap();
+
+ match answer.as_str().trim() {
+ "y" | "Y" | "yes" | "Yes" => kill_all_sessions(sessions),
+ _ => {
+ println!("Abort.");
+ process::exit(1);
+ }
+ }
+ }
+ }
+ }
+ Err(e) => {
+ eprintln!("Error occured: {:?}", e);
+ process::exit(1);
+ }
+ }
+ }
+
+ if let Some(Command::Sessions(Sessions::KillSession { target_session })) = opts.command.clone()
+ {
+ match target_session.as_ref() {
+ Some(target_session) => {
+ assert_session(target_session);
+ kill_session(target_session);
+ process::exit(0);
+ }
+ None => {
+ println!("Please specify the session name to kill.");
+ process::exit(1);
+ }
+ }
+ }
+
atomic_create_dir(&*ZELLIJ_TMP_DIR).unwrap();
atomic_create_dir(&*ZELLIJ_TMP_LOG_DIR).unwrap();
if let Some(path) = opts.server {
diff --git a/src/sessions.rs b/src/sessions.rs
index 9f1e20f0a..c2d8afea4 100644
--- a/src/sessions.rs
+++ b/src/sessions.rs
@@ -84,6 +84,19 @@ pub(crate) fn get_active_session() -> ActiveSession {
}
}
+pub(crate) fn kill_session(name: &str) {
+ let path = &*ZELLIJ_SOCK_DIR.join(name);
+ match LocalSocketStream::connect(path) {
+ Ok(stream) => {
+ IpcSenderWithContext::new(stream).send(ClientToServerMsg::KillSession);
+ }
+ Err(e) => {
+ eprintln!("Error occured: {:?}", e);
+ process::exit(1);
+ }
+ };
+}
+
pub(crate) fn list_sessions() {
let exit_code = match get_sessions() {
Ok(sessions) => {
diff --git a/zellij-server/src/lib.rs b/zellij-server/src/lib.rs
index 5ba049097..2e1b901d7 100644
--- a/zellij-server/src/lib.rs
+++ b/zellij-server/src/lib.rs
@@ -65,6 +65,7 @@ pub(crate) enum ServerInstruction {
ClientExit(ClientId),
RemoveClient(ClientId),
Error(String),
+ KillSession,
DetachSession(ClientId),
AttachClient(ClientAttributes, Options, ClientId),
}
@@ -78,6 +79,7 @@ impl From<&ServerInstruction> for ServerContext {
ServerInstruction::ClientExit(..) => ServerContext::ClientExit,
ServerInstruction::RemoveClient(..) => ServerContext::RemoveClient,
ServerInstruction::Error(_) => ServerContext::Error,
+ ServerInstruction::KillSession => ServerContext::KillSession,
ServerInstruction::DetachSession(..) => ServerContext::DetachSession,
ServerInstruction::AttachClient(..) => ServerContext::AttachClient,
}
@@ -400,6 +402,14 @@ pub fn start_server(mut os_input: Box<dyn ServerOsApi>, socket_path: PathBuf) {
.unwrap();
}
}
+ ServerInstruction::KillSession => {
+ let client_ids = session_state.read().unwrap().client_ids();
+ for client_id in client_ids {
+ os_input.send_to_client(client_id, ServerToClientMsg::Exit(ExitReason::Normal));
+ remove_client!(client_id, os_input, session_state);
+ }
+ break;
+ }
ServerInstruction::DetachSession(client_id) => {
os_input.send_to_client(client_id, ServerToClientMsg::Exit(ExitReason::Normal));
remove_client!(client_id, os_input, session_state);
diff --git a/zellij-server/src/route.rs b/zellij-server/src/route.rs
index 4a22b5c5c..fa659faa6 100644
--- a/zellij-server/src/route.rs
+++ b/zellij-server/src/route.rs
@@ -358,6 +358,9 @@ pub(crate) fn route_thread_main(
let _ = to_server.send(ServerInstruction::RemoveClient(client_id));
break;
}
+ ClientToServerMsg::KillSession => {
+ to_server.send(ServerInstruction::KillSession).unwrap();
+ }
}
}
}
diff --git a/zellij-utils/src/cli.rs b/zellij-utils/src/cli.rs
index 452033b8a..7ac9e958c 100644
--- a/zellij-utils/src/cli.rs
+++ b/zellij-utils/src/cli.rs
@@ -89,4 +89,19 @@ pub enum Sessions {
#[structopt(subcommand, name = "options")]
options: Option<SessionCommand>,
},
+
+ /// Kill the specific session
+ #[structopt(alias = "k")]
+ KillSession {
+ /// Name of target session
+ target_session: Option<String>,
+ },
+
+ /// Kill all sessions
+ #[structopt(alias = "ka")]
+ KillAllSessions {
+ /// Automatic yes to prompts
+ #[structopt(short, long)]
+ yes: bool,
+ },
}
diff --git a/zellij-utils/src/errors.rs b/zellij-utils/src/errors.rs
index 348e6013a..1859a9042 100644
--- a/zellij-utils/src/errors.rs
+++ b/zellij-utils/src/errors.rs
@@ -304,6 +304,7 @@ pub enum ServerContext {
ClientExit,
RemoveClient,
Error,
+ KillSession,
DetachSession,
AttachClient,
}
diff --git a/zellij-utils/src/ipc.rs b/zellij-utils/src/ipc.rs
index 5c327022f..995b89fb4 100644
--- a/zellij-utils/src/ipc.rs
+++ b/zellij-utils/src/ipc.rs
@@ -68,6 +68,7 @@ pub enum ClientToServerMsg {
AttachClient(ClientAttributes, Options),
Action(Action),
ClientExited,
+ KillSession,
}
// Types of messages sent from the server to the client