1use futures::{lock::BiLock, ready};
12use std::io::{self};
13use std::{
14 os::unix::io::{AsRawFd, RawFd},
15 task::{Context, Poll},
16};
17use tokio::io::{AsyncRead, AsyncWrite};
18
19use crate::{AsAsyncPtyFd, AsyncPtyMaster};
20
21pub fn split(master: AsyncPtyMaster) -> (AsyncPtyMasterReadHalf, AsyncPtyMasterWriteHalf) {
22 let (a, b) = BiLock::new(master);
23 (
24 AsyncPtyMasterReadHalf { handle: a },
25 AsyncPtyMasterWriteHalf { handle: b },
26 )
27}
28
29pub struct AsyncPtyMasterReadHalf {
31 handle: BiLock<AsyncPtyMaster>,
32}
33
34pub struct AsyncPtyMasterWriteHalf {
36 handle: BiLock<AsyncPtyMaster>,
37}
38
39impl AsAsyncPtyFd for AsyncPtyMasterReadHalf {
40 fn as_async_pty_fd(&self, cx: &mut Context<'_>) -> Poll<RawFd> {
41 let l = ready!(self.handle.poll_lock(cx));
42 Poll::Ready(l.as_raw_fd())
43 }
44}
45
46impl AsAsyncPtyFd for &AsyncPtyMasterReadHalf {
47 fn as_async_pty_fd(&self, cx: &mut Context<'_>) -> Poll<RawFd> {
48 let l = ready!(self.handle.poll_lock(cx));
49 Poll::Ready(l.as_raw_fd())
50 }
51}
52
53impl AsAsyncPtyFd for &mut AsyncPtyMasterReadHalf {
54 fn as_async_pty_fd(&self, cx: &mut Context<'_>) -> Poll<RawFd> {
55 let l = ready!(self.handle.poll_lock(cx));
56 Poll::Ready(l.as_raw_fd())
57 }
58}
59
60impl AsAsyncPtyFd for AsyncPtyMasterWriteHalf {
61 fn as_async_pty_fd(&self, cx: &mut Context<'_>) -> Poll<RawFd> {
62 let l = ready!(self.handle.poll_lock(cx));
63 Poll::Ready(l.as_raw_fd())
64 }
65}
66
67impl AsAsyncPtyFd for &AsyncPtyMasterWriteHalf {
68 fn as_async_pty_fd(&self, cx: &mut Context<'_>) -> Poll<RawFd> {
69 let l = ready!(self.handle.poll_lock(cx));
70 Poll::Ready(l.as_raw_fd())
71 }
72}
73
74impl AsAsyncPtyFd for &mut AsyncPtyMasterWriteHalf {
75 fn as_async_pty_fd(&self, cx: &mut Context<'_>) -> Poll<RawFd> {
76 let l = ready!(self.handle.poll_lock(cx));
77 Poll::Ready(l.as_raw_fd())
78 }
79}
80
81impl AsyncRead for AsyncPtyMasterReadHalf {
82 fn poll_read(
83 self: std::pin::Pin<&mut Self>,
84 cx: &mut std::task::Context<'_>,
85 buf: &mut [u8],
86 ) -> std::task::Poll<io::Result<usize>> {
87 let mut l = ready!(self.handle.poll_lock(cx));
88 l.as_pin_mut().poll_read(cx, buf)
89 }
90}
91
92impl AsyncWrite for AsyncPtyMasterWriteHalf {
93 fn poll_write(
94 self: std::pin::Pin<&mut Self>,
95 cx: &mut std::task::Context<'_>,
96 buf: &[u8],
97 ) -> Poll<Result<usize, io::Error>> {
98 let mut l = ready!(self.handle.poll_lock(cx));
99 l.as_pin_mut().poll_write(cx, buf)
100 }
101
102 fn poll_flush(
103 self: std::pin::Pin<&mut Self>,
104 cx: &mut std::task::Context<'_>,
105 ) -> Poll<Result<(), io::Error>> {
106 let mut l = ready!(self.handle.poll_lock(cx));
107 l.as_pin_mut().poll_flush(cx)
108 }
109
110 fn poll_shutdown(
111 self: std::pin::Pin<&mut Self>,
112 cx: &mut std::task::Context<'_>,
113 ) -> Poll<Result<(), io::Error>> {
114 let mut l = ready!(self.handle.poll_lock(cx));
115 l.as_pin_mut().poll_shutdown(cx)
116 }
117}