pty_process/blocking/
pty.rs

1/// Allocate and return a new pty.
2///
3/// # Errors
4/// Returns an error if the pty failed to be allocated.
5pub fn open() -> crate::Result<(Pty, Pts)> {
6    let pty = crate::sys::Pty::open()?;
7    let pts = pty.pts()?;
8    Ok((Pty(pty), Pts(pts)))
9}
10
11/// An allocated pty
12pub struct Pty(crate::sys::Pty);
13
14impl Pty {
15    /// Use the provided file descriptor as a pty.
16    ///
17    /// # Safety
18    /// The provided file descriptor must be valid, open, and belong to a pty.
19    #[must_use]
20    pub unsafe fn from_fd(fd: std::os::fd::OwnedFd) -> Self {
21        unsafe { Self(crate::sys::Pty::from_fd(fd)) }
22    }
23
24    /// Change the terminal size associated with the pty.
25    ///
26    /// # Errors
27    /// Returns an error if we were unable to set the terminal size.
28    pub fn resize(&self, size: crate::Size) -> crate::Result<()> {
29        self.0.set_term_size(size)
30    }
31}
32
33impl From<Pty> for std::os::fd::OwnedFd {
34    fn from(pty: Pty) -> Self {
35        pty.0.into()
36    }
37}
38
39impl std::os::fd::AsFd for Pty {
40    fn as_fd(&self) -> std::os::fd::BorrowedFd<'_> {
41        self.0.as_fd()
42    }
43}
44
45impl std::os::fd::AsRawFd for Pty {
46    fn as_raw_fd(&self) -> std::os::fd::RawFd {
47        self.0.as_raw_fd()
48    }
49}
50
51impl std::io::Read for Pty {
52    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
53        self.0.read(buf)
54    }
55}
56
57impl std::io::Write for Pty {
58    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
59        self.0.write(buf)
60    }
61
62    fn flush(&mut self) -> std::io::Result<()> {
63        self.0.flush()
64    }
65}
66
67impl std::io::Read for &Pty {
68    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
69        (&self.0).read(buf)
70    }
71}
72
73impl std::io::Write for &Pty {
74    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
75        (&self.0).write(buf)
76    }
77
78    fn flush(&mut self) -> std::io::Result<()> {
79        (&self.0).flush()
80    }
81}
82
83/// The child end of the pty
84///
85/// See [`open`] and [`Command::spawn`](crate::blocking::Command::spawn)
86pub struct Pts(pub(crate) crate::sys::Pts);
87
88impl Pts {
89    /// Use the provided file descriptor as a pts.
90    ///
91    /// # Safety
92    /// The provided file descriptor must be valid, open, and belong to the
93    /// child end of a pty.
94    #[must_use]
95    pub unsafe fn from_fd(fd: std::os::fd::OwnedFd) -> Self {
96        unsafe { Self(crate::sys::Pts::from_fd(fd)) }
97    }
98}
99
100impl std::os::fd::AsFd for Pts {
101    fn as_fd(&self) -> std::os::fd::BorrowedFd<'_> {
102        self.0.as_fd()
103    }
104}
105
106impl std::os::fd::AsRawFd for Pts {
107    fn as_raw_fd(&self) -> std::os::fd::RawFd {
108        self.0.as_raw_fd()
109    }
110}