• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! libc syscalls supporting `rustix::termios`.
2 //!
3 //! # Safety
4 //!
5 //! See the `rustix::backend::syscalls` module documentation for details.
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;
13 #[cfg(not(target_os = "wasi"))]
14 use crate::io;
15 #[cfg(not(target_os = "wasi"))]
16 use crate::process::{Pid, RawNonZeroPid};
17 #[cfg(not(target_os = "wasi"))]
18 use crate::termios::{Action, OptionalActions, QueueSelector, Speed, Termios, Winsize};
19 use core::mem::MaybeUninit;
20 
21 #[cfg(not(target_os = "wasi"))]
tcgetattr(fd: BorrowedFd<'_>) -> io::Result<Termios>22 pub(crate) fn tcgetattr(fd: BorrowedFd<'_>) -> io::Result<Termios> {
23     let mut result = MaybeUninit::<Termios>::uninit();
24     unsafe {
25         ret(c::tcgetattr(borrowed_fd(fd), result.as_mut_ptr()))?;
26         Ok(result.assume_init())
27     }
28 }
29 
30 #[cfg(not(target_os = "wasi"))]
tcgetpgrp(fd: BorrowedFd<'_>) -> io::Result<Pid>31 pub(crate) fn tcgetpgrp(fd: BorrowedFd<'_>) -> io::Result<Pid> {
32     unsafe {
33         let pid = ret_pid_t(c::tcgetpgrp(borrowed_fd(fd)))?;
34         debug_assert_ne!(pid, 0);
35         Ok(Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(pid)))
36     }
37 }
38 
39 #[cfg(not(target_os = "wasi"))]
tcsetpgrp(fd: BorrowedFd<'_>, pid: Pid) -> io::Result<()>40 pub(crate) fn tcsetpgrp(fd: BorrowedFd<'_>, pid: Pid) -> io::Result<()> {
41     unsafe { ret(c::tcsetpgrp(borrowed_fd(fd), pid.as_raw_nonzero().get())) }
42 }
43 
44 #[cfg(not(target_os = "wasi"))]
tcsetattr( fd: BorrowedFd, optional_actions: OptionalActions, termios: &Termios, ) -> io::Result<()>45 pub(crate) fn tcsetattr(
46     fd: BorrowedFd,
47     optional_actions: OptionalActions,
48     termios: &Termios,
49 ) -> io::Result<()> {
50     unsafe {
51         ret(c::tcsetattr(
52             borrowed_fd(fd),
53             optional_actions as _,
54             termios,
55         ))
56     }
57 }
58 
59 #[cfg(not(target_os = "wasi"))]
tcsendbreak(fd: BorrowedFd) -> io::Result<()>60 pub(crate) fn tcsendbreak(fd: BorrowedFd) -> io::Result<()> {
61     unsafe { ret(c::tcsendbreak(borrowed_fd(fd), 0)) }
62 }
63 
64 #[cfg(not(target_os = "wasi"))]
tcdrain(fd: BorrowedFd) -> io::Result<()>65 pub(crate) fn tcdrain(fd: BorrowedFd) -> io::Result<()> {
66     unsafe { ret(c::tcdrain(borrowed_fd(fd))) }
67 }
68 
69 #[cfg(not(target_os = "wasi"))]
tcflush(fd: BorrowedFd, queue_selector: QueueSelector) -> io::Result<()>70 pub(crate) fn tcflush(fd: BorrowedFd, queue_selector: QueueSelector) -> io::Result<()> {
71     unsafe { ret(c::tcflush(borrowed_fd(fd), queue_selector as _)) }
72 }
73 
74 #[cfg(not(target_os = "wasi"))]
tcflow(fd: BorrowedFd, action: Action) -> io::Result<()>75 pub(crate) fn tcflow(fd: BorrowedFd, action: Action) -> io::Result<()> {
76     unsafe { ret(c::tcflow(borrowed_fd(fd), action as _)) }
77 }
78 
79 #[cfg(not(target_os = "wasi"))]
tcgetsid(fd: BorrowedFd) -> io::Result<Pid>80 pub(crate) fn tcgetsid(fd: BorrowedFd) -> io::Result<Pid> {
81     unsafe {
82         let pid = ret_pid_t(c::tcgetsid(borrowed_fd(fd)))?;
83         debug_assert_ne!(pid, 0);
84         Ok(Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(pid)))
85     }
86 }
87 
88 #[cfg(not(target_os = "wasi"))]
tcsetwinsize(fd: BorrowedFd, winsize: Winsize) -> io::Result<()>89 pub(crate) fn tcsetwinsize(fd: BorrowedFd, winsize: Winsize) -> io::Result<()> {
90     unsafe { ret(c::ioctl(borrowed_fd(fd), c::TIOCSWINSZ, &winsize)) }
91 }
92 
93 #[cfg(not(target_os = "wasi"))]
tcgetwinsize(fd: BorrowedFd) -> io::Result<Winsize>94 pub(crate) fn tcgetwinsize(fd: BorrowedFd) -> io::Result<Winsize> {
95     unsafe {
96         let mut buf = MaybeUninit::<Winsize>::uninit();
97         ret(c::ioctl(
98             borrowed_fd(fd),
99             c::TIOCGWINSZ.into(),
100             buf.as_mut_ptr(),
101         ))?;
102         Ok(buf.assume_init())
103     }
104 }
105 
106 #[cfg(not(target_os = "wasi"))]
107 #[inline]
108 #[must_use]
cfgetospeed(termios: &Termios) -> Speed109 pub(crate) fn cfgetospeed(termios: &Termios) -> Speed {
110     unsafe { c::cfgetospeed(termios) }
111 }
112 
113 #[cfg(not(target_os = "wasi"))]
114 #[inline]
115 #[must_use]
cfgetispeed(termios: &Termios) -> Speed116 pub(crate) fn cfgetispeed(termios: &Termios) -> Speed {
117     unsafe { c::cfgetispeed(termios) }
118 }
119 
120 #[cfg(not(target_os = "wasi"))]
121 #[inline]
cfmakeraw(termios: &mut Termios)122 pub(crate) fn cfmakeraw(termios: &mut Termios) {
123     unsafe { c::cfmakeraw(termios) }
124 }
125 
126 #[cfg(not(target_os = "wasi"))]
127 #[inline]
cfsetospeed(termios: &mut Termios, speed: Speed) -> io::Result<()>128 pub(crate) fn cfsetospeed(termios: &mut Termios, speed: Speed) -> io::Result<()> {
129     unsafe { ret(c::cfsetospeed(termios, speed)) }
130 }
131 
132 #[cfg(not(target_os = "wasi"))]
133 #[inline]
cfsetispeed(termios: &mut Termios, speed: Speed) -> io::Result<()>134 pub(crate) fn cfsetispeed(termios: &mut Termios, speed: Speed) -> io::Result<()> {
135     unsafe { ret(c::cfsetispeed(termios, speed)) }
136 }
137 
138 #[cfg(not(target_os = "wasi"))]
139 #[inline]
cfsetspeed(termios: &mut Termios, speed: Speed) -> io::Result<()>140 pub(crate) fn cfsetspeed(termios: &mut Termios, speed: Speed) -> io::Result<()> {
141     unsafe { ret(c::cfsetspeed(termios, speed)) }
142 }
143 
isatty(fd: BorrowedFd<'_>) -> bool144 pub(crate) fn isatty(fd: BorrowedFd<'_>) -> bool {
145     // Use the return value of `isatty` alone. We don't check `errno` because
146     // we return `bool` rather than `io::Result<bool>`, because we assume
147     // `BorrrowedFd` protects us from `EBADF`, and any other reasonably
148     // anticipated errno value would end up interpreted as "assume it's not a
149     // terminal" anyway.
150     unsafe { c::isatty(borrowed_fd(fd)) != 0 }
151 }
152 
153 #[cfg(feature = "procfs")]
154 #[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))]
ttyname(dirfd: BorrowedFd<'_>, buf: &mut [u8]) -> io::Result<usize>155 pub(crate) fn ttyname(dirfd: BorrowedFd<'_>, buf: &mut [u8]) -> io::Result<usize> {
156     unsafe {
157         // `ttyname_r` returns its error status rather than using `errno`.
158         match c::ttyname_r(borrowed_fd(dirfd), buf.as_mut_ptr().cast(), buf.len()) {
159             0 => Ok(CStr::from_ptr(buf.as_ptr().cast()).to_bytes().len()),
160             err => Err(io::Errno::from_raw_os_error(err)),
161         }
162     }
163 }
164