summaryrefslogtreecommitdiffstats
path: root/vendor/nix/test/test_pty.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/nix/test/test_pty.rs')
-rw-r--r--vendor/nix/test/test_pty.rs313
1 files changed, 0 insertions, 313 deletions
diff --git a/vendor/nix/test/test_pty.rs b/vendor/nix/test/test_pty.rs
deleted file mode 100644
index 5c27e2d63..000000000
--- a/vendor/nix/test/test_pty.rs
+++ /dev/null
@@ -1,313 +0,0 @@
-use std::fs::File;
-use std::io::{Read, Write};
-use std::os::unix::prelude::*;
-use std::path::Path;
-use tempfile::tempfile;
-
-use libc::{_exit, STDOUT_FILENO};
-use nix::fcntl::{open, OFlag};
-use nix::pty::*;
-use nix::sys::stat;
-use nix::sys::termios::*;
-use nix::unistd::{close, pause, write};
-
-/// Regression test for Issue #659
-/// This is the correct way to explicitly close a `PtyMaster`
-#[test]
-fn test_explicit_close() {
- let mut f = {
- let m = posix_openpt(OFlag::O_RDWR).unwrap();
- close(m.into_raw_fd()).unwrap();
- tempfile().unwrap()
- };
- // This should work. But if there's been a double close, then it will
- // return EBADF
- f.write_all(b"whatever").unwrap();
-}
-
-/// Test equivalence of `ptsname` and `ptsname_r`
-#[test]
-#[cfg(any(target_os = "android", target_os = "linux"))]
-fn test_ptsname_equivalence() {
- let _m = crate::PTSNAME_MTX.lock();
-
- // Open a new PTTY master
- let master_fd = posix_openpt(OFlag::O_RDWR).unwrap();
- assert!(master_fd.as_raw_fd() > 0);
-
- // Get the name of the slave
- let slave_name = unsafe { ptsname(&master_fd) }.unwrap();
- let slave_name_r = ptsname_r(&master_fd).unwrap();
- assert_eq!(slave_name, slave_name_r);
-}
-
-/// Test data copying of `ptsname`
-// TODO need to run in a subprocess, since ptsname is non-reentrant
-#[test]
-#[cfg(any(target_os = "android", target_os = "linux"))]
-fn test_ptsname_copy() {
- let _m = crate::PTSNAME_MTX.lock();
-
- // Open a new PTTY master
- let master_fd = posix_openpt(OFlag::O_RDWR).unwrap();
- assert!(master_fd.as_raw_fd() > 0);
-
- // Get the name of the slave
- let slave_name1 = unsafe { ptsname(&master_fd) }.unwrap();
- let slave_name2 = unsafe { ptsname(&master_fd) }.unwrap();
- assert_eq!(slave_name1, slave_name2);
- // Also make sure that the string was actually copied and they point to different parts of
- // memory.
- assert_ne!(slave_name1.as_ptr(), slave_name2.as_ptr());
-}
-
-/// Test data copying of `ptsname_r`
-#[test]
-#[cfg(any(target_os = "android", target_os = "linux"))]
-fn test_ptsname_r_copy() {
- // Open a new PTTY master
- let master_fd = posix_openpt(OFlag::O_RDWR).unwrap();
- assert!(master_fd.as_raw_fd() > 0);
-
- // Get the name of the slave
- let slave_name1 = ptsname_r(&master_fd).unwrap();
- let slave_name2 = ptsname_r(&master_fd).unwrap();
- assert_eq!(slave_name1, slave_name2);
- assert_ne!(slave_name1.as_ptr(), slave_name2.as_ptr());
-}
-
-/// Test that `ptsname` returns different names for different devices
-#[test]
-#[cfg(any(target_os = "android", target_os = "linux"))]
-fn test_ptsname_unique() {
- let _m = crate::PTSNAME_MTX.lock();
-
- // Open a new PTTY master
- let master1_fd = posix_openpt(OFlag::O_RDWR).unwrap();
- assert!(master1_fd.as_raw_fd() > 0);
-
- // Open a second PTTY master
- let master2_fd = posix_openpt(OFlag::O_RDWR).unwrap();
- assert!(master2_fd.as_raw_fd() > 0);
-
- // Get the name of the slave
- let slave_name1 = unsafe { ptsname(&master1_fd) }.unwrap();
- let slave_name2 = unsafe { ptsname(&master2_fd) }.unwrap();
- assert_ne!(slave_name1, slave_name2);
-}
-
-/// Common setup for testing PTTY pairs
-fn open_ptty_pair() -> (PtyMaster, File) {
- let _m = crate::PTSNAME_MTX.lock();
-
- // Open a new PTTY master
- let master = posix_openpt(OFlag::O_RDWR).expect("posix_openpt failed");
-
- // Allow a slave to be generated for it
- grantpt(&master).expect("grantpt failed");
- unlockpt(&master).expect("unlockpt failed");
-
- // Get the name of the slave
- let slave_name = unsafe { ptsname(&master) }.expect("ptsname failed");
-
- // Open the slave device
- let slave_fd =
- open(Path::new(&slave_name), OFlag::O_RDWR, stat::Mode::empty())
- .unwrap();
-
- #[cfg(target_os = "illumos")]
- // TODO: rewrite using ioctl!
- #[allow(clippy::comparison_chain)]
- {
- use libc::{ioctl, I_FIND, I_PUSH};
-
- // On illumos systems, as per pts(7D), one must push STREAMS modules
- // after opening a device path returned from ptsname().
- let ptem = b"ptem\0";
- let ldterm = b"ldterm\0";
- let r = unsafe { ioctl(slave_fd, I_FIND, ldterm.as_ptr()) };
- if r < 0 {
- panic!("I_FIND failure");
- } else if r == 0 {
- if unsafe { ioctl(slave_fd, I_PUSH, ptem.as_ptr()) } < 0 {
- panic!("I_PUSH ptem failure");
- }
- if unsafe { ioctl(slave_fd, I_PUSH, ldterm.as_ptr()) } < 0 {
- panic!("I_PUSH ldterm failure");
- }
- }
- }
-
- let slave = unsafe { File::from_raw_fd(slave_fd) };
-
- (master, slave)
-}
-
-/// Test opening a master/slave PTTY pair
-///
-/// This uses a common `open_ptty_pair` because much of these functions aren't useful by
-/// themselves. So for this test we perform the basic act of getting a file handle for a
-/// master/slave PTTY pair, then just sanity-check the raw values.
-#[test]
-fn test_open_ptty_pair() {
- let (master, slave) = open_ptty_pair();
- assert!(master.as_raw_fd() > 0);
- assert!(slave.as_raw_fd() > 0);
-}
-
-/// Put the terminal in raw mode.
-fn make_raw(fd: RawFd) {
- let mut termios = tcgetattr(fd).unwrap();
- cfmakeraw(&mut termios);
- tcsetattr(fd, SetArg::TCSANOW, &termios).unwrap();
-}
-
-/// Test `io::Read` on the PTTY master
-#[test]
-fn test_read_ptty_pair() {
- let (mut master, mut slave) = open_ptty_pair();
- make_raw(slave.as_raw_fd());
-
- let mut buf = [0u8; 5];
- slave.write_all(b"hello").unwrap();
- master.read_exact(&mut buf).unwrap();
- assert_eq!(&buf, b"hello");
-
- let mut master = &master;
- slave.write_all(b"hello").unwrap();
- master.read_exact(&mut buf).unwrap();
- assert_eq!(&buf, b"hello");
-}
-
-/// Test `io::Write` on the PTTY master
-#[test]
-fn test_write_ptty_pair() {
- let (mut master, mut slave) = open_ptty_pair();
- make_raw(slave.as_raw_fd());
-
- let mut buf = [0u8; 5];
- master.write_all(b"adios").unwrap();
- slave.read_exact(&mut buf).unwrap();
- assert_eq!(&buf, b"adios");
-
- let mut master = &master;
- master.write_all(b"adios").unwrap();
- slave.read_exact(&mut buf).unwrap();
- assert_eq!(&buf, b"adios");
-}
-
-#[test]
-fn test_openpty() {
- // openpty uses ptname(3) internally
- let _m = crate::PTSNAME_MTX.lock();
-
- let pty = openpty(None, None).unwrap();
- assert!(pty.master > 0);
- assert!(pty.slave > 0);
-
- // Writing to one should be readable on the other one
- let string = "foofoofoo\n";
- let mut buf = [0u8; 10];
- write(pty.master, string.as_bytes()).unwrap();
- crate::read_exact(pty.slave, &mut buf);
-
- assert_eq!(&buf, string.as_bytes());
-
- // Read the echo as well
- let echoed_string = "foofoofoo\r\n";
- let mut buf = [0u8; 11];
- crate::read_exact(pty.master, &mut buf);
- assert_eq!(&buf, echoed_string.as_bytes());
-
- let string2 = "barbarbarbar\n";
- let echoed_string2 = "barbarbarbar\r\n";
- let mut buf = [0u8; 14];
- write(pty.slave, string2.as_bytes()).unwrap();
- crate::read_exact(pty.master, &mut buf);
-
- assert_eq!(&buf, echoed_string2.as_bytes());
-
- close(pty.master).unwrap();
- close(pty.slave).unwrap();
-}
-
-#[test]
-fn test_openpty_with_termios() {
- // openpty uses ptname(3) internally
- let _m = crate::PTSNAME_MTX.lock();
-
- // Open one pty to get attributes for the second one
- let mut termios = {
- let pty = openpty(None, None).unwrap();
- assert!(pty.master > 0);
- assert!(pty.slave > 0);
- let termios = tcgetattr(pty.slave).unwrap();
- close(pty.master).unwrap();
- close(pty.slave).unwrap();
- termios
- };
- // Make sure newlines are not transformed so the data is preserved when sent.
- termios.output_flags.remove(OutputFlags::ONLCR);
-
- let pty = openpty(None, &termios).unwrap();
- // Must be valid file descriptors
- assert!(pty.master > 0);
- assert!(pty.slave > 0);
-
- // Writing to one should be readable on the other one
- let string = "foofoofoo\n";
- let mut buf = [0u8; 10];
- write(pty.master, string.as_bytes()).unwrap();
- crate::read_exact(pty.slave, &mut buf);
-
- assert_eq!(&buf, string.as_bytes());
-
- // read the echo as well
- let echoed_string = "foofoofoo\n";
- crate::read_exact(pty.master, &mut buf);
- assert_eq!(&buf, echoed_string.as_bytes());
-
- let string2 = "barbarbarbar\n";
- let echoed_string2 = "barbarbarbar\n";
- let mut buf = [0u8; 13];
- write(pty.slave, string2.as_bytes()).unwrap();
- crate::read_exact(pty.master, &mut buf);
-
- assert_eq!(&buf, echoed_string2.as_bytes());
-
- close(pty.master).unwrap();
- close(pty.slave).unwrap();
-}
-
-#[test]
-fn test_forkpty() {
- use nix::sys::signal::*;
- use nix::sys::wait::wait;
- use nix::unistd::ForkResult::*;
- // forkpty calls openpty which uses ptname(3) internally.
- let _m0 = crate::PTSNAME_MTX.lock();
- // forkpty spawns a child process
- let _m1 = crate::FORK_MTX.lock();
-
- let string = "naninani\n";
- let echoed_string = "naninani\r\n";
- let pty = unsafe { forkpty(None, None).unwrap() };
- match pty.fork_result {
- Child => {
- write(STDOUT_FILENO, string.as_bytes()).unwrap();
- pause(); // we need the child to stay alive until the parent calls read
- unsafe {
- _exit(0);
- }
- }
- Parent { child } => {
- let mut buf = [0u8; 10];
- assert!(child.as_raw() > 0);
- crate::read_exact(pty.master, &mut buf);
- kill(child, SIGTERM).unwrap();
- wait().unwrap(); // keep other tests using generic wait from getting our child
- assert_eq!(&buf, echoed_string.as_bytes());
- close(pty.master).unwrap();
- }
- }
-}