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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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 }