rust/chg/src/uihandler.rs
changeset 43836 ce088b38f92b
parent 40120 e70b616a077b
child 44690 6bef9d43cc55
equal deleted inserted replaced
43835:d9f85f61f0ed 43836:ce088b38f92b
     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 }