summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/test.rs1
-rw-r--r--test/test_pty.rs92
2 files changed, 93 insertions, 0 deletions
diff --git a/test/test.rs b/test/test.rs
index 1357642e..1f87171d 100644
--- a/test/test.rs
+++ b/test/test.rs
@@ -23,6 +23,7 @@ mod test_mq;
#[cfg(any(target_os = "linux", target_os = "macos"))]
mod test_poll;
+mod test_pty;
use nixtest::assert_size_of;
diff --git a/test/test_pty.rs b/test/test_pty.rs
new file mode 100644
index 00000000..61780421
--- /dev/null
+++ b/test/test_pty.rs
@@ -0,0 +1,92 @@
+use std::path::Path;
+use std::os::unix::prelude::*;
+use nix::fcntl::{O_RDWR, open};
+use nix::pty::*;
+use nix::sys::stat;
+
+/// Test equivalence of `ptsname` and `ptsname_r`
+#[test]
+#[cfg(any(target_os = "android", target_os = "linux"))]
+fn test_ptsname_equivalence() {
+ // Open a new PTTY master
+ let master_fd = posix_openpt(O_RDWR).unwrap();
+ assert!(master_fd.as_raw_fd() > 0);
+
+ // Get the name of the slave
+ let slave_name = 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`
+#[test]
+#[cfg(any(target_os = "android", target_os = "linux"))]
+fn test_ptsname_copy() {
+ // Open a new PTTY master
+ let master_fd = posix_openpt(O_RDWR).unwrap();
+ assert!(master_fd.as_raw_fd() > 0);
+
+ // Get the name of the slave
+ let slave_name1 = ptsname(&master_fd).unwrap();
+ let slave_name2 = ptsname(&master_fd).unwrap();
+ assert!(slave_name1 == slave_name2);
+ // Also make sure that the string was actually copied and they point to different parts of
+ // memory.
+ assert!(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(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!(slave_name1 == slave_name2);
+ assert!(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() {
+ // Open a new PTTY master
+ let master1_fd = posix_openpt(O_RDWR).unwrap();
+ assert!(master1_fd.as_raw_fd() > 0);
+
+ // Open a second PTTY master
+ let master2_fd = posix_openpt(O_RDWR).unwrap();
+ assert!(master2_fd.as_raw_fd() > 0);
+
+ // Get the name of the slave
+ let slave_name1 = ptsname(&master1_fd).unwrap();
+ let slave_name2 = ptsname(&master2_fd).unwrap();
+ assert!(slave_name1 != slave_name2);
+}
+
+/// Test opening a master/slave PTTY pair
+///
+/// This is a single larger test 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 connect master/slave PTTY
+/// pair.
+#[test]
+fn test_open_ptty_pair() {
+ // Open a new PTTY master
+ let master_fd = posix_openpt(O_RDWR).unwrap();
+ assert!(master_fd.as_raw_fd() > 0);
+
+ // Allow a slave to be generated for it
+ grantpt(&master_fd).unwrap();
+ unlockpt(&master_fd).unwrap();
+
+ // Get the name of the slave
+ let slave_name = ptsname(&master_fd).unwrap();
+
+ // Open the slave device
+ let slave_fd = open(Path::new(&slave_name), O_RDWR, stat::Mode::empty()).unwrap();
+ assert!(slave_fd > 0);
+}