Use unsafe blocks in termios.h implementation

This commit is contained in:
sourceturner
2026-01-18 21:21:03 +01:00
parent 1a7136e6c4
commit 3873cf9a28
+28 -23
View File
@@ -2,6 +2,9 @@
//!
//! See <https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/termios.h.html>.
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use crate::{
header::{
errno,
@@ -71,7 +74,7 @@ pub struct termios {
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/tcgetattr.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn tcgetattr(fd: c_int, out: *mut termios) -> c_int {
sys_ioctl::ioctl(fd, sys_ioctl::TCGETS, out as *mut c_void)
unsafe { sys_ioctl::ioctl(fd, sys_ioctl::TCGETS, out as *mut c_void) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/tcsetattr.html>.
@@ -82,14 +85,14 @@ pub unsafe extern "C" fn tcsetattr(fd: c_int, act: c_int, value: *const termios)
return -1;
}
// This is safe because ioctl shouldn't modify the value
sys_ioctl::ioctl(fd, sys_ioctl::TCSETS + act as c_ulong, value as *mut c_void)
unsafe { sys_ioctl::ioctl(fd, sys_ioctl::TCSETS + act as c_ulong, value as *mut c_void) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/tcgetsid.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn tcgetsid(fd: c_int) -> pid_t {
let mut sid = 0;
if sys_ioctl::ioctl(fd, sys_ioctl::TIOCGSID, (&raw mut sid) as *mut c_void) < 0 {
if unsafe { sys_ioctl::ioctl(fd, sys_ioctl::TIOCGSID, (&raw mut sid) as *mut c_void) } < 0 {
return -1;
}
sid
@@ -99,7 +102,7 @@ pub unsafe extern "C" fn tcgetsid(fd: c_int) -> pid_t {
#[cfg(target_os = "linux")]
#[unsafe(no_mangle)]
pub unsafe extern "C" fn cfgetispeed(termios_p: *const termios) -> speed_t {
(*termios_p).__c_ispeed
unsafe { (*termios_p).__c_ispeed }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/cfgetispeed.html>.
@@ -114,7 +117,7 @@ pub unsafe extern "C" fn cfgetispeed(termios_p: *const termios) -> speed_t {
#[cfg(target_os = "linux")]
#[unsafe(no_mangle)]
pub unsafe extern "C" fn cfgetospeed(termios_p: *const termios) -> speed_t {
(*termios_p).__c_ospeed
unsafe { (*termios_p).__c_ospeed }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/cfgetospeed.html>.
@@ -131,7 +134,7 @@ pub unsafe extern "C" fn cfgetospeed(termios_p: *const termios) -> speed_t {
pub unsafe extern "C" fn cfsetispeed(termios_p: *mut termios, speed: speed_t) -> c_int {
match speed as usize {
B0..=B38400 | B57600..=B4000000 => {
(*termios_p).__c_ispeed = speed;
unsafe { (*termios_p).__c_ispeed = speed };
0
}
_ => {
@@ -156,7 +159,7 @@ pub unsafe extern "C" fn cfsetispeed(termios_p: *mut termios, speed: speed_t) ->
pub unsafe extern "C" fn cfsetospeed(termios_p: *mut termios, speed: speed_t) -> c_int {
match speed as usize {
B0..=B38400 | B57600..=B4000000 => {
(*termios_p).__c_ospeed = speed;
unsafe { (*termios_p).__c_ospeed = speed };
0
}
_ => {
@@ -180,23 +183,23 @@ pub unsafe extern "C" fn cfsetospeed(termios_p: *mut termios, speed: speed_t) ->
/// See <https://www.man7.org/linux/man-pages/man3/cfsetispeed.3.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn cfsetspeed(termios_p: *mut termios, speed: speed_t) -> c_int {
let r = cfsetispeed(termios_p, speed);
let r = unsafe { cfsetispeed(termios_p, speed) };
if r < 0 {
return r;
}
cfsetospeed(termios_p, speed)
unsafe { cfsetospeed(termios_p, speed) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/tcflush.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn tcflush(fd: c_int, queue: c_int) -> c_int {
sys_ioctl::ioctl(fd, sys_ioctl::TCFLSH, queue as *mut c_void)
unsafe { sys_ioctl::ioctl(fd, sys_ioctl::TCFLSH, queue as *mut c_void) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/tcdrain.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn tcdrain(fd: c_int) -> c_int {
sys_ioctl::ioctl(fd, sys_ioctl::TCSBRK, 1 as *mut _)
unsafe { sys_ioctl::ioctl(fd, sys_ioctl::TCSBRK, 1 as *mut _) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/tcsendbreak.html>.
@@ -204,19 +207,19 @@ pub unsafe extern "C" fn tcdrain(fd: c_int) -> c_int {
pub unsafe extern "C" fn tcsendbreak(fd: c_int, _dur: c_int) -> c_int {
// non-zero duration is ignored by musl due to it being
// implementation-defined. we do the same.
sys_ioctl::ioctl(fd, sys_ioctl::TCSBRK, 0 as *mut _)
unsafe { sys_ioctl::ioctl(fd, sys_ioctl::TCSBRK, 0 as *mut _) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/tcgetwinsize.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn tcgetwinsize(fd: c_int, sws: *mut winsize) -> c_int {
sys_ioctl::ioctl(fd, sys_ioctl::TIOCGWINSZ, sws.cast())
unsafe { sys_ioctl::ioctl(fd, sys_ioctl::TIOCGWINSZ, sws.cast()) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/tcsetwinsize.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn tcsetwinsize(fd: c_int, sws: *const winsize) -> c_int {
sys_ioctl::ioctl(fd, sys_ioctl::TIOCSWINSZ, (sws as *mut winsize).cast())
unsafe { sys_ioctl::ioctl(fd, sys_ioctl::TIOCSWINSZ, (sws as *mut winsize).cast()) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/tcflow.html>.
@@ -224,7 +227,7 @@ pub unsafe extern "C" fn tcsetwinsize(fd: c_int, sws: *const winsize) -> c_int {
pub unsafe extern "C" fn tcflow(fd: c_int, action: c_int) -> c_int {
// non-zero duration is ignored by musl due to it being
// implementation-defined. we do the same.
sys_ioctl::ioctl(fd, sys_ioctl::TCXONC, action as *mut _)
unsafe { sys_ioctl::ioctl(fd, sys_ioctl::TCXONC, action as *mut _) }
}
/// Non-POSIX, BSD extension
@@ -232,12 +235,14 @@ pub unsafe extern "C" fn tcflow(fd: c_int, action: c_int) -> c_int {
/// See <https://www.man7.org/linux/man-pages/man3/cfmakeraw.3.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn cfmakeraw(termios_p: *mut termios) {
(*termios_p).c_iflag &=
!(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON) as u32;
(*termios_p).c_oflag &= !OPOST as u32;
(*termios_p).c_lflag &= !(ECHO | ECHONL | ICANON | ISIG | IEXTEN) as u32;
(*termios_p).c_cflag &= !(CSIZE | PARENB) as u32;
(*termios_p).c_cflag |= CS8 as u32;
(*termios_p).c_cc[VMIN] = 1;
(*termios_p).c_cc[VTIME] = 0;
unsafe {
(*termios_p).c_iflag &=
!(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON) as u32;
(*termios_p).c_oflag &= !OPOST as u32;
(*termios_p).c_lflag &= !(ECHO | ECHONL | ICANON | ISIG | IEXTEN) as u32;
(*termios_p).c_cflag &= !(CSIZE | PARENB) as u32;
(*termios_p).c_cflag |= CS8 as u32;
(*termios_p).c_cc[VMIN] = 1;
(*termios_p).c_cc[VTIME] = 0;
}
}