summaryrefslogtreecommitdiffstats
path: root/third_party/rust/nix/test/sys/test_termios.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /third_party/rust/nix/test/sys/test_termios.rs
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/nix/test/sys/test_termios.rs')
-rw-r--r--third_party/rust/nix/test/sys/test_termios.rs107
1 files changed, 107 insertions, 0 deletions
diff --git a/third_party/rust/nix/test/sys/test_termios.rs b/third_party/rust/nix/test/sys/test_termios.rs
new file mode 100644
index 0000000000..83919378a7
--- /dev/null
+++ b/third_party/rust/nix/test/sys/test_termios.rs
@@ -0,0 +1,107 @@
+use std::os::unix::io::{AsFd, AsRawFd};
+use tempfile::tempfile;
+
+use nix::errno::Errno;
+use nix::fcntl;
+use nix::pty::openpty;
+use nix::sys::termios::{self, tcgetattr, LocalFlags, OutputFlags};
+use nix::unistd::{read, write};
+
+/// Helper function analogous to `std::io::Write::write_all`, but for `Fd`s
+fn write_all<Fd: AsFd>(f: Fd, buf: &[u8]) {
+ let mut len = 0;
+ while len < buf.len() {
+ len += write(f.as_fd().as_raw_fd(), &buf[len..]).unwrap();
+ }
+}
+
+// Test tcgetattr on a terminal
+#[test]
+fn test_tcgetattr_pty() {
+ // openpty uses ptname(3) internally
+ let _m = crate::PTSNAME_MTX.lock();
+
+ let pty = openpty(None, None).expect("openpty failed");
+ termios::tcgetattr(&pty.slave).unwrap();
+}
+
+// Test tcgetattr on something that isn't a terminal
+#[test]
+fn test_tcgetattr_enotty() {
+ let file = tempfile().unwrap();
+ assert_eq!(termios::tcgetattr(&file).err(), Some(Errno::ENOTTY));
+}
+
+// Test modifying output flags
+#[test]
+fn test_output_flags() {
+ // 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).expect("openpty failed");
+ tcgetattr(&pty.slave).expect("tcgetattr failed")
+ };
+
+ // Make sure postprocessing '\r' isn't specified by default or this test is useless.
+ assert!(!termios
+ .output_flags
+ .contains(OutputFlags::OPOST | OutputFlags::OCRNL));
+
+ // Specify that '\r' characters should be transformed to '\n'
+ // OPOST is specified to enable post-processing
+ termios
+ .output_flags
+ .insert(OutputFlags::OPOST | OutputFlags::OCRNL);
+
+ // Open a pty
+ let pty = openpty(None, &termios).unwrap();
+
+ // Write into the master
+ let string = "foofoofoo\r";
+ write_all(&pty.master, string.as_bytes());
+
+ // Read from the slave verifying that the output has been properly transformed
+ let mut buf = [0u8; 10];
+ crate::read_exact(&pty.slave, &mut buf);
+ let transformed_string = "foofoofoo\n";
+ assert_eq!(&buf, transformed_string.as_bytes());
+}
+
+// Test modifying local flags
+#[test]
+fn test_local_flags() {
+ // 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();
+ tcgetattr(&pty.slave).unwrap()
+ };
+
+ // Make sure echo is specified by default or this test is useless.
+ assert!(termios.local_flags.contains(LocalFlags::ECHO));
+
+ // Disable local echo
+ termios.local_flags.remove(LocalFlags::ECHO);
+
+ // Open a new pty with our modified termios settings
+ let pty = openpty(None, &termios).unwrap();
+
+ // Set the master is in nonblocking mode or reading will never return.
+ let flags = fcntl::fcntl(pty.master.as_raw_fd(), fcntl::F_GETFL).unwrap();
+ let new_flags =
+ fcntl::OFlag::from_bits_truncate(flags) | fcntl::OFlag::O_NONBLOCK;
+ fcntl::fcntl(pty.master.as_raw_fd(), fcntl::F_SETFL(new_flags)).unwrap();
+
+ // Write into the master
+ let string = "foofoofoo\r";
+ write_all(&pty.master, string.as_bytes());
+
+ // Try to read from the master, which should not have anything as echoing was disabled.
+ let mut buf = [0u8; 10];
+ let read = read(pty.master.as_raw_fd(), &mut buf).unwrap_err();
+ assert_eq!(read, Errno::EAGAIN);
+}