xref: /relibc/src/header/termios/mod.rs (revision ae7cee26a661c02341332a200ddf03223a6fb362)
1 //! termios implementation, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/termios.h.html
2 
3 use crate::{
4     header::{errno, sys_ioctl},
5     platform::{self, types::*},
6 };
7 
8 pub use self::sys::*;
9 
10 #[cfg(target_os = "linux")]
11 #[path = "linux.rs"]
12 pub mod sys;
13 
14 #[cfg(target_os = "redox")]
15 #[path = "redox.rs"]
16 pub mod sys;
17 
18 pub type cc_t = u8;
19 pub type speed_t = u32;
20 pub type tcflag_t = u32;
21 
22 pub const TCOOFF: usize = 0;
23 pub const TCOON: usize = 1;
24 pub const TCIOFF: usize = 2;
25 pub const TCION: usize = 3;
26 
27 pub const TCIFLUSH: usize = 0;
28 pub const TCOFLUSH: usize = 1;
29 pub const TCIOFLUSH: usize = 2;
30 
31 pub const TCSANOW: usize = 0;
32 pub const TCSADRAIN: usize = 1;
33 pub const TCSAFLUSH: usize = 2;
34 
35 #[cfg(target_os = "linux")]
36 #[repr(C)]
37 #[derive(Default)]
38 pub struct termios {
39     c_iflag: tcflag_t,
40     c_oflag: tcflag_t,
41     c_cflag: tcflag_t,
42     c_lflag: tcflag_t,
43     c_line: cc_t,
44     c_cc: [cc_t; NCCS],
45     __c_ispeed: speed_t,
46     __c_ospeed: speed_t,
47 }
48 
49 // Must match structure in redox_termios
50 #[cfg(target_os = "redox")]
51 #[repr(C)]
52 #[derive(Default)]
53 pub struct termios {
54     c_iflag: tcflag_t,
55     c_oflag: tcflag_t,
56     c_cflag: tcflag_t,
57     c_lflag: tcflag_t,
58     c_cc: [cc_t; NCCS],
59 }
60 
61 #[no_mangle]
62 pub unsafe extern "C" fn tcgetattr(fd: c_int, out: *mut termios) -> c_int {
63     sys_ioctl::ioctl(fd, sys_ioctl::TCGETS, out as *mut c_void)
64 }
65 
66 #[no_mangle]
67 pub unsafe extern "C" fn tcsetattr(fd: c_int, act: c_int, value: *mut termios) -> c_int {
68     if act < 0 || act > 2 {
69         platform::errno = errno::EINVAL;
70         return -1;
71     }
72     // This is safe because ioctl shouldn't modify the value
73     sys_ioctl::ioctl(fd, sys_ioctl::TCSETS + act as c_ulong, value as *mut c_void)
74 }
75 
76 #[cfg(target_os = "linux")]
77 #[no_mangle]
78 pub unsafe extern "C" fn cfgetispeed(termios_p: *const termios) -> speed_t {
79     (*termios_p).__c_ispeed
80 }
81 
82 #[cfg(target_os = "redox")]
83 #[no_mangle]
84 pub unsafe extern "C" fn cfgetispeed(termios_p: *const termios) -> speed_t {
85     //TODO
86     0
87 }
88 
89 #[cfg(target_os = "linux")]
90 #[no_mangle]
91 pub unsafe extern "C" fn cfgetospeed(termios_p: *const termios) -> speed_t {
92     (*termios_p).__c_ospeed
93 }
94 
95 #[cfg(target_os = "redox")]
96 #[no_mangle]
97 pub unsafe extern "C" fn cfgetospeed(termios_p: *const termios) -> speed_t {
98     //TODO
99     0
100 }
101 
102 #[cfg(target_os = "linux")]
103 #[no_mangle]
104 pub unsafe extern "C" fn cfsetispeed(termios_p: *mut termios, speed: speed_t) -> c_int {
105     match speed as usize {
106         B0..=B38400 | B57600..=B4000000 => {
107             (*termios_p).__c_ispeed = speed;
108             0
109         }
110         _ => {
111             platform::errno = errno::EINVAL;
112             -1
113         }
114     }
115 }
116 
117 #[cfg(target_os = "linux")]
118 #[no_mangle]
119 pub unsafe extern "C" fn cfsetospeed(termios_p: *mut termios, speed: speed_t) -> c_int {
120     match speed as usize {
121         B0..=B38400 | B57600..=B4000000 => {
122             (*termios_p).__c_ospeed = speed;
123             0
124         }
125         _ => {
126             platform::errno = errno::EINVAL;
127             -1
128         }
129     }
130 }
131 
132 #[no_mangle]
133 pub unsafe extern "C" fn tcflush(fd: c_int, queue: c_int) -> c_int {
134     sys_ioctl::ioctl(fd, sys_ioctl::TCFLSH, queue as *mut c_void)
135 }
136 
137 #[no_mangle]
138 pub unsafe extern "C" fn tcdrain(fd: c_int) -> c_int {
139     sys_ioctl::ioctl(fd, sys_ioctl::TCSBRK, 1 as *mut _)
140 }
141 
142 #[no_mangle]
143 pub unsafe extern "C" fn tcsendbreak(fd: c_int, _dur: c_int) -> c_int {
144     // non-zero duration is ignored by musl due to it being
145     // implementation-defined. we do the same.
146     sys_ioctl::ioctl(fd, sys_ioctl::TCSBRK, 0 as *mut _)
147 }
148 
149 #[no_mangle]
150 pub unsafe extern "C" fn tcflow(fd: c_int, action: c_int) -> c_int {
151     // non-zero duration is ignored by musl due to it being
152     // implementation-defined. we do the same.
153     sys_ioctl::ioctl(fd, sys_ioctl::TCXONC, action as *mut _)
154 }
155