Mercurial > public > mercurial-scm > hg
annotate rust/chg/src/attachio.rs @ 44688:1f5ab1a9363d
rust-chg: upgrade to 2018 edition and remove useless extern crates
Differential Revision: https://phab.mercurial-scm.org/D8399
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Fri, 10 Apr 2020 21:35:16 +0900 |
parents | ce088b38f92b |
children | 6bef9d43cc55 |
rev | line source |
---|---|
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 |
44688
1f5ab1a9363d
rust-chg: upgrade to 2018 edition and remove useless extern crates
Yuya Nishihara <yuya@tcha.org>
parents:
43818
diff
changeset
|
8 use futures::{try_ready, Async, Future, Poll}; |
39972
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
9 use std::io; |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
10 use std::os::unix::io::AsRawFd; |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
11 use tokio_hglib::codec::ChannelMessage; |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
12 use tokio_hglib::protocol::MessageLoop; |
43818
ce088b38f92b
rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39972
diff
changeset
|
13 use tokio_hglib::{Client, Connection}; |
39972
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
14 |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
15 use super::message; |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
16 use super::procutil; |
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 /// Future 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
|
19 /// |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
20 /// This works as follows: |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
21 /// 1. Client sends "attachio" request. |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
22 /// 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
|
23 /// 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
|
24 /// 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
|
25 /// |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
26 /// 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
|
27 /// 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
|
28 /// dispose of the client-side handle once attached. |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
29 #[must_use = "futures do nothing unless polled"] |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
30 pub struct AttachIo<C, I, O, E> |
43818
ce088b38f92b
rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39972
diff
changeset
|
31 where |
ce088b38f92b
rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39972
diff
changeset
|
32 C: Connection, |
39972
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
33 { |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
34 msg_loop: MessageLoop<C>, |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
35 stdin: I, |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
36 stdout: O, |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
37 stderr: Option<E>, |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
38 } |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
39 |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
40 impl<C, I, O, E> AttachIo<C, I, O, E> |
43818
ce088b38f92b
rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39972
diff
changeset
|
41 where |
ce088b38f92b
rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39972
diff
changeset
|
42 C: Connection + AsRawFd, |
ce088b38f92b
rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39972
diff
changeset
|
43 I: AsRawFd, |
ce088b38f92b
rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39972
diff
changeset
|
44 O: AsRawFd, |
ce088b38f92b
rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39972
diff
changeset
|
45 E: AsRawFd, |
39972
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
46 { |
43818
ce088b38f92b
rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39972
diff
changeset
|
47 pub fn with_client( |
ce088b38f92b
rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39972
diff
changeset
|
48 client: Client<C>, |
ce088b38f92b
rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39972
diff
changeset
|
49 stdin: I, |
ce088b38f92b
rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39972
diff
changeset
|
50 stdout: O, |
ce088b38f92b
rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39972
diff
changeset
|
51 stderr: Option<E>, |
ce088b38f92b
rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39972
diff
changeset
|
52 ) -> AttachIo<C, I, O, E> { |
39972
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
53 let msg_loop = MessageLoop::start(client, b"attachio"); |
43818
ce088b38f92b
rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39972
diff
changeset
|
54 AttachIo { |
ce088b38f92b
rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39972
diff
changeset
|
55 msg_loop, |
ce088b38f92b
rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39972
diff
changeset
|
56 stdin, |
ce088b38f92b
rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39972
diff
changeset
|
57 stdout, |
ce088b38f92b
rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39972
diff
changeset
|
58 stderr, |
ce088b38f92b
rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39972
diff
changeset
|
59 } |
39972
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
60 } |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
61 } |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
62 |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
63 impl<C, I, O, E> Future for AttachIo<C, I, O, E> |
43818
ce088b38f92b
rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39972
diff
changeset
|
64 where |
ce088b38f92b
rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39972
diff
changeset
|
65 C: Connection + AsRawFd, |
ce088b38f92b
rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39972
diff
changeset
|
66 I: AsRawFd, |
ce088b38f92b
rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39972
diff
changeset
|
67 O: AsRawFd, |
ce088b38f92b
rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39972
diff
changeset
|
68 E: AsRawFd, |
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 type Item = Client<C>; |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
71 type Error = io::Error; |
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 fn poll(&mut self) -> Poll<Self::Item, Self::Error> { |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
74 loop { |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
75 let (client, msg) = try_ready!(self.msg_loop.poll()); |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
76 match msg { |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
77 ChannelMessage::Data(b'r', data) => { |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
78 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
|
79 if fd_cnt == 3 { |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
80 return Ok(Async::Ready(client)); |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
81 } else { |
43818
ce088b38f92b
rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39972
diff
changeset
|
82 return Err(io::Error::new( |
ce088b38f92b
rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39972
diff
changeset
|
83 io::ErrorKind::InvalidData, |
ce088b38f92b
rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39972
diff
changeset
|
84 "unexpected attachio result", |
ce088b38f92b
rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39972
diff
changeset
|
85 )); |
39972
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
86 } |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
87 } |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
88 ChannelMessage::Data(..) => { |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
89 // 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
|
90 self.msg_loop = MessageLoop::resume(client); |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
91 } |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
92 ChannelMessage::InputRequest(1) => { |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
93 // 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
|
94 // 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
|
95 // be empty so the operation will complete immediately |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
96 let sock_fd = client.as_raw_fd(); |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
97 let ifd = self.stdin.as_raw_fd(); |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
98 let ofd = self.stdout.as_raw_fd(); |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
99 let efd = self.stderr.as_ref().map_or(ofd, |f| f.as_raw_fd()); |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
100 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
|
101 self.msg_loop = MessageLoop::resume(client); |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
102 } |
43818
ce088b38f92b
rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39972
diff
changeset
|
103 ChannelMessage::InputRequest(..) |
ce088b38f92b
rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39972
diff
changeset
|
104 | ChannelMessage::LineRequest(..) |
ce088b38f92b
rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39972
diff
changeset
|
105 | ChannelMessage::SystemRequest(..) => { |
ce088b38f92b
rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39972
diff
changeset
|
106 return Err(io::Error::new( |
ce088b38f92b
rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39972
diff
changeset
|
107 io::ErrorKind::InvalidData, |
ce088b38f92b
rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39972
diff
changeset
|
108 "unsupported request while attaching io", |
ce088b38f92b
rust: run rustfmt
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39972
diff
changeset
|
109 )); |
39972
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
110 } |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
111 } |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
112 } |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
113 } |
7a0ffdd4af78
rust-chg: add future that handles "attachio" request
Yuya Nishihara <yuya@tcha.org>
parents:
diff
changeset
|
114 } |