author | Matt Harbison <matt_harbison@yahoo.com> |
Fri, 19 Jul 2024 16:49:46 -0400 | |
changeset 51721 | ed28085827ec |
parent 45620 | 426294d06ddc |
permissions | -rw-r--r-- |
39974
a9c5fc436fd5
rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
1 |
// Copyright 2018 Yuya Nishihara <yuya@tcha.org> |
a9c5fc436fd5
rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
2 |
// |
a9c5fc436fd5
rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
3 |
// This software may be used and distributed according to the terms of the |
a9c5fc436fd5
rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
4 |
// GNU General Public License version 2 or any later version. |
a9c5fc436fd5
rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
5 |
|
44750
c794d0da5fb2
rust-chg: reimplement uihandler by using async-trait and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents:
44737
diff
changeset
|
6 |
use async_trait::async_trait; |
39974
a9c5fc436fd5
rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
7 |
use std::io; |
a9c5fc436fd5
rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
8 |
use std::os::unix::io::AsRawFd; |
a9c5fc436fd5
rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
9 |
use std::os::unix::process::ExitStatusExt; |
44737
e9e44e61042b
rust-chg: upgrade to futures-0.3 based libraries
Yuya Nishihara <yuya@tcha.org>
parents:
44689
diff
changeset
|
10 |
use std::process::Stdio; |
39974
a9c5fc436fd5
rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
11 |
use tokio; |
44755
4b0185841058
rust-chg: do not terminate tokio runtime until pager exits
Yuya Nishihara <yuya@tcha.org>
parents:
44750
diff
changeset
|
12 |
use tokio::process::{Child, ChildStdin, Command}; |
39974
a9c5fc436fd5
rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
13 |
|
44689
6bef9d43cc55
rust-chg: use "crate::" to import local modules
Yuya Nishihara <yuya@tcha.org>
parents:
43818
diff
changeset
|
14 |
use crate::message::CommandSpec; |
6bef9d43cc55
rust-chg: use "crate::" to import local modules
Yuya Nishihara <yuya@tcha.org>
parents:
43818
diff
changeset
|
15 |
use crate::procutil; |
39974
a9c5fc436fd5
rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
16 |
|
a9c5fc436fd5
rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
17 |
/// Callback to process shell command requests received from server. |
44750
c794d0da5fb2
rust-chg: reimplement uihandler by using async-trait and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents:
44737
diff
changeset
|
18 |
#[async_trait] |
c794d0da5fb2
rust-chg: reimplement uihandler by using async-trait and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents:
44737
diff
changeset
|
19 |
pub trait SystemHandler { |
39974
a9c5fc436fd5
rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
20 |
type PagerStdin: AsRawFd; |
a9c5fc436fd5
rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
21 |
|
a9c5fc436fd5
rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
22 |
/// Handles pager command request. |
a9c5fc436fd5
rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
23 |
/// |
a9c5fc436fd5
rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
24 |
/// Returns the pipe to be attached to the server if the pager is spawned. |
45620
426294d06ddc
rust: move rustfmt.toml to repo root so it can be used by `hg fix`
Martin von Zweigbergk <martinvonz@google.com>
parents:
44756
diff
changeset
|
25 |
async fn spawn_pager( |
426294d06ddc
rust: move rustfmt.toml to repo root so it can be used by `hg fix`
Martin von Zweigbergk <martinvonz@google.com>
parents:
44756
diff
changeset
|
26 |
&mut self, |
426294d06ddc
rust: move rustfmt.toml to repo root so it can be used by `hg fix`
Martin von Zweigbergk <martinvonz@google.com>
parents:
44756
diff
changeset
|
27 |
spec: &CommandSpec, |
426294d06ddc
rust: move rustfmt.toml to repo root so it can be used by `hg fix`
Martin von Zweigbergk <martinvonz@google.com>
parents:
44756
diff
changeset
|
28 |
) -> io::Result<Self::PagerStdin>; |
39974
a9c5fc436fd5
rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
29 |
|
a9c5fc436fd5
rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
30 |
/// Handles system command request. |
a9c5fc436fd5
rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
31 |
/// |
a9c5fc436fd5
rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
32 |
/// Returns command exit code (positive) or signal number (negative). |
44750
c794d0da5fb2
rust-chg: reimplement uihandler by using async-trait and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents:
44737
diff
changeset
|
33 |
async fn run_system(&mut self, spec: &CommandSpec) -> io::Result<i32>; |
39974
a9c5fc436fd5
rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
34 |
} |
a9c5fc436fd5
rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
35 |
|
a9c5fc436fd5
rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
36 |
/// Default cHg implementation to process requests received from server. |
44755
4b0185841058
rust-chg: do not terminate tokio runtime until pager exits
Yuya Nishihara <yuya@tcha.org>
parents:
44750
diff
changeset
|
37 |
pub struct ChgUiHandler { |
4b0185841058
rust-chg: do not terminate tokio runtime until pager exits
Yuya Nishihara <yuya@tcha.org>
parents:
44750
diff
changeset
|
38 |
pager: Option<Child>, |
4b0185841058
rust-chg: do not terminate tokio runtime until pager exits
Yuya Nishihara <yuya@tcha.org>
parents:
44750
diff
changeset
|
39 |
} |
39974
a9c5fc436fd5
rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
40 |
|
a9c5fc436fd5
rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
41 |
impl ChgUiHandler { |
a9c5fc436fd5
rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
42 |
pub fn new() -> ChgUiHandler { |
44755
4b0185841058
rust-chg: do not terminate tokio runtime until pager exits
Yuya Nishihara <yuya@tcha.org>
parents:
44750
diff
changeset
|
43 |
ChgUiHandler { pager: None } |
4b0185841058
rust-chg: do not terminate tokio runtime until pager exits
Yuya Nishihara <yuya@tcha.org>
parents:
44750
diff
changeset
|
44 |
} |
4b0185841058
rust-chg: do not terminate tokio runtime until pager exits
Yuya Nishihara <yuya@tcha.org>
parents:
44750
diff
changeset
|
45 |
|
4b0185841058
rust-chg: do not terminate tokio runtime until pager exits
Yuya Nishihara <yuya@tcha.org>
parents:
44750
diff
changeset
|
46 |
/// Waits until the pager process exits. |
4b0185841058
rust-chg: do not terminate tokio runtime until pager exits
Yuya Nishihara <yuya@tcha.org>
parents:
44750
diff
changeset
|
47 |
pub async fn wait_pager(&mut self) -> io::Result<()> { |
4b0185841058
rust-chg: do not terminate tokio runtime until pager exits
Yuya Nishihara <yuya@tcha.org>
parents:
44750
diff
changeset
|
48 |
if let Some(p) = self.pager.take() { |
4b0185841058
rust-chg: do not terminate tokio runtime until pager exits
Yuya Nishihara <yuya@tcha.org>
parents:
44750
diff
changeset
|
49 |
p.await?; |
4b0185841058
rust-chg: do not terminate tokio runtime until pager exits
Yuya Nishihara <yuya@tcha.org>
parents:
44750
diff
changeset
|
50 |
} |
4b0185841058
rust-chg: do not terminate tokio runtime until pager exits
Yuya Nishihara <yuya@tcha.org>
parents:
44750
diff
changeset
|
51 |
Ok(()) |
39974
a9c5fc436fd5
rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
52 |
} |
a9c5fc436fd5
rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
53 |
} |
a9c5fc436fd5
rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
54 |
|
44750
c794d0da5fb2
rust-chg: reimplement uihandler by using async-trait and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents:
44737
diff
changeset
|
55 |
#[async_trait] |
39974
a9c5fc436fd5
rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
56 |
impl SystemHandler for ChgUiHandler { |
a9c5fc436fd5
rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
57 |
type PagerStdin = ChildStdin; |
a9c5fc436fd5
rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
58 |
|
45620
426294d06ddc
rust: move rustfmt.toml to repo root so it can be used by `hg fix`
Martin von Zweigbergk <martinvonz@google.com>
parents:
44756
diff
changeset
|
59 |
async fn spawn_pager( |
426294d06ddc
rust: move rustfmt.toml to repo root so it can be used by `hg fix`
Martin von Zweigbergk <martinvonz@google.com>
parents:
44756
diff
changeset
|
60 |
&mut self, |
426294d06ddc
rust: move rustfmt.toml to repo root so it can be used by `hg fix`
Martin von Zweigbergk <martinvonz@google.com>
parents:
44756
diff
changeset
|
61 |
spec: &CommandSpec, |
426294d06ddc
rust: move rustfmt.toml to repo root so it can be used by `hg fix`
Martin von Zweigbergk <martinvonz@google.com>
parents:
44756
diff
changeset
|
62 |
) -> io::Result<Self::PagerStdin> { |
426294d06ddc
rust: move rustfmt.toml to repo root so it can be used by `hg fix`
Martin von Zweigbergk <martinvonz@google.com>
parents:
44756
diff
changeset
|
63 |
let mut pager = |
426294d06ddc
rust: move rustfmt.toml to repo root so it can be used by `hg fix`
Martin von Zweigbergk <martinvonz@google.com>
parents:
44756
diff
changeset
|
64 |
new_shell_command(&spec).stdin(Stdio::piped()).spawn()?; |
44737
e9e44e61042b
rust-chg: upgrade to futures-0.3 based libraries
Yuya Nishihara <yuya@tcha.org>
parents:
44689
diff
changeset
|
65 |
let pin = pager.stdin.take().unwrap(); |
39974
a9c5fc436fd5
rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
66 |
procutil::set_blocking_fd(pin.as_raw_fd())?; |
40119
e70b616a077b
rust-chg: remove SIGCHLD handler which won't work in oxidized chg
Yuya Nishihara <yuya@tcha.org>
parents:
39974
diff
changeset
|
67 |
// TODO: if pager exits, notify the server with SIGPIPE immediately. |
e70b616a077b
rust-chg: remove SIGCHLD handler which won't work in oxidized chg
Yuya Nishihara <yuya@tcha.org>
parents:
39974
diff
changeset
|
68 |
// otherwise the server won't get SIGPIPE if it does not write |
e70b616a077b
rust-chg: remove SIGCHLD handler which won't work in oxidized chg
Yuya Nishihara <yuya@tcha.org>
parents:
39974
diff
changeset
|
69 |
// anything. (issue5278) |
e70b616a077b
rust-chg: remove SIGCHLD handler which won't work in oxidized chg
Yuya Nishihara <yuya@tcha.org>
parents:
39974
diff
changeset
|
70 |
// kill(peerpid, SIGPIPE); |
44755
4b0185841058
rust-chg: do not terminate tokio runtime until pager exits
Yuya Nishihara <yuya@tcha.org>
parents:
44750
diff
changeset
|
71 |
self.pager = Some(pager); |
44750
c794d0da5fb2
rust-chg: reimplement uihandler by using async-trait and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents:
44737
diff
changeset
|
72 |
Ok(pin) |
39974
a9c5fc436fd5
rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
73 |
} |
a9c5fc436fd5
rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
74 |
|
44750
c794d0da5fb2
rust-chg: reimplement uihandler by using async-trait and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents:
44737
diff
changeset
|
75 |
async fn run_system(&mut self, spec: &CommandSpec) -> io::Result<i32> { |
c794d0da5fb2
rust-chg: reimplement uihandler by using async-trait and tokio-0.2
Yuya Nishihara <yuya@tcha.org>
parents:
44737
diff
changeset
|
76 |
let status = new_shell_command(&spec).spawn()?.await?; |
44756
27fe8cc1338f
rust-chg: clean up excessive indents
Yuya Nishihara <yuya@tcha.org>
parents:
44755
diff
changeset
|
77 |
let code = status |
27fe8cc1338f
rust-chg: clean up excessive indents
Yuya Nishihara <yuya@tcha.org>
parents:
44755
diff
changeset
|
78 |
.code() |
27fe8cc1338f
rust-chg: clean up excessive indents
Yuya Nishihara <yuya@tcha.org>
parents:
44755
diff
changeset
|
79 |
.or_else(|| status.signal().map(|n| -n)) |
27fe8cc1338f
rust-chg: clean up excessive indents
Yuya Nishihara <yuya@tcha.org>
parents:
44755
diff
changeset
|
80 |
.expect("either exit code or signal should be set"); |
27fe8cc1338f
rust-chg: clean up excessive indents
Yuya Nishihara <yuya@tcha.org>
parents:
44755
diff
changeset
|
81 |
Ok(code) |
39974
a9c5fc436fd5
rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
82 |
} |
a9c5fc436fd5
rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
83 |
} |
a9c5fc436fd5
rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
84 |
|
a9c5fc436fd5
rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
85 |
fn new_shell_command(spec: &CommandSpec) -> Command { |
a9c5fc436fd5
rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
86 |
let mut builder = Command::new("/bin/sh"); |
a9c5fc436fd5
rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
87 |
builder |
a9c5fc436fd5
rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
88 |
.arg("-c") |
a9c5fc436fd5
rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
89 |
.arg(&spec.command) |
a9c5fc436fd5
rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
90 |
.current_dir(&spec.current_dir) |
a9c5fc436fd5
rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
91 |
.env_clear() |
a9c5fc436fd5
rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
92 |
.envs(spec.envs.iter().cloned()); |
a9c5fc436fd5
rust-chg: add callback to handle pager and shell command requests
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
93 |
builder |
43818
ce088b38f92b
rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40119
diff
changeset
|
94 |
} |