author | Yuya Nishihara <yuya@tcha.org> |
Fri, 10 Apr 2020 22:07:11 +0900 | |
changeset 44738 | 1be605526c34 |
parent 44689 | 6bef9d43cc55 |
child 44749 | cb5822e6e545 |
permissions | -rw-r--r-- |
39972
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
1 |
// Copyright 2018 Yuya Nishihara <yuya@tcha.org> |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
2 |
// |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
3 |
// This software may be used and distributed according to the terms of the |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
4 |
// GNU General Public License version 2 or any later version. |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
5 |
|
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
6 |
//! Functions to send client-side fds over the command server channel. |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
7 |
|
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
8 |
use std::io; |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
9 |
use std::os::unix::io::AsRawFd; |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
10 |
use tokio_hglib::codec::ChannelMessage; |
44738
1be605526c34
rust-chg: reimplement attach_io operation as async function
Yuya Nishihara <yuya@tcha.org>
parents:
44689
diff
changeset
|
11 |
use tokio_hglib::{Connection, Protocol}; |
39972
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
12 |
|
44689
6bef9d43cc55
rust-chg: use "crate::" to import local modules
Yuya Nishihara <yuya@tcha.org>
parents:
44688
diff
changeset
|
13 |
use crate::message; |
6bef9d43cc55
rust-chg: use "crate::" to import local modules
Yuya Nishihara <yuya@tcha.org>
parents:
44688
diff
changeset
|
14 |
use crate::procutil; |
39972
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
15 |
|
44738
1be605526c34
rust-chg: reimplement attach_io operation as async function
Yuya Nishihara <yuya@tcha.org>
parents:
44689
diff
changeset
|
16 |
/// Sends client-side fds over the command server channel. |
39972
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
17 |
/// |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
18 |
/// This works as follows: |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
19 |
/// 1. Client sends "attachio" request. |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
20 |
/// 2. Server sends back 1-byte input request. |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
21 |
/// 3. Client sends fds with 1-byte dummy payload in response. |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
22 |
/// 4. Server returns the number of the fds received. |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
23 |
/// |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
24 |
/// If the stderr is omitted, it will be redirected to the stdout. This |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
25 |
/// allows us to attach the pager stdin to both stdout and stderr, and |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
26 |
/// dispose of the client-side handle once attached. |
44738
1be605526c34
rust-chg: reimplement attach_io operation as async function
Yuya Nishihara <yuya@tcha.org>
parents:
44689
diff
changeset
|
27 |
pub async fn attach_io( |
1be605526c34
rust-chg: reimplement attach_io operation as async function
Yuya Nishihara <yuya@tcha.org>
parents:
44689
diff
changeset
|
28 |
proto: &mut Protocol<impl Connection + AsRawFd>, |
1be605526c34
rust-chg: reimplement attach_io operation as async function
Yuya Nishihara <yuya@tcha.org>
parents:
44689
diff
changeset
|
29 |
stdin: impl AsRawFd, |
1be605526c34
rust-chg: reimplement attach_io operation as async function
Yuya Nishihara <yuya@tcha.org>
parents:
44689
diff
changeset
|
30 |
stdout: impl AsRawFd, |
1be605526c34
rust-chg: reimplement attach_io operation as async function
Yuya Nishihara <yuya@tcha.org>
parents:
44689
diff
changeset
|
31 |
stderr: Option<impl AsRawFd>, |
1be605526c34
rust-chg: reimplement attach_io operation as async function
Yuya Nishihara <yuya@tcha.org>
parents:
44689
diff
changeset
|
32 |
) -> io::Result<()> { |
1be605526c34
rust-chg: reimplement attach_io operation as async function
Yuya Nishihara <yuya@tcha.org>
parents:
44689
diff
changeset
|
33 |
// TODO: unindent |
1be605526c34
rust-chg: reimplement attach_io operation as async function
Yuya Nishihara <yuya@tcha.org>
parents:
44689
diff
changeset
|
34 |
{ |
1be605526c34
rust-chg: reimplement attach_io operation as async function
Yuya Nishihara <yuya@tcha.org>
parents:
44689
diff
changeset
|
35 |
proto.send_command("attachio").await?; |
39972
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
36 |
loop { |
44738
1be605526c34
rust-chg: reimplement attach_io operation as async function
Yuya Nishihara <yuya@tcha.org>
parents:
44689
diff
changeset
|
37 |
match proto.fetch_response().await? { |
39972
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
38 |
ChannelMessage::Data(b'r', data) => { |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
39 |
let fd_cnt = message::parse_result_code(data)?; |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
40 |
if fd_cnt == 3 { |
44738
1be605526c34
rust-chg: reimplement attach_io operation as async function
Yuya Nishihara <yuya@tcha.org>
parents:
44689
diff
changeset
|
41 |
return Ok(()); |
39972
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
42 |
} else { |
43818
ce088b38f92b
rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39972
diff
changeset
|
43 |
return Err(io::Error::new( |
ce088b38f92b
rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39972
diff
changeset
|
44 |
io::ErrorKind::InvalidData, |
ce088b38f92b
rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39972
diff
changeset
|
45 |
"unexpected attachio result", |
ce088b38f92b
rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39972
diff
changeset
|
46 |
)); |
39972
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
47 |
} |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
48 |
} |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
49 |
ChannelMessage::Data(..) => { |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
50 |
// just ignore data sent to uninteresting (optional) channel |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
51 |
} |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
52 |
ChannelMessage::InputRequest(1) => { |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
53 |
// this may fail with EWOULDBLOCK in theory, but the |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
54 |
// payload is quite small, and the send buffer should |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
55 |
// be empty so the operation will complete immediately |
44738
1be605526c34
rust-chg: reimplement attach_io operation as async function
Yuya Nishihara <yuya@tcha.org>
parents:
44689
diff
changeset
|
56 |
let sock_fd = proto.as_raw_fd(); |
1be605526c34
rust-chg: reimplement attach_io operation as async function
Yuya Nishihara <yuya@tcha.org>
parents:
44689
diff
changeset
|
57 |
let ifd = stdin.as_raw_fd(); |
1be605526c34
rust-chg: reimplement attach_io operation as async function
Yuya Nishihara <yuya@tcha.org>
parents:
44689
diff
changeset
|
58 |
let ofd = stdout.as_raw_fd(); |
1be605526c34
rust-chg: reimplement attach_io operation as async function
Yuya Nishihara <yuya@tcha.org>
parents:
44689
diff
changeset
|
59 |
let efd = stderr.as_ref().map_or(ofd, |f| f.as_raw_fd()); |
39972
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
60 |
procutil::send_raw_fds(sock_fd, &[ifd, ofd, efd])?; |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
61 |
} |
43818
ce088b38f92b
rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39972
diff
changeset
|
62 |
ChannelMessage::InputRequest(..) |
ce088b38f92b
rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39972
diff
changeset
|
63 |
| ChannelMessage::LineRequest(..) |
ce088b38f92b
rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39972
diff
changeset
|
64 |
| ChannelMessage::SystemRequest(..) => { |
ce088b38f92b
rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39972
diff
changeset
|
65 |
return Err(io::Error::new( |
ce088b38f92b
rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39972
diff
changeset
|
66 |
io::ErrorKind::InvalidData, |
ce088b38f92b
rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39972
diff
changeset
|
67 |
"unsupported request while attaching io", |
ce088b38f92b
rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39972
diff
changeset
|
68 |
)); |
39972
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
69 |
} |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
70 |
} |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
71 |
} |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
72 |
} |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
73 |
} |