Struct termios::Termios
[-] [+]
[src]
pub struct Termios { pub iflag: Flags, pub oflag: Flags, pub cflag: Flags, pub lflag: Flags, pub cc: Chars, // some fields omitted }
Safe wrapper around raw::Termios
Fields
iflag | Input flags |
oflag | Output flags |
cflag | Control flags |
lflag | Local flags |
cc | Control characters |
Methods
impl Termios
fn fetch(fd: c_int) -> Result<Termios>
[-]
Returns the Termios
structure associated with the fd
(file descriptor)
Examples
Inspect your TTY.
// examples/stdin.rs #![feature(libc)] extern crate libc; extern crate termios; use termios::prelude::*; fn main() { println!("{:?}", Termios::fetch(libc::STDIN_FILENO).unwrap()); }
$ ./stdin
iflag: ICRNL | IXON
oflag: ONLCR | OPOST
cflag: CS8 | CREAD
lflag: ECHOCTL | ECHOE | ECHOKE | ECHOK | ECHO | ICANON | IEXTEN | ISIG
cc: VDISCARD: 15, VEOF: 4, VEOL2: 0, (..)
ispeed: B38400
ospeed: B38400
$ echo 'this will panic!' | ./stdin
called `Result::unwrap()` on an `Err` value: file descriptor is not a TTY
The second call panicked because ./stdin
's stdin was not connected to a TTY, the
following ASCII art shows how the standard streams are wired in that case:
+-----------------+ `|` +---------------------+
TTY => |stdin stdout| =====> |stdin stdout| => TTY
| `echo` | | `./stdin` |
| stderr| => TTY | stderr| => TTY
+-----------------+ +---------------------+
fn update(&self, fd: c_int, when: When) -> Result<()>
[-]
Updates the Termios
structure associated with the fd
(file descriptor)
Examples
Unbuffered TTY input.
Consider the following application:
// examples/buffered.rs use std::io::{Read, self}; fn main() { let stdin = io::stdin(); for byte in stdin.lock().bytes() { match byte { Err(e) => panic!("{}", e), Ok(byte) => println!("Got {}", byte), } } }
You'll expect the application to print back each byte as you type, however if you run the
application and type: a b c ENTER CTRL+D
, you get the following output:
$ ./buffered
abc
Got 97
Got 98
Got 99
Got 10
You'll notice two things:
- The application prints back what you type.
- The application doesn't process your input until you hit ENTER.
The difference between the observed behavior and your expectations is caused by the TTY (the terminal emulator you are using). By default, the TTY echoes back what you type (this is essential when you are typing commands in a shell!), and also buffers (line by line) your input before sending it to the application.
If you want the application to match your expectations, then you'll have to modify the
behavior of the TTY using Termios
. The following code disables both echoing and line
buffering:
// examples/unbuffered.rs #![feature(libc)] extern crate libc; extern crate termios; use std::io::{Read, self}; use termios::prelude::*; // a.k.a. "Ctrl+D" const END_OF_TRANSMISSION: u8 = 4; fn main() { let old_termios = Termios::fetch(libc::STDIN_FILENO).unwrap(); let mut new_termios = old_termios; // Disable line buffering new_termios.clear(local::Flag::ICANON); // Disable echo new_termios.clear(local::Flag::ECHO); // Change the behavior of the TTY new_termios.update(libc::STDIN_FILENO, When::Now).unwrap(); let stdin = io::stdin(); for byte in stdin.lock().bytes() { match byte { Err(e) => panic!("{}", e), Ok(END_OF_TRANSMISSION) => break, Ok(byte) => println!("Got {}", byte), } } // Restore the original behavior of the TTY old_termios.update(libc::STDIN_FILENO, When::Now).unwrap(); }
If you run this example, you'll receive the "Got XYZ"
message each time you press a key.
fn make_raw(&mut self)
[-]
Puts Termios
in "raw" mode
Examples
Compare "cooked" and "raw" modes
// examples/raw.rs #![feature(libc)] extern crate libc; extern crate termios; use termios::prelude::*; fn main() { let mut termios = Termios::fetch(libc::STDIN_FILENO).unwrap(); println!("Cooked:\n{:?}", termios); termios.make_raw(); println!("\nRaw:\n{:?}", termios); }
Cooked:
iflag: ICRNL | IXON
oflag: ONLCR | OPOST
cflag: CS8 | CREAD
lflag: ECHOCTL | ECHOE | ECHOKE | ECHOK | ECHO | ICANON | IEXTEN | ISIG
cc: VDISCARD: 15, VEOF: 4, VEOL2: 0, (..)
ispeed: B38400
ospeed: B38400
Raw:
iflag:
oflag: ONLCR
cflag: CS8 | CREAD
lflag: ECHOCTL | ECHOE | ECHOKE | ECHOK
cc: VDISCARD: 15, VEOF: 4, VEOL2: 0, (..)
ispeed: B38400
ospeed: B38400
fn ispeed(&self) -> BaudRate
[-]
Returns the input baud rate
fn ospeed(&self) -> BaudRate
[-]
Returns the output baud rate
fn set_ispeed(&mut self, rate: BaudRate)
[-]
Sets the input baud rate
fn set_ospeed(&mut self, rate: BaudRate)
[-]
Sets the output baud rate
fn set_speed(&mut self, rate: BaudRate)
[-]
Sets both the input and the output baud rates
fn as_raw(&self) -> &Termios
[-]
Borrows the safe wrapper as its raw representation
unsafe fn as_raw_mut(&mut self) -> &mut Termios
[-]
Mutably borrows the safe wrapper as its raw representation
unsafe fn from_raw(termios: Termios) -> Termios
[-]
Puts raw::Termios
into a safe wrapper without performing any check
fn into_raw(self) -> Termios
[-]
Converts the safe wrapper into its raw representation