26 proto: &mut Protocol<impl Connection + AsRawFd>, |
26 proto: &mut Protocol<impl Connection + AsRawFd>, |
27 stdin: &impl AsRawFd, |
27 stdin: &impl AsRawFd, |
28 stdout: &impl AsRawFd, |
28 stdout: &impl AsRawFd, |
29 stderr: &impl AsRawFd, |
29 stderr: &impl AsRawFd, |
30 ) -> io::Result<()> { |
30 ) -> io::Result<()> { |
31 // TODO: unindent |
31 proto.send_command("attachio").await?; |
32 { |
32 loop { |
33 proto.send_command("attachio").await?; |
33 match proto.fetch_response().await? { |
34 loop { |
34 ChannelMessage::Data(b'r', data) => { |
35 match proto.fetch_response().await? { |
35 let fd_cnt = message::parse_result_code(data)?; |
36 ChannelMessage::Data(b'r', data) => { |
36 if fd_cnt == 3 { |
37 let fd_cnt = message::parse_result_code(data)?; |
37 return Ok(()); |
38 if fd_cnt == 3 { |
38 } else { |
39 return Ok(()); |
|
40 } else { |
|
41 return Err(io::Error::new( |
|
42 io::ErrorKind::InvalidData, |
|
43 "unexpected attachio result", |
|
44 )); |
|
45 } |
|
46 } |
|
47 ChannelMessage::Data(..) => { |
|
48 // just ignore data sent to uninteresting (optional) channel |
|
49 } |
|
50 ChannelMessage::InputRequest(1) => { |
|
51 // this may fail with EWOULDBLOCK in theory, but the |
|
52 // payload is quite small, and the send buffer should |
|
53 // be empty so the operation will complete immediately |
|
54 let sock_fd = proto.as_raw_fd(); |
|
55 let ifd = stdin.as_raw_fd(); |
|
56 let ofd = stdout.as_raw_fd(); |
|
57 let efd = stderr.as_raw_fd(); |
|
58 procutil::send_raw_fds(sock_fd, &[ifd, ofd, efd])?; |
|
59 } |
|
60 ChannelMessage::InputRequest(..) |
|
61 | ChannelMessage::LineRequest(..) |
|
62 | ChannelMessage::SystemRequest(..) => { |
|
63 return Err(io::Error::new( |
39 return Err(io::Error::new( |
64 io::ErrorKind::InvalidData, |
40 io::ErrorKind::InvalidData, |
65 "unsupported request while attaching io", |
41 "unexpected attachio result", |
66 )); |
42 )); |
67 } |
43 } |
|
44 } |
|
45 ChannelMessage::Data(..) => { |
|
46 // just ignore data sent to uninteresting (optional) channel |
|
47 } |
|
48 ChannelMessage::InputRequest(1) => { |
|
49 // this may fail with EWOULDBLOCK in theory, but the |
|
50 // payload is quite small, and the send buffer should |
|
51 // be empty so the operation will complete immediately |
|
52 let sock_fd = proto.as_raw_fd(); |
|
53 let ifd = stdin.as_raw_fd(); |
|
54 let ofd = stdout.as_raw_fd(); |
|
55 let efd = stderr.as_raw_fd(); |
|
56 procutil::send_raw_fds(sock_fd, &[ifd, ofd, efd])?; |
|
57 } |
|
58 ChannelMessage::InputRequest(..) |
|
59 | ChannelMessage::LineRequest(..) |
|
60 | ChannelMessage::SystemRequest(..) => { |
|
61 return Err(io::Error::new( |
|
62 io::ErrorKind::InvalidData, |
|
63 "unsupported request while attaching io", |
|
64 )); |
68 } |
65 } |
69 } |
66 } |
70 } |
67 } |
71 } |
68 } |