mirror of
https://github.com/wez/wezterm.git
synced 2024-11-27 12:23:46 +03:00
start a unix listener when running the mux server
This commit is contained in:
parent
0d51fd0e7d
commit
2b4b27c9c0
@ -4,6 +4,7 @@ use crate::font::FontConfiguration;
|
||||
use crate::frontend::FrontEnd;
|
||||
use crate::mux::tab::Tab;
|
||||
use crate::mux::Mux;
|
||||
use crate::server::listener::spawn_listener;
|
||||
use failure::Error;
|
||||
use promise::Executor;
|
||||
use promise::SpawnFunc;
|
||||
@ -33,8 +34,9 @@ pub struct MuxServerFrontEnd {
|
||||
}
|
||||
|
||||
impl MuxServerFrontEnd {
|
||||
pub fn try_new(_mux: &Rc<Mux>) -> Result<Rc<FrontEnd>, Error> {
|
||||
pub fn try_new(mux: &Rc<Mux>) -> Result<Rc<FrontEnd>, Error> {
|
||||
let (tx, rx) = mpsc::sync_channel(4);
|
||||
spawn_listener(mux.config(), Box::new(MuxExecutor { tx: tx.clone() }))?;
|
||||
Ok(Rc::new(Self { tx, rx }))
|
||||
}
|
||||
}
|
||||
@ -61,6 +63,7 @@ impl FrontEnd for MuxServerFrontEnd {
|
||||
_fontconfig: &Rc<FontConfiguration>,
|
||||
_tab: &Rc<Tab>,
|
||||
) -> Result<(), Error> {
|
||||
unimplemented!();
|
||||
// The tab was already added to the mux, so we are a NOP
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -1,36 +1,147 @@
|
||||
use crate::config::Config;
|
||||
use crate::server::{UnixListener, UnixStream};
|
||||
use failure::Error;
|
||||
use failure::{err_msg, Error};
|
||||
#[cfg(unix)]
|
||||
use libc::{mode_t, umask};
|
||||
use promise::Executor;
|
||||
use std::fs::{remove_file, DirBuilder};
|
||||
use std::io::{Read, Write};
|
||||
#[cfg(unix)]
|
||||
use std::os::unix::fs::{DirBuilderExt, PermissionsExt};
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
use std::thread;
|
||||
|
||||
pub trait SocketLike: Read + Write + Send {}
|
||||
|
||||
pub trait Acceptor {
|
||||
fn accept(&self) -> Result<Box<SocketLike>, Error>;
|
||||
}
|
||||
|
||||
impl SocketLike for UnixStream {}
|
||||
|
||||
impl Acceptor for UnixListener {
|
||||
fn accept(&self) -> Result<Box<SocketLike>, Error> {
|
||||
let (stream, _addr) = UnixListener::accept(self)?;
|
||||
#[cfg(unix)]
|
||||
{
|
||||
let timeout = std::time::Duration::new(60, 0);
|
||||
stream.set_read_timeout(Some(timeout))?;
|
||||
stream.set_write_timeout(Some(timeout))?;
|
||||
}
|
||||
Ok(Box::new(stream))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Listener {
|
||||
acceptor: Box<Acceptor>,
|
||||
acceptor: UnixListener,
|
||||
executor: Box<Executor>,
|
||||
}
|
||||
|
||||
impl Listener {
|
||||
pub fn new(acceptor: Box<Acceptor>) -> Self {
|
||||
Self { acceptor }
|
||||
pub fn new(acceptor: UnixListener, executor: Box<Executor>) -> Self {
|
||||
Self { acceptor, executor }
|
||||
}
|
||||
|
||||
fn run(&mut self) {
|
||||
for stream in self.acceptor.incoming() {
|
||||
match stream {
|
||||
Ok(stream) => {
|
||||
let executor = self.executor.clone_executor();
|
||||
let mut session = ClientSession::new(stream, executor);
|
||||
thread::spawn(move || session.run());
|
||||
}
|
||||
Err(err) => {
|
||||
eprintln!("accept failed: {}", err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ClientSession {}
|
||||
pub struct ClientSession {
|
||||
stream: UnixStream,
|
||||
executor: Box<Executor>,
|
||||
}
|
||||
|
||||
impl ClientSession {
|
||||
fn new(stream: UnixStream, executor: Box<Executor>) -> Self {
|
||||
Self { stream, executor }
|
||||
}
|
||||
|
||||
fn run(&mut self) {}
|
||||
}
|
||||
|
||||
/// Unfortunately, novice unix users can sometimes be running
|
||||
/// with an overly permissive umask so we take care to install
|
||||
/// a more restrictive mask while we might be creating things
|
||||
/// in the filesystem.
|
||||
/// This struct locks down the umask for its lifetime, restoring
|
||||
/// the prior umask when it is dropped.
|
||||
struct UmaskSaver {
|
||||
#[cfg(unix)]
|
||||
mask: mode_t,
|
||||
}
|
||||
|
||||
impl UmaskSaver {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
#[cfg(unix)]
|
||||
mask: unsafe { umask(0o077) },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for UmaskSaver {
|
||||
fn drop(&mut self) {
|
||||
#[cfg(unix)]
|
||||
unsafe {
|
||||
umask(self.mask);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Take care when setting up the listener socket;
|
||||
/// we need to be sure that the directory that we create it in
|
||||
/// is owned by the user and has appropriate file permissions
|
||||
/// that prevent other users from manipulating its contents.
|
||||
fn safely_create_sock_path(sock_path: &String) -> Result<UnixListener, Error> {
|
||||
let sock_path = Path::new(sock_path);
|
||||
|
||||
eprintln!("setting up {}", sock_path.display());
|
||||
|
||||
let _saver = UmaskSaver::new();
|
||||
|
||||
let sock_dir = sock_path
|
||||
.parent()
|
||||
.ok_or_else(|| format_err!("sock_path {} has no parent dir", sock_path.display()))?;
|
||||
|
||||
let mut builder = DirBuilder::new();
|
||||
builder.recursive(true);
|
||||
|
||||
#[cfg(unix)]
|
||||
{
|
||||
builder.mode(0o700);
|
||||
}
|
||||
|
||||
builder.create(sock_dir)?;
|
||||
|
||||
// Let's be sure that the ownership looks sane
|
||||
let meta = sock_dir.symlink_metadata()?;
|
||||
|
||||
#[cfg(unix)]
|
||||
{
|
||||
let permissions = meta.permissions();
|
||||
if (permissions.mode() & 0o22) != 0 {
|
||||
bail!(
|
||||
"The permissions for {} are insecure and currently
|
||||
allow other users to write to it (permissions={:?})",
|
||||
sock_dir.display(),
|
||||
permissions
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if sock_path.exists() {
|
||||
remove_file(sock_path)?;
|
||||
}
|
||||
|
||||
UnixListener::bind(sock_path)
|
||||
.map_err(|e| format_err!("Failed to bind to {}: {}", sock_path.display(), e))
|
||||
}
|
||||
|
||||
pub fn spawn_listener(config: &Arc<Config>, executor: Box<Executor>) -> Result<(), Error> {
|
||||
let sock_path = config
|
||||
.mux_server_unix_domain_socket_path
|
||||
.as_ref()
|
||||
.ok_or_else(|| err_msg("no mux_server_unix_domain_socket_path"))?;
|
||||
let mut listener = Listener::new(safely_create_sock_path(sock_path)?, executor);
|
||||
thread::spawn(move || {
|
||||
listener.run();
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
#[cfg(unix)]
|
||||
use std::os::unix::net::{SocketAddr, UnixListener, UnixStream};
|
||||
use std::os::unix::net::{UnixListener, UnixStream};
|
||||
#[cfg(windows)]
|
||||
use uds_windows::{SocketAddr, UnixListener, UnixStream};
|
||||
use uds_windows::{UnixListener, UnixStream};
|
||||
|
||||
pub mod client;
|
||||
pub mod listener;
|
||||
|
Loading…
Reference in New Issue
Block a user