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

Trait Implementations

impl Clear<Flag> for Termios

fn clear(&mut self, flag: Flag)

impl Contains<Flag> for Termios

fn contains(&self, flag: Flag) -> bool

impl Set<Flag> for Termios

fn set(&mut self, flag: Flag)

impl Get for Termios

fn get<T>(&self) -> T where T: GetFrom<Self>

impl Set<CSIZE> for Termios

fn set(&mut self, csize: CSIZE)

impl Clear<Flag> for Termios

fn clear(&mut self, flag: Flag)

impl Contains<Flag> for Termios

fn contains(&self, flag: Flag) -> bool

impl Set<Flag> for Termios

fn set(&mut self, flag: Flag)

impl Clear<Flag> for Termios

fn clear(&mut self, flag: Flag)

impl Contains<Flag> for Termios

fn contains(&self, flag: Flag) -> bool

impl Set<Flag> for Termios

fn set(&mut self, flag: Flag)

impl Clear<Flag> for Termios

fn clear(&mut self, flag: Flag)

impl Contains<Flag> for Termios

fn contains(&self, flag: Flag) -> bool

impl Set<Flag> for Termios

fn set(&mut self, flag: Flag)

impl Debug for Termios

fn fmt(&self, f: &mut Formatter) -> Result

Derived Implementations

impl Copy for Termios

impl Clone for Termios

fn clone(&self) -> Termios

fn clone_from(&mut self, source: &Self)