7 extern crate futures; |
7 extern crate futures; |
8 extern crate log; |
8 extern crate log; |
9 extern crate tokio; |
9 extern crate tokio; |
10 extern crate tokio_hglib; |
10 extern crate tokio_hglib; |
11 |
11 |
12 use chg::locator; |
12 use chg::locator::Locator; |
13 use chg::procutil; |
13 use chg::procutil; |
14 use chg::{ChgClientExt, ChgUiHandler}; |
14 use chg::{ChgClientExt, ChgUiHandler}; |
15 use futures::sync::oneshot; |
15 use futures::sync::oneshot; |
16 use std::env; |
16 use std::env; |
17 use std::io; |
17 use std::io; |
18 use std::process; |
18 use std::process; |
19 use std::time::Instant; |
19 use std::time::Instant; |
20 use tokio::prelude::*; |
20 use tokio::prelude::*; |
21 use tokio_hglib::UnixClient; |
|
22 |
21 |
23 struct DebugLogger { |
22 struct DebugLogger { |
24 start: Instant, |
23 start: Instant, |
25 } |
24 } |
26 |
25 |
62 log::set_boxed_logger(Box::new(DebugLogger::new())) |
61 log::set_boxed_logger(Box::new(DebugLogger::new())) |
63 .expect("any logger should not be installed yet"); |
62 .expect("any logger should not be installed yet"); |
64 log::set_max_level(log::LevelFilter::Debug); |
63 log::set_max_level(log::LevelFilter::Debug); |
65 } |
64 } |
66 |
65 |
|
66 // TODO: add loop detection by $CHGINTERNALMARK |
|
67 |
67 let code = run().unwrap_or_else(|err| { |
68 let code = run().unwrap_or_else(|err| { |
68 writeln!(io::stderr(), "chg: abort: {}", err).unwrap_or(()); |
69 writeln!(io::stderr(), "chg: abort: {}", err).unwrap_or(()); |
69 255 |
70 255 |
70 }); |
71 }); |
71 process::exit(code); |
72 process::exit(code); |
72 } |
73 } |
73 |
74 |
74 fn run() -> io::Result<i32> { |
75 fn run() -> io::Result<i32> { |
75 let current_dir = env::current_dir()?; |
76 let current_dir = env::current_dir()?; |
76 let sock_path = locator::prepare_server_socket_path()?; |
77 let loc = Locator::prepare_from_env()?; |
77 let handler = ChgUiHandler::new(); |
78 let handler = ChgUiHandler::new(); |
78 let (result_tx, result_rx) = oneshot::channel(); |
79 let (result_tx, result_rx) = oneshot::channel(); |
79 let fut = UnixClient::connect(sock_path) |
80 let fut = loc |
80 .and_then(|client| client.set_current_dir(current_dir)) |
81 .connect() |
|
82 .and_then(|(_, client)| client.set_current_dir(current_dir)) |
81 .and_then(|client| client.attach_io(io::stdin(), io::stdout(), io::stderr())) |
83 .and_then(|client| client.attach_io(io::stdin(), io::stdout(), io::stderr())) |
82 .and_then(|client| { |
84 .and_then(|client| { |
83 let pid = client.server_spec().process_id.unwrap(); |
85 let pid = client.server_spec().process_id.unwrap(); |
84 let pgid = client.server_spec().process_group_id; |
86 let pgid = client.server_spec().process_group_id; |
85 procutil::setup_signal_handler_once(pid, pgid)?; |
87 procutil::setup_signal_handler_once(pid, pgid)?; |