relibc/header/termios/
mod.rs1use crate::{
6 header::{errno, sys_ioctl},
7 platform::{
8 self,
9 types::{c_int, c_uchar, c_uint, c_ulong, c_void, pid_t},
10 },
11};
12
13pub use crate::header::bits_winsize::winsize;
14
15pub use self::sys::*;
16
17#[cfg(target_os = "linux")]
18#[path = "linux.rs"]
19pub mod sys;
20
21#[cfg(target_os = "redox")]
22#[path = "redox.rs"]
23pub mod sys;
24
25pub type cc_t = c_uchar;
27pub type speed_t = c_uint;
29pub type tcflag_t = c_uint;
31
32pub const TCOOFF: c_int = 0;
34pub const TCOON: c_int = 1;
36pub const TCIOFF: c_int = 2;
38pub const TCION: c_int = 3;
40
41pub const TCIFLUSH: c_int = 0;
43pub const TCOFLUSH: c_int = 1;
45pub const TCIOFLUSH: c_int = 2;
47
48pub const TCSANOW: c_int = 0;
50pub const TCSADRAIN: c_int = 1;
52pub const TCSAFLUSH: c_int = 2;
54
55#[cfg(target_os = "linux")]
57#[repr(C)]
58#[derive(Default, Clone)]
59pub struct termios {
60 pub c_iflag: tcflag_t,
62 pub c_oflag: tcflag_t,
64 pub c_cflag: tcflag_t,
66 pub c_lflag: tcflag_t,
68 pub c_line: cc_t,
69 pub c_cc: [cc_t; NCCS],
71 pub __c_ispeed: speed_t,
72 pub __c_ospeed: speed_t,
73}
74
75#[cfg(target_os = "redox")]
78#[repr(C)]
79#[derive(Default, Clone)]
80pub struct termios {
81 pub c_iflag: tcflag_t,
83 pub c_oflag: tcflag_t,
85 pub c_cflag: tcflag_t,
87 pub c_lflag: tcflag_t,
89 pub c_cc: [cc_t; NCCS],
91}
92
93#[unsafe(no_mangle)]
95pub unsafe extern "C" fn tcgetattr(fd: c_int, out: *mut termios) -> c_int {
96 unsafe { sys_ioctl::ioctl(fd, sys_ioctl::TCGETS, out.cast::<c_void>()) }
97}
98
99#[unsafe(no_mangle)]
101pub unsafe extern "C" fn tcsetattr(fd: c_int, act: c_int, value: *const termios) -> c_int {
102 if !(0..=2).contains(&act) {
103 platform::ERRNO.set(errno::EINVAL);
104 return -1;
105 }
106 unsafe { sys_ioctl::ioctl(fd, sys_ioctl::TCSETS + act as c_ulong, value as *mut c_void) }
108}
109
110#[unsafe(no_mangle)]
112pub unsafe extern "C" fn tcgetsid(fd: c_int) -> pid_t {
113 let mut sid = 0;
114 if unsafe { sys_ioctl::ioctl(fd, sys_ioctl::TIOCGSID, (&raw mut sid).cast::<c_void>()) } < 0 {
115 return -1;
116 }
117 sid
118}
119
120#[cfg(target_os = "linux")]
122#[unsafe(no_mangle)]
123pub unsafe extern "C" fn cfgetispeed(termios_p: *const termios) -> speed_t {
124 unsafe { (*termios_p).__c_ispeed }
125}
126
127#[cfg(target_os = "redox")]
129#[unsafe(no_mangle)]
130pub unsafe extern "C" fn cfgetispeed(termios_p: *const termios) -> speed_t {
131 0
133}
134
135#[cfg(target_os = "linux")]
137#[unsafe(no_mangle)]
138pub unsafe extern "C" fn cfgetospeed(termios_p: *const termios) -> speed_t {
139 unsafe { (*termios_p).__c_ospeed }
140}
141
142#[cfg(target_os = "redox")]
144#[unsafe(no_mangle)]
145pub unsafe extern "C" fn cfgetospeed(termios_p: *const termios) -> speed_t {
146 0
148}
149
150#[cfg(target_os = "linux")]
152#[unsafe(no_mangle)]
153pub unsafe extern "C" fn cfsetispeed(termios_p: *mut termios, speed: speed_t) -> c_int {
154 match speed as usize {
155 B0..=B38400 | B57600..=B4000000 => {
156 unsafe { (*termios_p).__c_ispeed = speed };
157 0
158 }
159 _ => {
160 platform::ERRNO.set(errno::EINVAL);
161 -1
162 }
163 }
164}
165
166#[cfg(target_os = "redox")]
168#[unsafe(no_mangle)]
169pub unsafe extern "C" fn cfsetispeed(termios_p: *mut termios, speed: speed_t) -> c_int {
170 platform::ERRNO.set(errno::EINVAL);
172 -1
173}
174
175#[cfg(target_os = "linux")]
177#[unsafe(no_mangle)]
178pub unsafe extern "C" fn cfsetospeed(termios_p: *mut termios, speed: speed_t) -> c_int {
179 match speed as usize {
180 B0..=B38400 | B57600..=B4000000 => {
181 unsafe { (*termios_p).__c_ospeed = speed };
182 0
183 }
184 _ => {
185 platform::ERRNO.set(errno::EINVAL);
186 -1
187 }
188 }
189}
190
191#[cfg(target_os = "redox")]
193#[unsafe(no_mangle)]
194pub unsafe extern "C" fn cfsetospeed(termios_p: *mut termios, speed: speed_t) -> c_int {
195 platform::ERRNO.set(errno::EINVAL);
197 -1
198}
199
200#[unsafe(no_mangle)]
204pub unsafe extern "C" fn cfsetspeed(termios_p: *mut termios, speed: speed_t) -> c_int {
205 let r = unsafe { cfsetispeed(termios_p, speed) };
206 if r < 0 {
207 return r;
208 }
209 unsafe { cfsetospeed(termios_p, speed) }
210}
211
212#[unsafe(no_mangle)]
214pub unsafe extern "C" fn tcflush(fd: c_int, queue: c_int) -> c_int {
215 unsafe { sys_ioctl::ioctl(fd, sys_ioctl::TCFLSH, queue as *mut c_void) }
216}
217
218#[unsafe(no_mangle)]
220pub unsafe extern "C" fn tcdrain(fd: c_int) -> c_int {
221 unsafe { sys_ioctl::ioctl(fd, sys_ioctl::TCSBRK, core::ptr::dangling_mut()) }
222}
223
224#[unsafe(no_mangle)]
226pub unsafe extern "C" fn tcsendbreak(fd: c_int, _dur: c_int) -> c_int {
227 unsafe { sys_ioctl::ioctl(fd, sys_ioctl::TCSBRK, core::ptr::null_mut()) }
230}
231
232#[unsafe(no_mangle)]
234pub unsafe extern "C" fn tcgetwinsize(fd: c_int, sws: *mut winsize) -> c_int {
235 unsafe { sys_ioctl::ioctl(fd, sys_ioctl::TIOCGWINSZ, sws.cast()) }
236}
237
238#[unsafe(no_mangle)]
240pub unsafe extern "C" fn tcsetwinsize(fd: c_int, sws: *const winsize) -> c_int {
241 unsafe { sys_ioctl::ioctl(fd, sys_ioctl::TIOCSWINSZ, sws.cast_mut().cast()) }
242}
243
244#[unsafe(no_mangle)]
246pub unsafe extern "C" fn tcflow(fd: c_int, action: c_int) -> c_int {
247 unsafe { sys_ioctl::ioctl(fd, sys_ioctl::TCXONC, action as *mut _) }
250}
251
252#[unsafe(no_mangle)]
256pub unsafe extern "C" fn cfmakeraw(termios_p: *mut termios) {
257 unsafe {
258 (*termios_p).c_iflag &=
259 !(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON) as u32;
260 (*termios_p).c_oflag &= !OPOST as u32;
261 (*termios_p).c_lflag &= !(ECHO | ECHONL | ICANON | ISIG | IEXTEN) as u32;
262 (*termios_p).c_cflag &= !(CSIZE | PARENB) as u32;
263 (*termios_p).c_cflag |= CS8 as u32;
264 (*termios_p).c_cc[VMIN] = 1;
265 (*termios_p).c_cc[VTIME] = 0;
266 }
267}