tab_pty_process/
split.rs

1// Copyright 2018 Peter Williams, Tokio Contributors
2// Copyright 2019 Fabian Freyer
3// Licensed under both the MIT License and the Apache-2.0 license.
4
5//! This module is a clone of
6//! <https://github.com/tokio-rs/tokio/blob/master/tokio-io/src/split.rs>
7//! (commit 1119d57), modified to refer to our AsyncPtyMaster types. We need
8//! to implement the splitting ourselves in order to be able to implement
9//! AsRawFd for the split types.
10
11use 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
29/// Read half of a AsyncPtyMaster, created with AsyncPtyMaster::split.
30pub struct AsyncPtyMasterReadHalf {
31    handle: BiLock<AsyncPtyMaster>,
32}
33
34/// Write half of a AsyncPtyMaster, created with AsyncPtyMaster::split.
35pub 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}