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