Merge branch 'termios-func-doc' into 'master'
document termios functions See merge request redox-os/relibc!1526
This commit is contained in:
@@ -21,6 +21,13 @@ pub struct sgttyb {
|
||||
sg_flags: c_ushort,
|
||||
}
|
||||
|
||||
/// Non-POSIX, see <https://www.man7.org/linux/man-pages/man2/ioctl.2.html>.
|
||||
///
|
||||
/// Manipulates the underlying device parameters of special files.
|
||||
///
|
||||
/// Upon success, usually returns `0`. A few operations use the return value
|
||||
/// as an output parameter and returns a nonnegative value on success. Upon
|
||||
/// failure, `-1` is returned and errno set to indicate the error.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn ioctl(fd: c_int, request: c_ulong, out: *mut c_void) -> c_int {
|
||||
// TODO: Somehow support varargs to syscall??
|
||||
|
||||
+184
-70
@@ -91,67 +91,122 @@ pub struct termios {
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/tcgetattr.html>.
|
||||
///
|
||||
/// Gets the parameters associated with the terminal referred to by `fildes`
|
||||
/// and stores them in the termios structure referenced by `termios_p`.
|
||||
///
|
||||
/// Upon success, returns `0`. Upon failure, returns `-1` and sets errno to
|
||||
/// indicate the error.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn tcgetattr(fd: c_int, out: *mut termios) -> c_int {
|
||||
unsafe { sys_ioctl::ioctl(fd, sys_ioctl::TCGETS, out.cast::<c_void>()) }
|
||||
pub unsafe extern "C" fn tcgetattr(fildes: c_int, termios_p: *mut termios) -> c_int {
|
||||
unsafe { sys_ioctl::ioctl(fildes, sys_ioctl::TCGETS, termios_p.cast::<c_void>()) }
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/tcsetattr.html>.
|
||||
///
|
||||
/// Sets the parameters associated with the terminal referred to by `fildes`
|
||||
/// from the termios structure referred to by `termios_p`.
|
||||
///
|
||||
/// Upon success, returns `0`. Upon failure, returns `-1` and sets errno to
|
||||
/// indicate the error.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn tcsetattr(fd: c_int, act: c_int, value: *const termios) -> c_int {
|
||||
if !(0..=2).contains(&act) {
|
||||
platform::ERRNO.set(errno::EINVAL);
|
||||
return -1;
|
||||
pub unsafe extern "C" fn tcsetattr(
|
||||
fildes: c_int,
|
||||
optional_actions: c_int,
|
||||
termios_p: *const termios,
|
||||
) -> c_int {
|
||||
match optional_actions {
|
||||
TCSANOW | TCSADRAIN | TCSAFLUSH => {
|
||||
// This is safe because ioctl shouldn't modify the value
|
||||
unsafe {
|
||||
sys_ioctl::ioctl(
|
||||
fildes,
|
||||
sys_ioctl::TCSETS + optional_actions as c_ulong,
|
||||
termios_p as *mut c_void,
|
||||
)
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
platform::ERRNO.set(errno::EINVAL);
|
||||
-1
|
||||
}
|
||||
}
|
||||
// This is safe because ioctl shouldn't modify the value
|
||||
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>.
|
||||
///
|
||||
/// Obtains the process group ID of the session for which the terminal
|
||||
/// specified by `fildes` is the controlling terminal.
|
||||
///
|
||||
/// Upon success, returns the process group ID of the session associated with
|
||||
/// the terminal. Upon failure, returns `-1` and sets errno to indicate the
|
||||
/// error.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn tcgetsid(fd: c_int) -> pid_t {
|
||||
pub unsafe extern "C" fn tcgetsid(fildes: c_int) -> pid_t {
|
||||
let mut sid = 0;
|
||||
if unsafe { sys_ioctl::ioctl(fd, sys_ioctl::TIOCGSID, (&raw mut sid).cast::<c_void>()) } < 0 {
|
||||
if unsafe { sys_ioctl::ioctl(fildes, sys_ioctl::TIOCGSID, (&raw mut sid).cast::<c_void>()) } < 0
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
sid
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/cfgetispeed.html>.
|
||||
#[cfg(target_os = "linux")]
|
||||
///
|
||||
/// Extracts the input baud rate from the termios structure reference to by
|
||||
/// `termios_p`.
|
||||
///
|
||||
/// Returns a value representing the input baud rate.
|
||||
///
|
||||
/// # Implementation
|
||||
/// Infallible. Always returns a value.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn cfgetispeed(termios_p: *const termios) -> speed_t {
|
||||
unsafe { (*termios_p).__c_ispeed }
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/cfgetispeed.html>.
|
||||
#[cfg(target_os = "redox")]
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn cfgetispeed(termios_p: *const termios) -> speed_t {
|
||||
//TODO
|
||||
0
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
unsafe { (*termios_p).__c_ispeed }
|
||||
}
|
||||
#[cfg(target_os = "redox")]
|
||||
{
|
||||
//TODO
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/cfgetospeed.html>.
|
||||
#[cfg(target_os = "linux")]
|
||||
///
|
||||
/// Extracts the output baud rate from the termios structure reference to by
|
||||
/// `termios_p`.
|
||||
///
|
||||
/// Returns a value representing the output baud rate.
|
||||
///
|
||||
/// # Implementation
|
||||
/// Infallible. Always returns a value.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn cfgetospeed(termios_p: *const termios) -> speed_t {
|
||||
unsafe { (*termios_p).__c_ospeed }
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/cfgetospeed.html>.
|
||||
#[cfg(target_os = "redox")]
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn cfgetospeed(termios_p: *const termios) -> speed_t {
|
||||
//TODO
|
||||
0
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
unsafe { (*termios_p).__c_ospeed }
|
||||
}
|
||||
#[cfg(target_os = "redox")]
|
||||
{
|
||||
//TODO
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/cfsetispeed.html>.
|
||||
#[cfg(target_os = "linux")]
|
||||
///
|
||||
/// Sets the input baud rate stored in the structure pointed to by `termios_p`
|
||||
/// to `speed`.
|
||||
///
|
||||
/// Upon success, returns `0`. Upon failure, returns `-1` and sets errno to
|
||||
/// indicate the error.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn cfsetispeed(termios_p: *mut termios, speed: speed_t) -> c_int {
|
||||
match speed as usize {
|
||||
// TODO redox impl
|
||||
#[cfg(target_os = "linux")]
|
||||
B0..=B38400 | B57600..=B4000000 => {
|
||||
unsafe { (*termios_p).__c_ispeed = speed };
|
||||
0
|
||||
@@ -163,20 +218,18 @@ pub unsafe extern "C" fn cfsetispeed(termios_p: *mut termios, speed: speed_t) ->
|
||||
}
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/cfsetispeed.html>.
|
||||
#[cfg(target_os = "redox")]
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn cfsetispeed(termios_p: *mut termios, speed: speed_t) -> c_int {
|
||||
//TODO
|
||||
platform::ERRNO.set(errno::EINVAL);
|
||||
-1
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/cfsetospeed.html>.
|
||||
#[cfg(target_os = "linux")]
|
||||
///
|
||||
/// Sets the output baud rate stored in the structure pointed to by `termios_p`
|
||||
/// to `speed`.
|
||||
///
|
||||
/// Upon success, returns `0`. Upon failure, returns `-1` and sets errno to
|
||||
/// indicate the error.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn cfsetospeed(termios_p: *mut termios, speed: speed_t) -> c_int {
|
||||
match speed as usize {
|
||||
// TODO redox impl
|
||||
#[cfg(target_os = "linux")]
|
||||
B0..=B38400 | B57600..=B4000000 => {
|
||||
unsafe { (*termios_p).__c_ospeed = speed };
|
||||
0
|
||||
@@ -188,18 +241,18 @@ pub unsafe extern "C" fn cfsetospeed(termios_p: *mut termios, speed: speed_t) ->
|
||||
}
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/cfsetospeed.html>.
|
||||
#[cfg(target_os = "redox")]
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn cfsetospeed(termios_p: *mut termios, speed: speed_t) -> c_int {
|
||||
//TODO
|
||||
platform::ERRNO.set(errno::EINVAL);
|
||||
-1
|
||||
}
|
||||
|
||||
/// Non-POSIX, 4.4 BSD extension
|
||||
// TODO should be guarded by _BSD_SOURCE or _DEFAULT_SOURCE
|
||||
/// Non-POSIX, 4.4 BSD extension, see
|
||||
/// <https://www.man7.org/linux/man-pages/man3/cfsetispeed.3.html>.
|
||||
///
|
||||
/// See <https://www.man7.org/linux/man-pages/man3/cfsetispeed.3.html>.
|
||||
/// Sets both the input and output baud rate stored in the structure pointed to
|
||||
/// by `termios_p` to `speed`.
|
||||
///
|
||||
/// Upon success, returns `0`. Upon failure, returns `-1` and sets errno to
|
||||
/// indicate the error.
|
||||
///
|
||||
/// # Implementation
|
||||
/// Calls `cfsetispeed()` and if successful then calls `cfsetospeed()`.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn cfsetspeed(termios_p: *mut termios, speed: speed_t) -> c_int {
|
||||
let r = unsafe { cfsetispeed(termios_p, speed) };
|
||||
@@ -210,48 +263,109 @@ pub unsafe extern "C" fn cfsetspeed(termios_p: *mut termios, speed: speed_t) ->
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/tcflush.html>.
|
||||
///
|
||||
/// Discards data written to the object referred to by `fildes` but not
|
||||
/// transmitted, or data received but not read, depending on the value of
|
||||
/// `queue_selector`.
|
||||
///
|
||||
/// Upon success, returns `0`. Upon failure, returns `-1` and sets errno to
|
||||
/// indicate the error.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn tcflush(fd: c_int, queue: c_int) -> c_int {
|
||||
unsafe { sys_ioctl::ioctl(fd, sys_ioctl::TCFLSH, queue as *mut c_void) }
|
||||
pub unsafe extern "C" fn tcflush(fildes: c_int, queue_selector: c_int) -> c_int {
|
||||
match queue_selector {
|
||||
TCIFLUSH | TCOFLUSH | TCIOFLUSH => unsafe {
|
||||
sys_ioctl::ioctl(fildes, sys_ioctl::TCFLSH, queue_selector as *mut c_void)
|
||||
},
|
||||
_ => {
|
||||
platform::ERRNO.set(errno::EINVAL);
|
||||
-1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/tcdrain.html>.
|
||||
///
|
||||
/// Blocks until all output written to the object referred to by `fildes` is
|
||||
/// transmitted.
|
||||
///
|
||||
/// Upon success, returns `0`. Upon failure, returns `-1` and sets errno to
|
||||
/// indicate the error.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn tcdrain(fd: c_int) -> c_int {
|
||||
unsafe { sys_ioctl::ioctl(fd, sys_ioctl::TCSBRK, core::ptr::dangling_mut()) }
|
||||
pub unsafe extern "C" fn tcdrain(fildes: c_int) -> c_int {
|
||||
unsafe { sys_ioctl::ioctl(fildes, sys_ioctl::TCSBRK, core::ptr::dangling_mut()) }
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/tcsendbreak.html>.
|
||||
///
|
||||
/// Causes transmission of a continuous stream of zero-valued bits for at least
|
||||
/// 0.25 seconds, and not more than 0.5 seconds.
|
||||
///
|
||||
/// Upon success, returns `0`. Upon failure, returns `-1` and sets errno to
|
||||
/// indicate the error.
|
||||
///
|
||||
/// # Implementation
|
||||
/// This function does not accept a non-zero duration. `_duration` is ignored
|
||||
/// and assumed to be `0`. Matches behaviour of musl.
|
||||
#[unsafe(no_mangle)]
|
||||
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.
|
||||
unsafe { sys_ioctl::ioctl(fd, sys_ioctl::TCSBRK, core::ptr::null_mut()) }
|
||||
pub unsafe extern "C" fn tcsendbreak(fildes: c_int, _duration: c_int) -> c_int {
|
||||
unsafe { sys_ioctl::ioctl(fildes, sys_ioctl::TCSBRK, core::ptr::null_mut()) }
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/tcgetwinsize.html>.
|
||||
///
|
||||
/// Gets the terminal window size associated with the terminal referred to by
|
||||
/// `fildes` and stores it in the winsize structure pointed to by `winsize_p`.
|
||||
///
|
||||
/// Upon success, returns `0`. Upon failure, returns `-1` and sets errno to
|
||||
/// indicate the error.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn tcgetwinsize(fd: c_int, sws: *mut winsize) -> c_int {
|
||||
unsafe { sys_ioctl::ioctl(fd, sys_ioctl::TIOCGWINSZ, sws.cast()) }
|
||||
pub unsafe extern "C" fn tcgetwinsize(fildes: c_int, winsize_p: *mut winsize) -> c_int {
|
||||
unsafe { sys_ioctl::ioctl(fildes, sys_ioctl::TIOCGWINSZ, winsize_p.cast()) }
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/tcsetwinsize.html>.
|
||||
///
|
||||
/// Sets the terminal window size associated with the terminal referred to by
|
||||
/// `fildes` and stores it in the winsize structure pointed to by `winsize_p`.
|
||||
///
|
||||
/// Upon success, returns `0`. Upon failure, returns `-1` and sets errno to
|
||||
/// indicate the error.
|
||||
///
|
||||
/// # Safety
|
||||
/// It is undefined behaviour if the value of the winsize structure pointed to
|
||||
/// by `winsize_p` was not derived from the result of a call to
|
||||
/// `tcsgetwinsize()` on `fildes`.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn tcsetwinsize(fd: c_int, sws: *const winsize) -> c_int {
|
||||
unsafe { sys_ioctl::ioctl(fd, sys_ioctl::TIOCSWINSZ, sws.cast_mut().cast()) }
|
||||
pub unsafe extern "C" fn tcsetwinsize(fildes: c_int, winsize_p: *const winsize) -> c_int {
|
||||
unsafe { sys_ioctl::ioctl(fildes, sys_ioctl::TIOCSWINSZ, winsize_p.cast_mut().cast()) }
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/tcflow.html>.
|
||||
///
|
||||
/// Suspends or restarts transmission or reception of data on the object
|
||||
/// referred to by `fildes`, depending on the value of `action`.
|
||||
///
|
||||
/// Upon success, returns `0`. Upon failure, returns `-1` and sets errno to
|
||||
/// indicate the error.
|
||||
#[unsafe(no_mangle)]
|
||||
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.
|
||||
unsafe { sys_ioctl::ioctl(fd, sys_ioctl::TCXONC, action as *mut _) }
|
||||
pub unsafe extern "C" fn tcflow(fildes: c_int, action: c_int) -> c_int {
|
||||
match action {
|
||||
TCIOFF | TCION | TCOOFF | TCOON => unsafe {
|
||||
sys_ioctl::ioctl(fildes, sys_ioctl::TCXONC, action as *mut _)
|
||||
},
|
||||
_ => {
|
||||
platform::ERRNO.set(errno::EINVAL);
|
||||
-1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Non-POSIX, BSD extension
|
||||
// TODO should be guarded by _BSD_SOURCE or _DEFAULT_SOURCE
|
||||
/// Non-POSIX, BSD extension, see <https://www.man7.org/linux/man-pages/man3/cfmakeraw.3.html>.
|
||||
///
|
||||
/// See <https://www.man7.org/linux/man-pages/man3/cfmakeraw.3.html>.
|
||||
/// Sets the terminal to something similar to "raw" mode: input is available
|
||||
/// character by character, echoing is disabled, and all special processing of
|
||||
/// terminal input and output characters is disabled.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn cfmakeraw(termios_p: *mut termios) {
|
||||
unsafe {
|
||||
|
||||
@@ -715,10 +715,16 @@ pub unsafe extern "C" fn getwd(path_name: *mut c_char) -> *mut c_char {
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/isatty.html>.
|
||||
///
|
||||
/// Checks whether `fildes`, an open file descriptor, is associated with a
|
||||
/// terminal device.
|
||||
///
|
||||
/// Returns `1` to indicate `fildes` is associated with a terminal device or
|
||||
/// returns `0` to indicate it is not.
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn isatty(fd: c_int) -> c_int {
|
||||
pub extern "C" fn isatty(fildes: c_int) -> c_int {
|
||||
let mut t = termios::termios::default();
|
||||
if unsafe { termios::tcgetattr(fd, &raw mut t) == 0 } {
|
||||
if unsafe { termios::tcgetattr(fildes, &raw mut t) == 0 } {
|
||||
1
|
||||
} else {
|
||||
0
|
||||
|
||||
Reference in New Issue
Block a user