##// END OF EJS Templates
rust-chg: upgrade to futures-0.3 based libraries...
rust-chg: upgrade to futures-0.3 based libraries And do some trivial fixes: - BytesMut::put_u32_be() -> put_u32() - tokio_process -> tokio::process, CommandExt -> Command, spawn_async() -> spawn(), stdin() -> stdin - tokio_timer::sleep() -> tokio::time::delay_for() Differential Revision: https://phab.mercurial-scm.org/D8441

File last commit:

r45231:e9e44e61 default
r45231:e9e44e61 default
Show More
uihandler.rs
86 lines | 2.8 KiB | application/rls-services+xml | RustLexer
Yuya Nishihara
rust-chg: add callback to handle pager and shell command requests...
r40010 // Copyright 2018 Yuya Nishihara <yuya@tcha.org>
//
// This software may be used and distributed according to the terms of the
// GNU General Public License version 2 or any later version.
Gregory Szorc
rust: run rustfmt...
r44270 use futures::future::IntoFuture;
Yuya Nishihara
rust-chg: add callback to handle pager and shell command requests...
r40010 use futures::Future;
use std::io;
use std::os::unix::io::AsRawFd;
use std::os::unix::process::ExitStatusExt;
Yuya Nishihara
rust-chg: upgrade to futures-0.3 based libraries...
r45231 use std::process::Stdio;
Yuya Nishihara
rust-chg: add callback to handle pager and shell command requests...
r40010 use tokio;
Yuya Nishihara
rust-chg: upgrade to futures-0.3 based libraries...
r45231 use tokio::process::{ChildStdin, Command};
Yuya Nishihara
rust-chg: add callback to handle pager and shell command requests...
r40010
Yuya Nishihara
rust-chg: use "crate::" to import local modules...
r45180 use crate::message::CommandSpec;
use crate::procutil;
Yuya Nishihara
rust-chg: add callback to handle pager and shell command requests...
r40010
/// Callback to process shell command requests received from server.
pub trait SystemHandler: Sized {
type PagerStdin: AsRawFd;
type SpawnPagerResult: IntoFuture<Item = (Self, Self::PagerStdin), Error = io::Error>;
type RunSystemResult: IntoFuture<Item = (Self, i32), Error = io::Error>;
/// Handles pager command request.
///
/// Returns the pipe to be attached to the server if the pager is spawned.
fn spawn_pager(self, spec: CommandSpec) -> Self::SpawnPagerResult;
/// Handles system command request.
///
/// Returns command exit code (positive) or signal number (negative).
fn run_system(self, spec: CommandSpec) -> Self::RunSystemResult;
}
/// Default cHg implementation to process requests received from server.
Gregory Szorc
rust: run rustfmt...
r44270 pub struct ChgUiHandler {}
Yuya Nishihara
rust-chg: add callback to handle pager and shell command requests...
r40010
impl ChgUiHandler {
pub fn new() -> ChgUiHandler {
ChgUiHandler {}
}
}
impl SystemHandler for ChgUiHandler {
type PagerStdin = ChildStdin;
type SpawnPagerResult = io::Result<(Self, Self::PagerStdin)>;
type RunSystemResult = Box<dyn Future<Item = (Self, i32), Error = io::Error> + Send>;
fn spawn_pager(self, spec: CommandSpec) -> Self::SpawnPagerResult {
Yuya Nishihara
rust-chg: upgrade to futures-0.3 based libraries...
r45231 let mut pager = new_shell_command(&spec).stdin(Stdio::piped()).spawn()?;
let pin = pager.stdin.take().unwrap();
Yuya Nishihara
rust-chg: add callback to handle pager and shell command requests...
r40010 procutil::set_blocking_fd(pin.as_raw_fd())?;
Yuya Nishihara
rust-chg: remove SIGCHLD handler which won't work in oxidized chg...
r40155 // TODO: if pager exits, notify the server with SIGPIPE immediately.
// otherwise the server won't get SIGPIPE if it does not write
// anything. (issue5278)
// kill(peerpid, SIGPIPE);
Gregory Szorc
rust: run rustfmt...
r44270 tokio::spawn(pager.map(|_| ()).map_err(|_| ())); // just ignore errors
Yuya Nishihara
rust-chg: add callback to handle pager and shell command requests...
r40010 Ok((self, pin))
}
fn run_system(self, spec: CommandSpec) -> Self::RunSystemResult {
let fut = new_shell_command(&spec)
Yuya Nishihara
rust-chg: upgrade to futures-0.3 based libraries...
r45231 .spawn()
Yuya Nishihara
rust-chg: add callback to handle pager and shell command requests...
r40010 .into_future()
.flatten()
.map(|status| {
Gregory Szorc
rust: run rustfmt...
r44270 let code = status
.code()
.or_else(|| status.signal().map(|n| -n))
Yuya Nishihara
rust-chg: add callback to handle pager and shell command requests...
r40010 .expect("either exit code or signal should be set");
(self, code)
});
Box::new(fut)
}
}
fn new_shell_command(spec: &CommandSpec) -> Command {
let mut builder = Command::new("/bin/sh");
builder
.arg("-c")
.arg(&spec.command)
.current_dir(&spec.current_dir)
.env_clear()
.envs(spec.envs.iter().cloned());
builder
Gregory Szorc
rust: run rustfmt...
r44270 }