aboutsummaryrefslogtreecommitdiffstats
path: root/src/common
diff options
context:
space:
mode:
authora-kenji <aks.kenji@protonmail.com>2021-05-16 12:44:56 +0200
committera-kenji <aks.kenji@protonmail.com>2021-05-16 12:44:56 +0200
commit197f31875646a5b78abd23edecee072931b2b14b (patch)
treea8fb17d057d77c0a5090c5e1878ecd5618ec592d /src/common
parentSplit Layout Flag (diff)
parentDocs(changelog): Multiprocess model #499 (diff)
downloadsl0ppij-197f31875646a5b78abd23edecee072931b2b14b.tar.gz
sl0ppij-197f31875646a5b78abd23edecee072931b2b14b.tar.xz
sl0ppij-197f31875646a5b78abd23edecee072931b2b14b.zip
Merge branch 'main' of https://github.com/zellij-org/zellij into layout-path-506
Diffstat (limited to 'src/common')
-rw-r--r--src/common/errors.rs40
-rw-r--r--src/common/input/handler.rs8
-rw-r--r--src/common/ipc.rs32
-rw-r--r--src/common/os_input_output.rs67
-rw-r--r--src/common/pty.rs4
-rw-r--r--src/common/screen.rs4
-rw-r--r--src/common/utils/consts.rs4
-rw-r--r--src/common/wasm_vm.rs4
8 files changed, 100 insertions, 63 deletions
diff --git a/src/common/errors.rs b/src/common/errors.rs
index c2caf19d..262dfd6b 100644
--- a/src/common/errors.rs
+++ b/src/common/errors.rs
@@ -19,12 +19,29 @@ const MAX_THREAD_CALL_STACK: usize = 6;
use super::thread_bus::SenderWithContext;
#[cfg(not(test))]
use std::panic::PanicInfo;
+
+pub trait ErrorInstruction {
+ fn error(err: String) -> Self;
+}
+
+impl ErrorInstruction for ClientInstruction {
+ fn error(err: String) -> Self {
+ ClientInstruction::Error(err)
+ }
+}
+
+impl ErrorInstruction for ServerInstruction {
+ fn error(err: String) -> Self {
+ ServerInstruction::Error(err)
+ }
+}
+
/// Custom panic handler/hook. Prints the [`ErrorContext`].
#[cfg(not(test))]
-pub fn handle_panic(
- info: &PanicInfo<'_>,
- send_app_instructions: &SenderWithContext<ClientInstruction>,
-) {
+pub fn handle_panic<T>(info: &PanicInfo<'_>, sender: &SenderWithContext<T>)
+where
+ T: ErrorInstruction + Clone,
+{
use backtrace::Backtrace;
use std::{process, thread};
let backtrace = Backtrace::new();
@@ -70,7 +87,7 @@ pub fn handle_panic(
println!("{}", backtrace);
process::exit(1);
} else {
- let _ = send_app_instructions.send(ClientInstruction::Error(backtrace));
+ let _ = sender.send(T::error(backtrace));
}
}
@@ -103,6 +120,11 @@ impl ErrorContext {
break;
}
}
+ self.update_thread_ctx()
+ }
+
+ /// Updates the thread local [`ErrorContext`].
+ pub fn update_thread_ctx(&self) {
ASYNCOPENCALLS
.try_with(|ctx| *ctx.borrow_mut() = *self)
.unwrap_or_else(|_| OPENCALLS.with(|ctx| *ctx.borrow_mut() = *self));
@@ -333,6 +355,7 @@ pub enum ClientContext {
Error,
UnblockInputThread,
Render,
+ ServerError,
}
impl From<&ClientInstruction> for ClientContext {
@@ -340,6 +363,7 @@ impl From<&ClientInstruction> for ClientContext {
match *client_instruction {
ClientInstruction::Exit => ClientContext::Exit,
ClientInstruction::Error(_) => ClientContext::Error,
+ ClientInstruction::ServerError(_) => ClientContext::ServerError,
ClientInstruction::Render(_) => ClientContext::Render,
ClientInstruction::UnblockInputThread => ClientContext::UnblockInputThread,
}
@@ -350,22 +374,20 @@ impl From<&ClientInstruction> for ClientContext {
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
pub enum ServerContext {
NewClient,
- Action,
Render,
- TerminalResize,
UnblockInputThread,
ClientExit,
+ Error,
}
impl From<&ServerInstruction> for ServerContext {
fn from(server_instruction: &ServerInstruction) -> Self {
match *server_instruction {
ServerInstruction::NewClient(..) => ServerContext::NewClient,
- ServerInstruction::Action(_) => ServerContext::Action,
- ServerInstruction::TerminalResize(_) => ServerContext::TerminalResize,
ServerInstruction::Render(_) => ServerContext::Render,
ServerInstruction::UnblockInputThread => ServerContext::UnblockInputThread,
ServerInstruction::ClientExit => ServerContext::ClientExit,
+ ServerInstruction::Error(_) => ServerContext::Error,
}
}
}
diff --git a/src/common/input/handler.rs b/src/common/input/handler.rs
index b2f4d0a3..4ac2cf83 100644
--- a/src/common/input/handler.rs
+++ b/src/common/input/handler.rs
@@ -4,10 +4,10 @@ use super::actions::Action;
use super::keybinds::Keybinds;
use crate::client::ClientInstruction;
use crate::common::input::config::Config;
+use crate::common::ipc::ClientToServerMsg;
use crate::common::thread_bus::{SenderWithContext, OPENCALLS};
use crate::errors::ContextType;
use crate::os_input_output::ClientOsApi;
-use crate::server::ServerInstruction;
use crate::CommandIsExecuting;
use termion::input::{TermRead, TermReadEventsAndRaw};
@@ -139,7 +139,7 @@ impl InputHandler {
Action::SwitchToMode(mode) => {
self.mode = mode;
self.os_input
- .send_to_server(ServerInstruction::Action(action));
+ .send_to_server(ClientToServerMsg::Action(action));
}
Action::CloseFocus
| Action::NewPane(_)
@@ -151,13 +151,13 @@ impl InputHandler {
| Action::MoveFocusOrTab(_) => {
self.command_is_executing.blocking_input_thread();
self.os_input
- .send_to_server(ServerInstruction::Action(action));
+ .send_to_server(ClientToServerMsg::Action(action));
self.command_is_executing
.wait_until_input_thread_is_unblocked();
}
_ => self
.os_input
- .send_to_server(ServerInstruction::Action(action)),
+ .send_to_server(ClientToServerMsg::Action(action)),
}
should_break
diff --git a/src/common/ipc.rs b/src/common/ipc.rs
index 190680dc..129727a1 100644
--- a/src/common/ipc.rs
+++ b/src/common/ipc.rs
@@ -1,10 +1,14 @@
//! IPC stuff for starting to split things into a client and server model.
-use crate::common::errors::{get_current_ctx, ErrorContext};
+use crate::cli::CliArgs;
+use crate::common::{
+ errors::{get_current_ctx, ErrorContext},
+ input::{actions::Action, options::Options},
+};
+use crate::panes::PositionAndSize;
use interprocess::local_socket::LocalSocketStream;
use nix::unistd::dup;
use serde::{Deserialize, Serialize};
-use std::collections::HashSet;
use std::io::{self, Write};
use std::marker::PhantomData;
use std::os::unix::io::{AsRawFd, FromRawFd};
@@ -29,9 +33,9 @@ pub enum ClientType {
}
// Types of messages sent from the client to the server
-#[derive(Serialize, Deserialize)]
-pub enum _ClientToServerMsg {
- // List which sessions are available
+#[derive(Serialize, Deserialize, Debug, Clone)]
+pub enum ClientToServerMsg {
+ /*// List which sessions are available
ListSessions,
// Create a new session
CreateSession,
@@ -40,16 +44,24 @@ pub enum _ClientToServerMsg {
// Force detach
DetachSession(SessionId),
// Disconnect from the session we're connected to
- DisconnectFromSession,
+ DisconnectFromSession,*/
+ ClientExit,
+ TerminalResize(PositionAndSize),
+ NewClient(PositionAndSize, CliArgs, Options),
+ Action(Action),
}
// Types of messages sent from the server to the client
-// @@@ Implement Serialize and Deserialize for this...
-pub enum _ServerToClientMsg {
- // Info about a particular session
+#[derive(Serialize, Deserialize, Debug, Clone)]
+pub enum ServerToClientMsg {
+ /*// Info about a particular session
SessionInfo(Session),
// A list of sessions
- SessionList(HashSet<Session>),
+ SessionList(HashSet<Session>),*/
+ Render(Option<String>),
+ UnblockInputThread,
+ Exit,
+ ServerError(String),
}
/// Sends messages on a stream socket, along with an [`ErrorContext`].
diff --git a/src/common/os_input_output.rs b/src/common/os_input_output.rs
index 6f891e0d..adde6fdf 100644
--- a/src/common/os_input_output.rs
+++ b/src/common/os_input_output.rs
@@ -1,11 +1,8 @@
-use crate::client::ClientInstruction;
-use crate::common::{
- ipc::{IpcReceiverWithContext, IpcSenderWithContext},
- utils::consts::ZELLIJ_IPC_PIPE,
+use crate::common::ipc::{
+ ClientToServerMsg, IpcReceiverWithContext, IpcSenderWithContext, ServerToClientMsg,
};
use crate::errors::ErrorContext;
use crate::panes::PositionAndSize;
-use crate::server::ServerInstruction;
use crate::utils::shared::default_palette;
use interprocess::local_socket::LocalSocketStream;
use nix::fcntl::{fcntl, FcntlArg, OFlag};
@@ -170,8 +167,8 @@ fn spawn_terminal(file_to_open: Option<PathBuf>, orig_termios: termios::Termios)
#[derive(Clone)]
pub struct ServerOsInputOutput {
orig_termios: Arc<Mutex<termios::Termios>>,
- receive_instructions_from_client: Option<Arc<Mutex<IpcReceiverWithContext<ServerInstruction>>>>,
- send_instructions_to_client: Arc<Mutex<Option<IpcSenderWithContext<ClientInstruction>>>>,
+ receive_instructions_from_client: Option<Arc<Mutex<IpcReceiverWithContext<ClientToServerMsg>>>>,
+ send_instructions_to_client: Arc<Mutex<Option<IpcSenderWithContext<ServerToClientMsg>>>>,
}
/// The `ServerOsApi` trait represents an abstract interface to the features of an operating system that
@@ -195,9 +192,9 @@ pub trait ServerOsApi: Send + Sync {
/// Returns a [`Box`] pointer to this [`ServerOsApi`] struct.
fn box_clone(&self) -> Box<dyn ServerOsApi>;
/// Receives a message on server-side IPC channel
- fn recv_from_client(&self) -> (ServerInstruction, ErrorContext);
+ fn recv_from_client(&self) -> (ClientToServerMsg, ErrorContext);
/// Sends a message to client
- fn send_to_client(&self, msg: ClientInstruction);
+ fn send_to_client(&self, msg: ServerToClientMsg);
/// Adds a sender to client
fn add_client_sender(&mut self);
/// Update the receiver socket for the client
@@ -236,7 +233,7 @@ impl ServerOsApi for ServerOsInputOutput {
waitpid(Pid::from_raw(pid), None).unwrap();
Ok(())
}
- fn recv_from_client(&self) -> (ServerInstruction, ErrorContext) {
+ fn recv_from_client(&self) -> (ClientToServerMsg, ErrorContext) {
self.receive_instructions_from_client
.as_ref()
.unwrap()
@@ -244,7 +241,7 @@ impl ServerOsApi for ServerOsInputOutput {
.unwrap()
.recv()
}
- fn send_to_client(&self, msg: ClientInstruction) {
+ fn send_to_client(&self, msg: ServerToClientMsg) {
self.send_instructions_to_client
.lock()
.unwrap()
@@ -291,8 +288,8 @@ pub fn get_server_os_input() -> ServerOsInputOutput {
#[derive(Clone)]
pub struct ClientOsInputOutput {
orig_termios: Arc<Mutex<termios::Termios>>,
- send_instructions_to_server: Arc<Mutex<Option<IpcSenderWithContext<ServerInstruction>>>>,
- receive_instructions_from_server: Arc<Mutex<Option<IpcReceiverWithContext<ClientInstruction>>>>,
+ send_instructions_to_server: Arc<Mutex<Option<IpcSenderWithContext<ClientToServerMsg>>>>,
+ receive_instructions_from_server: Arc<Mutex<Option<IpcReceiverWithContext<ServerToClientMsg>>>>,
}
/// The `ClientOsApi` trait represents an abstract interface to the features of an operating system that
@@ -305,7 +302,7 @@ pub trait ClientOsApi: Send + Sync {
fn set_raw_mode(&mut self, fd: RawFd);
/// Set the terminal associated to file descriptor `fd` to
/// [cooked mode](https://en.wikipedia.org/wiki/Terminal_mode).
- fn unset_raw_mode(&mut self, fd: RawFd);
+ fn unset_raw_mode(&self, fd: RawFd);
/// Returns the writer that allows writing to standard output.
fn get_stdout_writer(&self) -> Box<dyn io::Write>;
/// Returns the raw contents of standard input.
@@ -313,13 +310,13 @@ pub trait ClientOsApi: Send + Sync {
/// Returns a [`Box`] pointer to this [`ClientOsApi`] struct.
fn box_clone(&self) -> Box<dyn ClientOsApi>;
/// Sends a message to the server.
- fn send_to_server(&self, msg: ServerInstruction);
+ fn send_to_server(&self, msg: ClientToServerMsg);
/// Receives a message on client-side IPC channel
// This should be called from the client-side router thread only.
- fn recv_from_server(&self) -> (ClientInstruction, ErrorContext);
- fn receive_sigwinch(&self, cb: Box<dyn Fn()>);
+ fn recv_from_server(&self) -> (ServerToClientMsg, ErrorContext);
+ fn handle_signals(&self, sigwinch_cb: Box<dyn Fn()>, quit_cb: Box<dyn Fn()>);
/// Establish a connection with the server socket.
- fn connect_to_server(&self);
+ fn connect_to_server(&self, path: &Path);
}
impl ClientOsApi for ClientOsInputOutput {
@@ -329,7 +326,7 @@ impl ClientOsApi for ClientOsInputOutput {
fn set_raw_mode(&mut self, fd: RawFd) {
into_raw_mode(fd);
}
- fn unset_raw_mode(&mut self, fd: RawFd) {
+ fn unset_raw_mode(&self, fd: RawFd) {
let orig_termios = self.orig_termios.lock().unwrap();
unset_raw_mode(fd, orig_termios.clone());
}
@@ -349,7 +346,7 @@ impl ClientOsApi for ClientOsInputOutput {
let stdout = ::std::io::stdout();
Box::new(stdout)
}
- fn send_to_server(&self, msg: ServerInstruction) {
+ fn send_to_server(&self, msg: ClientToServerMsg) {
self.send_instructions_to_server
.lock()
.unwrap()
@@ -357,7 +354,7 @@ impl ClientOsApi for ClientOsInputOutput {
.unwrap()
.send(msg);
}
- fn recv_from_server(&self) -> (ClientInstruction, ErrorContext) {
+ fn recv_from_server(&self) -> (ServerToClientMsg, ErrorContext) {
self.receive_instructions_from_server
.lock()
.unwrap()
@@ -365,28 +362,34 @@ impl ClientOsApi for ClientOsInputOutput {
.unwrap()
.recv()
}
- fn receive_sigwinch(&self, cb: Box<dyn Fn()>) {
- let mut signals = Signals::new(&[SIGWINCH, SIGTERM, SIGINT, SIGQUIT]).unwrap();
+ fn handle_signals(&self, sigwinch_cb: Box<dyn Fn()>, quit_cb: Box<dyn Fn()>) {
+ let mut signals = Signals::new(&[SIGWINCH, SIGTERM, SIGINT, SIGQUIT, SIGHUP]).unwrap();
for signal in signals.forever() {
match signal {
SIGWINCH => {
- cb();
+ sigwinch_cb();
}
- SIGTERM | SIGINT | SIGQUIT => {
+ SIGTERM | SIGINT | SIGQUIT | SIGHUP => {
+ quit_cb();
break;
}
_ => unreachable!(),
}
}
}
- fn connect_to_server(&self) {
- let socket = match LocalSocketStream::connect(&**ZELLIJ_IPC_PIPE) {
- Ok(sock) => sock,
- Err(_) => {
- std::thread::sleep(std::time::Duration::from_millis(20));
- LocalSocketStream::connect(&**ZELLIJ_IPC_PIPE).unwrap()
+ fn connect_to_server(&self, path: &Path) {
+ let socket;
+ loop {
+ match LocalSocketStream::connect(path) {
+ Ok(sock) => {
+ socket = sock;
+ break;
+ }
+ Err(_) => {
+ std::thread::sleep(std::time::Duration::from_millis(50));
+ }
}
- };
+ }
let sender = IpcSenderWithContext::new(socket);
let receiver = sender.get_receiver();
*self.send_instructions_to_server.lock().unwrap() = Some(sender);
diff --git a/src/common/pty.rs b/src/common/pty.rs
index 3c471d6a..5f5442b5 100644
--- a/src/common/pty.rs
+++ b/src/common/pty.rs
@@ -8,7 +8,7 @@ use std::pin::*;
use std::time::{Duration, Instant};
use crate::client::panes::PaneId;
-use crate::common::errors::{get_current_ctx, ContextType, PtyContext};
+use crate::common::errors::{get_current_ctx, ContextType};
use crate::common::screen::ScreenInstruction;
use crate::common::thread_bus::{Bus, ThreadSenders};
use crate::layout::Layout;
@@ -87,7 +87,7 @@ pub struct Pty {
pub fn pty_thread_main(mut pty: Pty, maybe_layout: Option<Layout>) {
loop {
let (event, mut err_ctx) = pty.bus.recv().expect("failed to receive event on channel");
- err_ctx.add_call(ContextType::Pty(PtyContext::from(&event)));
+ err_ctx.add_call(ContextType::Pty((&event).into()));
match event {
PtyInstruction::SpawnTerminal(file_to_open) => {
let pid = pty.spawn_terminal(file_to_open);
diff --git a/src/common/screen.rs b/src/common/screen.rs
index bc99f953..62fcec19 100644
--- a/src/common/screen.rs
+++ b/src/common/screen.rs
@@ -7,7 +7,7 @@ use std::str;
use crate::common::input::options::Options;
use crate::common::pty::{PtyInstruction, VteBytes};
use crate::common::thread_bus::Bus;
-use crate::errors::{ContextType, ScreenContext};
+use crate::errors::ContextType;
use crate::layout::Layout;
use crate::panes::PaneId;
use crate::panes::PositionAndSize;
@@ -353,7 +353,7 @@ pub fn screen_thread_main(
.bus
.recv()
.expect("failed to receive event on channel");
- err_ctx.add_call(ContextType::Screen(ScreenContext::from(&event)));
+ err_ctx.add_call(ContextType::Screen((&event).into()));
match event {
ScreenInstruction::PtyBytes(pid, vte_bytes) => {
let active_tab = screen.get_active_tab_mut().unwrap();
diff --git a/src/common/utils/consts.rs b/src/common/utils/consts.rs
index 479405c3..42843eb8 100644
--- a/src/common/utils/consts.rs
+++ b/src/common/utils/consts.rs
@@ -49,6 +49,6 @@ lazy_static! {
}
pub const FEATURES: &[&str] = &[
- #[cfg(feature = "enable_automatic_asset_installation")]
- "enable_automatic_asset_installation",
+ #[cfg(feature = "disable_automatic_asset_installation")]
+ "disable_automatic_asset_installation",
];
diff --git a/src/common/wasm_vm.rs b/src/common/wasm_vm.rs
index e5567285..51eb4ed8 100644
--- a/src/common/wasm_vm.rs
+++ b/src/common/wasm_vm.rs
@@ -15,7 +15,7 @@ use wasmer::{
use wasmer_wasi::{Pipe, WasiEnv, WasiState};
use zellij_tile::data::{Event, EventType, PluginIds};
-use crate::common::errors::{ContextType, PluginContext};
+use crate::common::errors::ContextType;
use crate::common::pty::PtyInstruction;
use crate::common::screen::ScreenInstruction;
use crate::common::thread_bus::{Bus, ThreadSenders};
@@ -44,7 +44,7 @@ pub fn wasm_thread_main(bus: Bus<PluginInstruction>, store: Store, data_dir: Pat
let mut plugin_map = HashMap::new();
loop {
let (event, mut err_ctx) = bus.recv().expect("failed to receive event on channel");
- err_ctx.add_call(ContextType::Plugin(PluginContext::from(&event)));
+ err_ctx.add_call(ContextType::Plugin((&event).into()));
match event {
PluginInstruction::Load(pid_tx, path) => {
let plugin_dir = data_dir.join("plugins/");