• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use std::os::unix::io::RawFd;
2 
3 use bitflags::bitflags;
4 use nix::libc;
5 
6 use crate::Result;
7 
8 // These are wrapped in a module because they're `pub` by default
9 mod raw {
10     use nix::libc;
11     use nix::{ioctl_none_bad, ioctl_read, ioctl_read_bad, ioctl_write_ptr, ioctl_write_ptr_bad};
12 
13     ioctl_none_bad!(tiocexcl, libc::TIOCEXCL);
14     ioctl_none_bad!(tiocnxcl, libc::TIOCNXCL);
15     ioctl_read_bad!(tiocmget, libc::TIOCMGET, libc::c_int);
16     ioctl_none_bad!(tiocsbrk, libc::TIOCSBRK);
17     ioctl_none_bad!(tioccbrk, libc::TIOCCBRK);
18 
19     #[cfg(any(target_os = "android", target_os = "linux"))]
20     ioctl_read_bad!(fionread, libc::FIONREAD, libc::c_int);
21 
22     // See: /usr/include/sys/filio.h
23     #[cfg(any(
24         target_os = "dragonfly",
25         target_os = "freebsd",
26         target_os = "ios",
27         target_os = "macos",
28         target_os = "netbsd",
29         target_os = "openbsd"
30     ))]
31     ioctl_read!(fionread, b'f', 127, libc::c_int);
32 
33     #[cfg(any(target_os = "android", target_os = "linux"))]
34     ioctl_read_bad!(tiocoutq, libc::TIOCOUTQ, libc::c_int);
35 
36     // See: /usr/include/sys/ttycom.h
37     #[cfg(any(
38         target_os = "dragonfly",
39         target_os = "freebsd",
40         target_os = "ios",
41         target_os = "macos",
42         target_os = "netbsd",
43         target_os = "openbsd"
44     ))]
45     ioctl_read!(tiocoutq, b't', 115, libc::c_int);
46 
47     ioctl_write_ptr_bad!(tiocmbic, libc::TIOCMBIC, libc::c_int);
48     ioctl_write_ptr_bad!(tiocmbis, libc::TIOCMBIS, libc::c_int);
49     ioctl_read!(
50         #[cfg(any(
51             target_os = "android",
52             all(
53                 target_os = "linux",
54                 not(any(
55                     target_env = "musl",
56                     target_arch = "powerpc",
57                     target_arch = "powerpc64"
58                 ))
59             )
60         ))]
61         tcgets2,
62         b'T',
63         0x2A,
64         libc::termios2
65     );
66     ioctl_write_ptr!(
67         #[cfg(any(
68             target_os = "android",
69             all(
70                 target_os = "linux",
71                 not(any(
72                     target_env = "musl",
73                     target_arch = "powerpc",
74                     target_arch = "powerpc64"
75                 ))
76             )
77         ))]
78         tcsets2,
79         b'T',
80         0x2B,
81         libc::termios2
82     );
83     #[cfg(any(target_os = "ios", target_os = "macos"))]
84     const IOSSIOSPEED: libc::c_ulong = 0x80045402;
85     ioctl_write_ptr_bad!(
86         #[cfg(any(target_os = "ios", target_os = "macos"))]
87         iossiospeed,
88         IOSSIOSPEED,
89         libc::speed_t
90     );
91 }
92 
93 bitflags! {
94     /// Flags to indicate which wires in a serial connection to use
95     pub struct SerialLines: libc::c_int {
96         const DATA_SET_READY = libc::TIOCM_DSR;
97         const DATA_TERMINAL_READY = libc::TIOCM_DTR;
98         const REQUEST_TO_SEND = libc::TIOCM_RTS;
99         const SECONDARY_TRANSMIT = libc::TIOCM_ST;
100         const SECONDARY_RECEIVE = libc::TIOCM_SR;
101         const CLEAR_TO_SEND = libc::TIOCM_CTS;
102         const DATA_CARRIER_DETECT = libc::TIOCM_CAR;
103         const RING = libc::TIOCM_RNG;
104     }
105 }
106 
tiocexcl(fd: RawFd) -> Result<()>107 pub fn tiocexcl(fd: RawFd) -> Result<()> {
108     unsafe { raw::tiocexcl(fd) }
109         .map(|_| ())
110         .map_err(|e| e.into())
111 }
112 
tiocnxcl(fd: RawFd) -> Result<()>113 pub fn tiocnxcl(fd: RawFd) -> Result<()> {
114     unsafe { raw::tiocnxcl(fd) }
115         .map(|_| ())
116         .map_err(|e| e.into())
117 }
118 
tiocmget(fd: RawFd) -> Result<SerialLines>119 pub fn tiocmget(fd: RawFd) -> Result<SerialLines> {
120     let mut status: libc::c_int = 0;
121     unsafe { raw::tiocmget(fd, &mut status) }
122         .map(|_| SerialLines::from_bits_truncate(status))
123         .map_err(|e| e.into())
124 }
125 
tiocsbrk(fd: RawFd) -> Result<()>126 pub fn tiocsbrk(fd: RawFd) -> Result<()> {
127     unsafe { raw::tiocsbrk(fd) }
128         .map(|_| ())
129         .map_err(|e| e.into())
130 }
131 
tioccbrk(fd: RawFd) -> Result<()>132 pub fn tioccbrk(fd: RawFd) -> Result<()> {
133     unsafe { raw::tioccbrk(fd) }
134         .map(|_| ())
135         .map_err(|e| e.into())
136 }
137 
fionread(fd: RawFd) -> Result<u32>138 pub fn fionread(fd: RawFd) -> Result<u32> {
139     let mut retval: libc::c_int = 0;
140     unsafe { raw::fionread(fd, &mut retval) }
141         .map(|_| retval as u32)
142         .map_err(|e| e.into())
143 }
144 
tiocoutq(fd: RawFd) -> Result<u32>145 pub fn tiocoutq(fd: RawFd) -> Result<u32> {
146     let mut retval: libc::c_int = 0;
147     unsafe { raw::tiocoutq(fd, &mut retval) }
148         .map(|_| retval as u32)
149         .map_err(|e| e.into())
150 }
151 
tiocmbic(fd: RawFd, status: SerialLines) -> Result<()>152 pub fn tiocmbic(fd: RawFd, status: SerialLines) -> Result<()> {
153     let bits = status.bits() as libc::c_int;
154     unsafe { raw::tiocmbic(fd, &bits) }
155         .map(|_| ())
156         .map_err(|e| e.into())
157 }
158 
tiocmbis(fd: RawFd, status: SerialLines) -> Result<()>159 pub fn tiocmbis(fd: RawFd, status: SerialLines) -> Result<()> {
160     let bits = status.bits() as libc::c_int;
161     unsafe { raw::tiocmbis(fd, &bits) }
162         .map(|_| ())
163         .map_err(|e| e.into())
164 }
165 
166 #[cfg(any(
167     target_os = "android",
168     all(
169         target_os = "linux",
170         not(any(
171             target_env = "musl",
172             target_arch = "powerpc",
173             target_arch = "powerpc64"
174         ))
175     )
176 ))]
tcgets2(fd: RawFd) -> Result<libc::termios2>177 pub fn tcgets2(fd: RawFd) -> Result<libc::termios2> {
178     let mut options = std::mem::MaybeUninit::uninit();
179     match unsafe { raw::tcgets2(fd, options.as_mut_ptr()) } {
180         Ok(_) => unsafe { Ok(options.assume_init()) },
181         Err(e) => Err(e.into()),
182     }
183 }
184 
185 #[cfg(any(
186     target_os = "android",
187     all(
188         target_os = "linux",
189         not(any(
190             target_env = "musl",
191             target_arch = "powerpc",
192             target_arch = "powerpc64"
193         ))
194     )
195 ))]
tcsets2(fd: RawFd, options: &libc::termios2) -> Result<()>196 pub fn tcsets2(fd: RawFd, options: &libc::termios2) -> Result<()> {
197     unsafe { raw::tcsets2(fd, options) }
198         .map(|_| ())
199         .map_err(|e| e.into())
200 }
201 
202 #[cfg(any(target_os = "ios", target_os = "macos"))]
iossiospeed(fd: RawFd, baud_rate: &libc::speed_t) -> Result<()>203 pub fn iossiospeed(fd: RawFd, baud_rate: &libc::speed_t) -> Result<()> {
204     unsafe { raw::iossiospeed(fd, baud_rate) }
205         .map(|_| ())
206         .map_err(|e| e.into())
207 }
208