1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#![feature(libc)]
extern crate libc;
extern crate termios_sys as sys;

pub use sys::*;

use std::os::unix::io::{AsRawFd};
use std::{io};


macro_rules! tio_call {
    ($expr:expr) => (
        match unsafe { $expr } {
            0 => Ok(()),
            _ => Err(io::Error::last_os_error()),
        }
    )
}


pub trait TermIntf {
    fn get_term_attr(&self, tio: &mut sys::termios) -> io::Result<()>;
    fn set_term_attr(&self, optional_actions: libc::c_int,
                     tio: &sys::termios) -> io::Result<()>;

    fn send_break(&self, duration: libc::c_int) -> io::Result<()>;

    fn drain_term(&self) -> io::Result<()>;
    fn flush_term(&self, queue_selector: libc::c_int) -> io::Result<()>;
    fn set_term_flow(&self, action: libc::c_int) -> io::Result<()>;
}


impl<T> TermIntf for T where T: AsRawFd {
    fn get_term_attr(&self, tio: &mut sys::termios) -> io::Result<()> {
        tio_call!( sys::tcgetattr(self.as_raw_fd(), tio) )
    }

    fn set_term_attr(&self, optional_actions: libc::c_int,
                     tio: &sys::termios) -> io::Result<()> {
        tio_call!( sys::tcsetattr(self.as_raw_fd(), optional_actions, tio) )
    }

    fn send_break(&self, duration: libc::c_int) -> io::Result<()> {
        tio_call!( sys::tcsendbreak(self.as_raw_fd(), duration) )
    }

    fn drain_term(&self) -> io::Result<()> {
        tio_call!( sys::tcdrain(self.as_raw_fd()) )
    }

    fn flush_term(&self, queue_selector: libc::c_int) -> io::Result<()> {
        tio_call!( sys::tcflush(self.as_raw_fd(), queue_selector) )
    }

    fn set_term_flow(&self, action: libc::c_int) -> io::Result<()> {
        tio_call!( sys::tcflow(self.as_raw_fd(), action) )
    }
}


pub trait TermiosExt {
    fn make_raw(&mut self);

    fn get_input_speed(&self) -> sys::speed_t;
    fn get_output_speed(&self) -> sys::speed_t;
    fn set_input_speed(&mut self, speed: sys::speed_t) -> io::Result<()>;
    fn set_output_speed(&mut self, speed: sys::speed_t) -> io::Result<()>;
    fn set_io_speed(&mut self, speed: sys::speed_t) -> io::Result<()>;
}


impl TermiosExt for sys::termios {
    fn make_raw(&mut self) {
        unsafe { sys::cfmakeraw(self) };
    }

    fn get_input_speed(&self) -> sys::speed_t {
        unsafe { sys::cfgetispeed(self) }
    }

    fn get_output_speed(&self) -> sys::speed_t {
        unsafe { sys::cfgetospeed(self) }
    }

    fn set_input_speed(&mut self, speed: sys::speed_t) -> io::Result<()> {
        tio_call!( sys::cfsetispeed(self, speed) )
    }

    fn set_output_speed(&mut self, speed: sys::speed_t) -> io::Result<()> {
        tio_call!( sys::cfsetospeed(self, speed) )
    }

    fn set_io_speed(&mut self, speed: sys::speed_t) -> io::Result<()> {
        tio_call!( sys::cfsetspeed(self, speed) )
    }
}