40 fn log(&self, record: &log::Record) { |
40 fn log(&self, record: &log::Record) { |
41 if self.enabled(record.metadata()) { |
41 if self.enabled(record.metadata()) { |
42 // just make the output looks similar to chg of C |
42 // just make the output looks similar to chg of C |
43 let l = format!("{}", record.level()).to_lowercase(); |
43 let l = format!("{}", record.level()).to_lowercase(); |
44 let t = self.start.elapsed(); |
44 let t = self.start.elapsed(); |
45 writeln!(io::stderr(), "chg: {}: {}.{:06} {}", |
45 writeln!( |
46 l, t.as_secs(), t.subsec_micros(), record.args()).unwrap_or(()); |
46 io::stderr(), |
|
47 "chg: {}: {}.{:06} {}", |
|
48 l, |
|
49 t.as_secs(), |
|
50 t.subsec_micros(), |
|
51 record.args() |
|
52 ) |
|
53 .unwrap_or(()); |
47 } |
54 } |
48 } |
55 } |
49 |
56 |
50 fn flush(&self) { |
57 fn flush(&self) {} |
51 } |
|
52 } |
58 } |
53 |
59 |
54 fn main() { |
60 fn main() { |
55 if env::var_os("CHGDEBUG").is_some() { |
61 if env::var_os("CHGDEBUG").is_some() { |
56 log::set_boxed_logger(Box::new(DebugLogger::new())) |
62 log::set_boxed_logger(Box::new(DebugLogger::new())) |
69 let current_dir = env::current_dir()?; |
75 let current_dir = env::current_dir()?; |
70 let sock_path = locator::prepare_server_socket_path()?; |
76 let sock_path = locator::prepare_server_socket_path()?; |
71 let handler = ChgUiHandler::new(); |
77 let handler = ChgUiHandler::new(); |
72 let (result_tx, result_rx) = oneshot::channel(); |
78 let (result_tx, result_rx) = oneshot::channel(); |
73 let fut = UnixClient::connect(sock_path) |
79 let fut = UnixClient::connect(sock_path) |
74 .and_then(|client| { |
80 .and_then(|client| client.set_current_dir(current_dir)) |
75 client.set_current_dir(current_dir) |
81 .and_then(|client| client.attach_io(io::stdin(), io::stdout(), io::stderr())) |
76 }) |
|
77 .and_then(|client| { |
|
78 client.attach_io(io::stdin(), io::stdout(), io::stderr()) |
|
79 }) |
|
80 .and_then(|client| { |
82 .and_then(|client| { |
81 let pid = client.server_spec().process_id.unwrap(); |
83 let pid = client.server_spec().process_id.unwrap(); |
82 let pgid = client.server_spec().process_group_id; |
84 let pgid = client.server_spec().process_group_id; |
83 procutil::setup_signal_handler_once(pid, pgid)?; |
85 procutil::setup_signal_handler_once(pid, pgid)?; |
84 Ok(client) |
86 Ok(client) |
85 }) |
87 }) |
86 .and_then(|client| { |
88 .and_then(|client| client.run_command_chg(handler, env::args_os().skip(1))) |
87 client.run_command_chg(handler, env::args_os().skip(1)) |
|
88 }) |
|
89 .map(|(_client, _handler, code)| { |
89 .map(|(_client, _handler, code)| { |
90 procutil::restore_signal_handler_once()?; |
90 procutil::restore_signal_handler_once()?; |
91 Ok(code) |
91 Ok(code) |
92 }) |
92 }) |
93 .or_else(|err| Ok(Err(err))) // pass back error to caller |
93 .or_else(|err| Ok(Err(err))) // pass back error to caller |
94 .map(|res| result_tx.send(res).unwrap()); |
94 .map(|res| result_tx.send(res).unwrap()); |
95 tokio::run(fut); |
95 tokio::run(fut); |
96 result_rx.wait().unwrap_or(Err(io::Error::new(io::ErrorKind::Other, |
96 result_rx.wait().unwrap_or(Err(io::Error::new( |
97 "no exit code set"))) |
97 io::ErrorKind::Other, |
|
98 "no exit code set", |
|
99 ))) |
98 } |
100 } |