relibc: implement cfgetispeed/cfsetispeed on Redox
Replaces the four hard stubs (cfgetispeed, cfgetospeed, cfsetispeed, cfsetospeed) that returned either 0 or EINVAL unconditionally on Redox. The functions were tracked in the Round 7 audit as a 'medium' severity gap (serial tools like minicom, screen, cu that query baud rate would always see 0). The fix: * Adds two non-POSIX extension fields to the Redox termios struct: __c_ispeed and __c_ospeed (both speed_t, default 0). Documented as 'non-POSIX; B0..=B4000000' per BSD conventions. * cfgetispeed now reads termios.__c_ispeed (was 0) * cfgetospeed now reads termios.__c_ospeed (was 0) * cfsetispeed writes termios.__c_ispeed for valid speeds (B0..=B38400, B57600..=B4000000); EINVAL otherwise (was EINVAL for all speeds on Redox) * cfsetospeed writes termios.__c_ospeed for valid speeds (was EINVAL for all speeds on Redox) The added fields are placed after c_cc to match BSD/glibc struct termios layout ordering. Redox has no established userspace ABI for termios yet, so the layout extension is safe. Applications that only call cfget*/cfset*baud functions (and not direct field access) will now get real baud-rate roundtripping. POSIX compliance: the functions now correctly return the stored speed on get, store the requested speed on set, and return -1 with errno=EINVAL for out-of-range speeds.
This commit is contained in:
@@ -91,6 +91,10 @@ pub struct termios {
|
|||||||
pub c_lflag: tcflag_t,
|
pub c_lflag: tcflag_t,
|
||||||
/// Control characters.
|
/// Control characters.
|
||||||
pub c_cc: [cc_t; NCCS],
|
pub c_cc: [cc_t; NCCS],
|
||||||
|
/// Input baud rate (non-POSIX; B0..=B4000000).
|
||||||
|
pub __c_ispeed: speed_t,
|
||||||
|
/// Output baud rate (non-POSIX; B0..=B4000000).
|
||||||
|
pub __c_ospeed: speed_t,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/tcgetattr.html>.
|
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/tcgetattr.html>.
|
||||||
@@ -171,8 +175,7 @@ pub unsafe extern "C" fn cfgetispeed(termios_p: *const termios) -> speed_t {
|
|||||||
}
|
}
|
||||||
#[cfg(target_os = "redox")]
|
#[cfg(target_os = "redox")]
|
||||||
{
|
{
|
||||||
//TODO
|
unsafe { (*termios_p).__c_ispeed }
|
||||||
0
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,8 +196,7 @@ pub unsafe extern "C" fn cfgetospeed(termios_p: *const termios) -> speed_t {
|
|||||||
}
|
}
|
||||||
#[cfg(target_os = "redox")]
|
#[cfg(target_os = "redox")]
|
||||||
{
|
{
|
||||||
//TODO
|
unsafe { (*termios_p).__c_ospeed }
|
||||||
0
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,8 +210,6 @@ pub unsafe extern "C" fn cfgetospeed(termios_p: *const termios) -> speed_t {
|
|||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
pub unsafe extern "C" fn cfsetispeed(termios_p: *mut termios, speed: speed_t) -> c_int {
|
pub unsafe extern "C" fn cfsetispeed(termios_p: *mut termios, speed: speed_t) -> c_int {
|
||||||
match speed as usize {
|
match speed as usize {
|
||||||
// TODO redox impl
|
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
B0..=B38400 | B57600..=B4000000 => {
|
B0..=B38400 | B57600..=B4000000 => {
|
||||||
unsafe { (*termios_p).__c_ispeed = speed };
|
unsafe { (*termios_p).__c_ispeed = speed };
|
||||||
0
|
0
|
||||||
@@ -231,8 +231,6 @@ pub unsafe extern "C" fn cfsetispeed(termios_p: *mut termios, speed: speed_t) ->
|
|||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
pub unsafe extern "C" fn cfsetospeed(termios_p: *mut termios, speed: speed_t) -> c_int {
|
pub unsafe extern "C" fn cfsetospeed(termios_p: *mut termios, speed: speed_t) -> c_int {
|
||||||
match speed as usize {
|
match speed as usize {
|
||||||
// TODO redox impl
|
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
B0..=B38400 | B57600..=B4000000 => {
|
B0..=B38400 | B57600..=B4000000 => {
|
||||||
unsafe { (*termios_p).__c_ospeed = speed };
|
unsafe { (*termios_p).__c_ospeed = speed };
|
||||||
0
|
0
|
||||||
|
|||||||
Reference in New Issue
Block a user