equal
deleted
inserted
replaced
1 // Copyright 2018 Yuya Nishihara <yuya@tcha.org> |
1 // Copyright 2018 Yuya Nishihara <yuya@tcha.org> |
2 // |
2 // |
3 // This software may be used and distributed according to the terms of the |
3 // This software may be used and distributed according to the terms of the |
4 // GNU General Public License version 2 or any later version. |
4 // GNU General Public License version 2 or any later version. |
5 |
5 |
|
6 use futures::future::IntoFuture; |
6 use futures::Future; |
7 use futures::Future; |
7 use futures::future::IntoFuture; |
|
8 use std::io; |
8 use std::io; |
9 use std::os::unix::io::AsRawFd; |
9 use std::os::unix::io::AsRawFd; |
10 use std::os::unix::process::ExitStatusExt; |
10 use std::os::unix::process::ExitStatusExt; |
11 use std::process::{Command, Stdio}; |
11 use std::process::{Command, Stdio}; |
12 use tokio; |
12 use tokio; |
31 /// Returns command exit code (positive) or signal number (negative). |
31 /// Returns command exit code (positive) or signal number (negative). |
32 fn run_system(self, spec: CommandSpec) -> Self::RunSystemResult; |
32 fn run_system(self, spec: CommandSpec) -> Self::RunSystemResult; |
33 } |
33 } |
34 |
34 |
35 /// Default cHg implementation to process requests received from server. |
35 /// Default cHg implementation to process requests received from server. |
36 pub struct ChgUiHandler { |
36 pub struct ChgUiHandler {} |
37 } |
|
38 |
37 |
39 impl ChgUiHandler { |
38 impl ChgUiHandler { |
40 pub fn new() -> ChgUiHandler { |
39 pub fn new() -> ChgUiHandler { |
41 ChgUiHandler {} |
40 ChgUiHandler {} |
42 } |
41 } |
55 procutil::set_blocking_fd(pin.as_raw_fd())?; |
54 procutil::set_blocking_fd(pin.as_raw_fd())?; |
56 // TODO: if pager exits, notify the server with SIGPIPE immediately. |
55 // TODO: if pager exits, notify the server with SIGPIPE immediately. |
57 // otherwise the server won't get SIGPIPE if it does not write |
56 // otherwise the server won't get SIGPIPE if it does not write |
58 // anything. (issue5278) |
57 // anything. (issue5278) |
59 // kill(peerpid, SIGPIPE); |
58 // kill(peerpid, SIGPIPE); |
60 tokio::spawn(pager.map(|_| ()).map_err(|_| ())); // just ignore errors |
59 tokio::spawn(pager.map(|_| ()).map_err(|_| ())); // just ignore errors |
61 Ok((self, pin)) |
60 Ok((self, pin)) |
62 } |
61 } |
63 |
62 |
64 fn run_system(self, spec: CommandSpec) -> Self::RunSystemResult { |
63 fn run_system(self, spec: CommandSpec) -> Self::RunSystemResult { |
65 let fut = new_shell_command(&spec) |
64 let fut = new_shell_command(&spec) |
66 .spawn_async() |
65 .spawn_async() |
67 .into_future() |
66 .into_future() |
68 .flatten() |
67 .flatten() |
69 .map(|status| { |
68 .map(|status| { |
70 let code = status.code().or_else(|| status.signal().map(|n| -n)) |
69 let code = status |
|
70 .code() |
|
71 .or_else(|| status.signal().map(|n| -n)) |
71 .expect("either exit code or signal should be set"); |
72 .expect("either exit code or signal should be set"); |
72 (self, code) |
73 (self, code) |
73 }); |
74 }); |
74 Box::new(fut) |
75 Box::new(fut) |
75 } |
76 } |
82 .arg(&spec.command) |
83 .arg(&spec.command) |
83 .current_dir(&spec.current_dir) |
84 .current_dir(&spec.current_dir) |
84 .env_clear() |
85 .env_clear() |
85 .envs(spec.envs.iter().cloned()); |
86 .envs(spec.envs.iter().cloned()); |
86 builder |
87 builder |
87 } |
88 } |