]>
Commit | Line | Data |
---|---|---|
064997fb FG |
1 | //! libc syscalls supporting `rustix::termios`. |
2 | //! | |
3 | //! # Safety | |
4 | //! | |
487cf647 | 5 | //! See the `rustix::backend::syscalls` module documentation for details. |
064997fb FG |
6 | |
7 | use super::super::c; | |
8 | use super::super::conv::{borrowed_fd, ret, ret_pid_t}; | |
9 | use crate::fd::BorrowedFd; | |
10 | #[cfg(feature = "procfs")] | |
11 | #[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] | |
12 | use crate::ffi::CStr; | |
9c376795 | 13 | #[cfg(not(target_os = "wasi"))] |
064997fb | 14 | use crate::io; |
9c376795 | 15 | #[cfg(not(target_os = "wasi"))] |
064997fb | 16 | use crate::process::{Pid, RawNonZeroPid}; |
9c376795 | 17 | #[cfg(not(target_os = "wasi"))] |
064997fb FG |
18 | use crate::termios::{Action, OptionalActions, QueueSelector, Speed, Termios, Winsize}; |
19 | use core::mem::MaybeUninit; | |
064997fb | 20 | |
9c376795 | 21 | #[cfg(not(target_os = "wasi"))] |
064997fb FG |
22 | pub(crate) fn tcgetattr(fd: BorrowedFd<'_>) -> io::Result<Termios> { |
23 | let mut result = MaybeUninit::<Termios>::uninit(); | |
24 | unsafe { | |
487cf647 FG |
25 | ret(c::tcgetattr(borrowed_fd(fd), result.as_mut_ptr()))?; |
26 | Ok(result.assume_init()) | |
064997fb FG |
27 | } |
28 | } | |
29 | ||
353b0b11 FG |
30 | #[cfg(all( |
31 | any(target_os = "android", target_os = "linux"), | |
32 | any( | |
33 | target_arch = "x86", | |
34 | target_arch = "x86_64", | |
35 | target_arch = "x32", | |
36 | target_arch = "riscv64", | |
37 | target_arch = "aarch64", | |
38 | target_arch = "arm", | |
39 | target_arch = "mips", | |
40 | target_arch = "mips64", | |
41 | ) | |
42 | ))] | |
43 | pub(crate) fn tcgetattr2(fd: BorrowedFd<'_>) -> io::Result<crate::termios::Termios2> { | |
44 | let mut result = MaybeUninit::<crate::termios::Termios2>::uninit(); | |
45 | unsafe { | |
46 | ret(c::ioctl(borrowed_fd(fd), c::TCGETS2, result.as_mut_ptr()))?; | |
47 | Ok(result.assume_init()) | |
48 | } | |
49 | } | |
50 | ||
9c376795 | 51 | #[cfg(not(target_os = "wasi"))] |
064997fb FG |
52 | pub(crate) fn tcgetpgrp(fd: BorrowedFd<'_>) -> io::Result<Pid> { |
53 | unsafe { | |
54 | let pid = ret_pid_t(c::tcgetpgrp(borrowed_fd(fd)))?; | |
55 | debug_assert_ne!(pid, 0); | |
56 | Ok(Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(pid))) | |
57 | } | |
58 | } | |
59 | ||
9c376795 | 60 | #[cfg(not(target_os = "wasi"))] |
064997fb FG |
61 | pub(crate) fn tcsetpgrp(fd: BorrowedFd<'_>, pid: Pid) -> io::Result<()> { |
62 | unsafe { ret(c::tcsetpgrp(borrowed_fd(fd), pid.as_raw_nonzero().get())) } | |
63 | } | |
64 | ||
9c376795 | 65 | #[cfg(not(target_os = "wasi"))] |
064997fb FG |
66 | pub(crate) fn tcsetattr( |
67 | fd: BorrowedFd, | |
68 | optional_actions: OptionalActions, | |
69 | termios: &Termios, | |
70 | ) -> io::Result<()> { | |
71 | unsafe { | |
72 | ret(c::tcsetattr( | |
73 | borrowed_fd(fd), | |
74 | optional_actions as _, | |
75 | termios, | |
76 | )) | |
77 | } | |
78 | } | |
79 | ||
353b0b11 FG |
80 | #[cfg(all( |
81 | any(target_os = "android", target_os = "linux"), | |
82 | any( | |
83 | target_arch = "x86", | |
84 | target_arch = "x86_64", | |
85 | target_arch = "x32", | |
86 | target_arch = "riscv64", | |
87 | target_arch = "aarch64", | |
88 | target_arch = "arm", | |
89 | target_arch = "mips", | |
90 | target_arch = "mips64", | |
91 | ) | |
92 | ))] | |
93 | pub(crate) fn tcsetattr2( | |
94 | fd: BorrowedFd, | |
95 | optional_actions: OptionalActions, | |
96 | termios: &crate::termios::Termios2, | |
97 | ) -> io::Result<()> { | |
98 | unsafe { | |
99 | ret(c::ioctl( | |
100 | borrowed_fd(fd), | |
101 | (c::TCSETS2 as u32 + optional_actions as u32) as _, | |
102 | termios, | |
103 | )) | |
104 | } | |
105 | } | |
106 | ||
9c376795 | 107 | #[cfg(not(target_os = "wasi"))] |
064997fb FG |
108 | pub(crate) fn tcsendbreak(fd: BorrowedFd) -> io::Result<()> { |
109 | unsafe { ret(c::tcsendbreak(borrowed_fd(fd), 0)) } | |
110 | } | |
111 | ||
9c376795 | 112 | #[cfg(not(target_os = "wasi"))] |
064997fb FG |
113 | pub(crate) fn tcdrain(fd: BorrowedFd) -> io::Result<()> { |
114 | unsafe { ret(c::tcdrain(borrowed_fd(fd))) } | |
115 | } | |
116 | ||
9c376795 | 117 | #[cfg(not(target_os = "wasi"))] |
064997fb FG |
118 | pub(crate) fn tcflush(fd: BorrowedFd, queue_selector: QueueSelector) -> io::Result<()> { |
119 | unsafe { ret(c::tcflush(borrowed_fd(fd), queue_selector as _)) } | |
120 | } | |
121 | ||
9c376795 | 122 | #[cfg(not(target_os = "wasi"))] |
064997fb FG |
123 | pub(crate) fn tcflow(fd: BorrowedFd, action: Action) -> io::Result<()> { |
124 | unsafe { ret(c::tcflow(borrowed_fd(fd), action as _)) } | |
125 | } | |
126 | ||
9c376795 | 127 | #[cfg(not(target_os = "wasi"))] |
064997fb FG |
128 | pub(crate) fn tcgetsid(fd: BorrowedFd) -> io::Result<Pid> { |
129 | unsafe { | |
130 | let pid = ret_pid_t(c::tcgetsid(borrowed_fd(fd)))?; | |
131 | debug_assert_ne!(pid, 0); | |
132 | Ok(Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(pid))) | |
133 | } | |
134 | } | |
135 | ||
9c376795 | 136 | #[cfg(not(target_os = "wasi"))] |
064997fb FG |
137 | pub(crate) fn tcsetwinsize(fd: BorrowedFd, winsize: Winsize) -> io::Result<()> { |
138 | unsafe { ret(c::ioctl(borrowed_fd(fd), c::TIOCSWINSZ, &winsize)) } | |
139 | } | |
140 | ||
9c376795 | 141 | #[cfg(not(target_os = "wasi"))] |
064997fb FG |
142 | pub(crate) fn tcgetwinsize(fd: BorrowedFd) -> io::Result<Winsize> { |
143 | unsafe { | |
144 | let mut buf = MaybeUninit::<Winsize>::uninit(); | |
145 | ret(c::ioctl( | |
146 | borrowed_fd(fd), | |
147 | c::TIOCGWINSZ.into(), | |
148 | buf.as_mut_ptr(), | |
149 | ))?; | |
150 | Ok(buf.assume_init()) | |
151 | } | |
152 | } | |
153 | ||
9c376795 | 154 | #[cfg(not(target_os = "wasi"))] |
064997fb FG |
155 | #[inline] |
156 | #[must_use] | |
157 | pub(crate) fn cfgetospeed(termios: &Termios) -> Speed { | |
158 | unsafe { c::cfgetospeed(termios) } | |
159 | } | |
160 | ||
9c376795 | 161 | #[cfg(not(target_os = "wasi"))] |
064997fb FG |
162 | #[inline] |
163 | #[must_use] | |
164 | pub(crate) fn cfgetispeed(termios: &Termios) -> Speed { | |
165 | unsafe { c::cfgetispeed(termios) } | |
166 | } | |
167 | ||
9c376795 | 168 | #[cfg(not(target_os = "wasi"))] |
064997fb FG |
169 | #[inline] |
170 | pub(crate) fn cfmakeraw(termios: &mut Termios) { | |
171 | unsafe { c::cfmakeraw(termios) } | |
172 | } | |
173 | ||
9c376795 | 174 | #[cfg(not(target_os = "wasi"))] |
064997fb FG |
175 | #[inline] |
176 | pub(crate) fn cfsetospeed(termios: &mut Termios, speed: Speed) -> io::Result<()> { | |
177 | unsafe { ret(c::cfsetospeed(termios, speed)) } | |
178 | } | |
179 | ||
9c376795 | 180 | #[cfg(not(target_os = "wasi"))] |
064997fb FG |
181 | #[inline] |
182 | pub(crate) fn cfsetispeed(termios: &mut Termios, speed: Speed) -> io::Result<()> { | |
183 | unsafe { ret(c::cfsetispeed(termios, speed)) } | |
184 | } | |
185 | ||
9c376795 | 186 | #[cfg(not(target_os = "wasi"))] |
064997fb FG |
187 | #[inline] |
188 | pub(crate) fn cfsetspeed(termios: &mut Termios, speed: Speed) -> io::Result<()> { | |
189 | unsafe { ret(c::cfsetspeed(termios, speed)) } | |
190 | } | |
191 | ||
192 | pub(crate) fn isatty(fd: BorrowedFd<'_>) -> bool { | |
9c376795 FG |
193 | // Use the return value of `isatty` alone. We don't check `errno` because |
194 | // we return `bool` rather than `io::Result<bool>`, because we assume | |
195 | // `BorrrowedFd` protects us from `EBADF`, and any other reasonably | |
196 | // anticipated errno value would end up interpreted as "assume it's not a | |
197 | // terminal" anyway. | |
198 | unsafe { c::isatty(borrowed_fd(fd)) != 0 } | |
064997fb FG |
199 | } |
200 | ||
201 | #[cfg(feature = "procfs")] | |
202 | #[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] | |
203 | pub(crate) fn ttyname(dirfd: BorrowedFd<'_>, buf: &mut [u8]) -> io::Result<usize> { | |
204 | unsafe { | |
205 | // `ttyname_r` returns its error status rather than using `errno`. | |
206 | match c::ttyname_r(borrowed_fd(dirfd), buf.as_mut_ptr().cast(), buf.len()) { | |
207 | 0 => Ok(CStr::from_ptr(buf.as_ptr().cast()).to_bytes().len()), | |
208 | err => Err(io::Errno::from_raw_os_error(err)), | |
209 | } | |
210 | } | |
211 | } |