##// END OF EJS Templates
rust-chg: have attach_io() simply take reference of AsRawFd object...
Yuya Nishihara -
r45233:cb5822e6 default
parent child Browse files
Show More
@@ -1,73 +1,71 b''
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 //! Functions to send client-side fds over the command server channel.
6 //! Functions to send client-side fds over the command server channel.
7
7
8 use std::io;
8 use std::io;
9 use std::os::unix::io::AsRawFd;
9 use std::os::unix::io::AsRawFd;
10 use tokio_hglib::codec::ChannelMessage;
10 use tokio_hglib::codec::ChannelMessage;
11 use tokio_hglib::{Connection, Protocol};
11 use tokio_hglib::{Connection, Protocol};
12
12
13 use crate::message;
13 use crate::message;
14 use crate::procutil;
14 use crate::procutil;
15
15
16 /// Sends client-side fds over the command server channel.
16 /// Sends client-side fds over the command server channel.
17 ///
17 ///
18 /// This works as follows:
18 /// This works as follows:
19 /// 1. Client sends "attachio" request.
19 /// 1. Client sends "attachio" request.
20 /// 2. Server sends back 1-byte input request.
20 /// 2. Server sends back 1-byte input request.
21 /// 3. Client sends fds with 1-byte dummy payload in response.
21 /// 3. Client sends fds with 1-byte dummy payload in response.
22 /// 4. Server returns the number of the fds received.
22 /// 4. Server returns the number of the fds received.
23 ///
23 ///
24 /// If the stderr is omitted, it will be redirected to the stdout. This
24 /// The client-side fds may be dropped once duplicated to the server.
25 /// allows us to attach the pager stdin to both stdout and stderr, and
26 /// dispose of the client-side handle once attached.
27 pub async fn attach_io(
25 pub async fn attach_io(
28 proto: &mut Protocol<impl Connection + AsRawFd>,
26 proto: &mut Protocol<impl Connection + AsRawFd>,
29 stdin: impl AsRawFd,
27 stdin: &impl AsRawFd,
30 stdout: impl AsRawFd,
28 stdout: &impl AsRawFd,
31 stderr: Option<impl AsRawFd>,
29 stderr: &impl AsRawFd,
32 ) -> io::Result<()> {
30 ) -> io::Result<()> {
33 // TODO: unindent
31 // TODO: unindent
34 {
32 {
35 proto.send_command("attachio").await?;
33 proto.send_command("attachio").await?;
36 loop {
34 loop {
37 match proto.fetch_response().await? {
35 match proto.fetch_response().await? {
38 ChannelMessage::Data(b'r', data) => {
36 ChannelMessage::Data(b'r', data) => {
39 let fd_cnt = message::parse_result_code(data)?;
37 let fd_cnt = message::parse_result_code(data)?;
40 if fd_cnt == 3 {
38 if fd_cnt == 3 {
41 return Ok(());
39 return Ok(());
42 } else {
40 } else {
43 return Err(io::Error::new(
41 return Err(io::Error::new(
44 io::ErrorKind::InvalidData,
42 io::ErrorKind::InvalidData,
45 "unexpected attachio result",
43 "unexpected attachio result",
46 ));
44 ));
47 }
45 }
48 }
46 }
49 ChannelMessage::Data(..) => {
47 ChannelMessage::Data(..) => {
50 // just ignore data sent to uninteresting (optional) channel
48 // just ignore data sent to uninteresting (optional) channel
51 }
49 }
52 ChannelMessage::InputRequest(1) => {
50 ChannelMessage::InputRequest(1) => {
53 // this may fail with EWOULDBLOCK in theory, but the
51 // this may fail with EWOULDBLOCK in theory, but the
54 // payload is quite small, and the send buffer should
52 // payload is quite small, and the send buffer should
55 // be empty so the operation will complete immediately
53 // be empty so the operation will complete immediately
56 let sock_fd = proto.as_raw_fd();
54 let sock_fd = proto.as_raw_fd();
57 let ifd = stdin.as_raw_fd();
55 let ifd = stdin.as_raw_fd();
58 let ofd = stdout.as_raw_fd();
56 let ofd = stdout.as_raw_fd();
59 let efd = stderr.as_ref().map_or(ofd, |f| f.as_raw_fd());
57 let efd = stderr.as_raw_fd();
60 procutil::send_raw_fds(sock_fd, &[ifd, ofd, efd])?;
58 procutil::send_raw_fds(sock_fd, &[ifd, ofd, efd])?;
61 }
59 }
62 ChannelMessage::InputRequest(..)
60 ChannelMessage::InputRequest(..)
63 | ChannelMessage::LineRequest(..)
61 | ChannelMessage::LineRequest(..)
64 | ChannelMessage::SystemRequest(..) => {
62 | ChannelMessage::SystemRequest(..) => {
65 return Err(io::Error::new(
63 return Err(io::Error::new(
66 io::ErrorKind::InvalidData,
64 io::ErrorKind::InvalidData,
67 "unsupported request while attaching io",
65 "unsupported request while attaching io",
68 ));
66 ));
69 }
67 }
70 }
68 }
71 }
69 }
72 }
70 }
73 }
71 }
General Comments 0
You need to be logged in to leave comments. Login now