Skip to main content

pty/
pty.rs

1// Copyright (c) 2020 Xu Shaohua <shaohua@biofan.org>. All rights reserved.
2// Use of this source is governed by Apache-2.0 License that can be found
3// in the LICENSE file.
4
5fn ptsname(pty_fd: i32) -> Result<String, nc::Errno> {
6    #[allow(unused_mut)]
7    let mut n: i32 = 0;
8    let n_ptr = (&mut n) as *mut i32 as *const _;
9    unsafe { nc::ioctl(pty_fd, nc::TIOCGPTN, n_ptr)? };
10    Ok(format!("/dev/pts/{}", n))
11}
12
13fn unlockpt(pty_fd: i32) -> Result<i32, nc::Errno> {
14    let u: i32 = 0;
15    let u_ptr = &u as *const i32 as *const _;
16    unsafe { nc::ioctl(pty_fd, nc::TIOCSPTLCK, u_ptr) }
17}
18
19fn open_pty() -> Result<(i32, i32), nc::Errno> {
20    #[cfg(any(target_os = "linux", target_os = "android"))]
21    let pty_fd = unsafe { nc::openat(nc::AT_FDCWD, "/dev/ptmx", nc::O_RDWR, 0)? };
22    #[cfg(target_os = "freebsd")]
23    let pty_fd = unsafe { nc::open("/dev/ptmx", nc::O_RDWR, 0)? };
24
25    println!("pty_fd: {}", pty_fd);
26
27    let sname = ptsname(pty_fd)?;
28    println!("sname: {}", sname);
29    unlockpt(pty_fd)?;
30
31    #[cfg(any(target_os = "linux", target_os = "android"))]
32    let tty_fd = unsafe { nc::openat(nc::AT_FDCWD, &sname, nc::O_RDWR | nc::O_NOCTTY, 0)? };
33
34    #[cfg(target_os = "freebsd")]
35    let tty_fd = unsafe { nc::open(&sname, nc::O_RDWR | nc::O_NOCTTY, 0)? };
36
37    println!("tty_fd: {}", tty_fd);
38    Ok((pty_fd, tty_fd))
39}
40
41fn main() {
42    if let Ok((pty, tty)) = open_pty() {
43        println!("pty: {}, tty: {}", pty, tty);
44    }
45}