add documentation for functions relating to controlling terminal
This commit is contained in:
@@ -88,14 +88,20 @@ pub const _POSIX_CHILD_MAX: c_long = 25;
|
||||
pub const _POSIX_CLOCKRES_MIN: c_long = 20000000;
|
||||
pub const _POSIX_DELAYTIMER_MAX: c_long = 32;
|
||||
pub const _POSIX_HOST_NAME_MAX: c_long = 255;
|
||||
/// Minimum required value for `LINK_MAX`.
|
||||
pub const _POSIX_LINK_MAX: c_long = 8;
|
||||
pub const _POSIX_LOGIN_NAME_MAX: c_long = 9;
|
||||
/// Minimum required value for `MAX_CANON`.
|
||||
pub const _POSIX_MAX_CANON: c_long = 255;
|
||||
/// Minimum required value for `MAX_INPUT`.
|
||||
pub const _POSIX_MAX_INPUT: c_long = 255;
|
||||
/// Minimum required value for `NAME_MAX`.
|
||||
pub const _POSIX_NAME_MAX: c_long = 14;
|
||||
pub const _POSIX_NGROUPS_MAX: c_long = 8;
|
||||
pub const _POSIX_OPEN_MAX: c_long = 20;
|
||||
/// Minimum required value for `PATH_MAX`.
|
||||
pub const _POSIX_PATH_MAX: c_long = 256;
|
||||
/// Minimum required value for `PIPE_BUF`.
|
||||
pub const _POSIX_PIPE_BUF: c_long = 512;
|
||||
pub const _POSIX_RE_DUP_MAX: c_long = 255;
|
||||
pub const _POSIX_RTSIG_MAX: c_long = 8;
|
||||
@@ -104,6 +110,7 @@ pub const _POSIX_SEM_VALUE_MAX: c_long = 32767;
|
||||
pub const _POSIX_SIGQUEUE_MAX: c_long = 32;
|
||||
pub const _POSIX_SSIZE_MAX: c_long = 32767;
|
||||
pub const _POSIX_STREAM_MAX: c_long = 8;
|
||||
/// Minimum required value for `SYMLINK_MAX`.
|
||||
pub const _POSIX_SYMLINK_MAX: c_long = 255;
|
||||
/// Minimum required value for `SYMLOOP_MAX`.
|
||||
pub const _POSIX_SYMLOOP_MAX: c_long = 8;
|
||||
@@ -138,12 +145,24 @@ pub const RE_DUP_MAX: c_long = _POSIX2_RE_DUP_MAX;
|
||||
pub const HOST_NAME_MAX: c_long = _POSIX_HOST_NAME_MAX;
|
||||
pub const LOGIN_NAME_MAX: c_long = 255;
|
||||
pub const GETENTROPY_MAX: c_long = 256;
|
||||
/// Maximum number of links to a single file.
|
||||
pub const LINK_MAX: c_long = 127;
|
||||
/// Maximum number of bytes that is guaranteed to be atomic when writing to a
|
||||
/// pipe.
|
||||
pub const PIPE_BUF: c_long = 4096;
|
||||
/// Minimum number of bits needed to represent, as a signed integer value, the
|
||||
/// maximum size of a regular file allowed in the specified directory.
|
||||
pub const FILESIZEBITS: c_long = 64;
|
||||
/// Maximum number of bytes in a terminal canonical input line.
|
||||
pub const MAX_CANON: c_long = _POSIX_MAX_CANON;
|
||||
/// Maximum number of bytes for which space is available in a terminal input
|
||||
/// queue; therefore, the maximum number of bytes a conforming application may
|
||||
/// require to be typed as input before reading them.
|
||||
pub const MAX_INPUT: c_long = _POSIX_MAX_INPUT;
|
||||
/// Maximum number of bytes in a symbolic link.
|
||||
pub const SYMLINK_MAX: c_long = _POSIX_SYMLINK_MAX;
|
||||
/// Minimum number of bytes of storage actually allocated for any portion of a
|
||||
/// file.
|
||||
pub const POSIX_ALLOC_SIZE_MIN: c_long = 4096;
|
||||
|
||||
// PTHREAD_DESTRUCTOR_ITERATIONS defined in bits file
|
||||
@@ -153,4 +172,5 @@ pub const PTHREAD_STACK_MIN: c_long = 65536;
|
||||
/// Maximum number of symbolic links that can be reliably traversed in the
|
||||
/// resolution of a pathname in the absence of a loop.
|
||||
pub const SYMLOOP_MAX: c_long = 64;
|
||||
/// Maximum length of terminal device name.
|
||||
pub const TTY_NAME_MAX: c_long = 32; // "/scheme/pty/".len() + size of usize::MAX as string + 1
|
||||
|
||||
@@ -33,6 +33,7 @@ pub const RENAME_EXCHANGE: c_uint = 0x02;
|
||||
pub const RENAME_WHITEOUT: c_uint = 0x04;
|
||||
|
||||
// /dev/tty + nul
|
||||
/// Maximum size of character array to hold `ctermid()` output.
|
||||
pub const L_ctermid: usize = 9;
|
||||
// form of name is /XXXXXX, so 7
|
||||
pub const L_tmpnam: c_int = 7;
|
||||
|
||||
@@ -300,6 +300,25 @@ pub unsafe extern "C" fn clearerr(stream: *mut FILE) {
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/ctermid.html>.
|
||||
///
|
||||
/// Generates a string that, when used as a pathname, refers to the current
|
||||
/// controlling terminal for the current process. If a pathname is returned,
|
||||
/// access to the file is not guaranteed.
|
||||
///
|
||||
/// If `s` is a null pointer, the string is generated in a static area, the
|
||||
/// address of which is returned. If `s` is not a null pointer, `s` is assumed
|
||||
/// to point to a character array of at least `L_ctermid` bytes; the string is
|
||||
/// placed in this array and the value of `s` shall be returned. An empty
|
||||
/// string shall be returned if the pathname that would refer to the
|
||||
/// controlling terminal cannot be determined, or if the function is
|
||||
/// unsuccessful.
|
||||
///
|
||||
/// # Safety
|
||||
/// - The application shall not modify the string returned.
|
||||
/// - The returned pointer might be invalidated or the string content might be
|
||||
/// overwritten by a subsequent call to `ctermid()`.
|
||||
/// - The returned pointer might be invalidated if the calling thread is
|
||||
/// terminated.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn ctermid(s: *mut c_char) -> *mut c_char {
|
||||
static mut TERMID: [u8; L_ctermid] = *b"/dev/tty\0";
|
||||
|
||||
+47
-32
@@ -938,11 +938,25 @@ pub unsafe extern "C" fn posix_openpt(flags: c_int) -> c_int {
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/ptsname.html>.
|
||||
///
|
||||
/// Returns the name of the subsidiary pseudo-terminal device associated with a
|
||||
/// manager pseudo-terminal device.
|
||||
///
|
||||
/// Upon success, returns a pointer to a string which is the name of the
|
||||
/// subsidiary pseudo-terminal device. Upon failure, returns a null pointer and
|
||||
/// sets errno to indicate the error value.
|
||||
///
|
||||
/// # Safety
|
||||
/// - The application shall not modify the string returned.
|
||||
/// - The returned pointer might be invalidated or the string content might be
|
||||
/// overwritten by a subsequent call to `ptsname()`.
|
||||
/// - The returned pointer and string content might be invalidated if the
|
||||
/// calling thread is terminated.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn ptsname(fd: c_int) -> *mut c_char {
|
||||
pub unsafe extern "C" fn ptsname(fildes: c_int) -> *mut c_char {
|
||||
const PTS_BUFFER_LEN: usize = limits::TTY_NAME_MAX as usize;
|
||||
static mut PTS_BUFFER: [c_char; PTS_BUFFER_LEN] = [0; PTS_BUFFER_LEN];
|
||||
let ret = unsafe { ptsname_r(fd, (&raw mut PTS_BUFFER).cast(), PTS_BUFFER_LEN) };
|
||||
let ret = unsafe { ptsname_r(fildes, (&raw mut PTS_BUFFER).cast(), PTS_BUFFER_LEN) };
|
||||
if ret != 0 {
|
||||
platform::ERRNO.set(ret);
|
||||
ptr::null_mut()
|
||||
@@ -952,42 +966,43 @@ pub unsafe extern "C" fn ptsname(fd: c_int) -> *mut c_char {
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/ptsname.html>.
|
||||
///
|
||||
/// Stores the name of the subsidiary pseudo-terminal device corresponding to
|
||||
/// `fildes` in the character array referenced by `name`. The array is
|
||||
/// `namesize` characters long and should have space for the `name` and the
|
||||
/// terminating null character.
|
||||
///
|
||||
/// Upon success, returns `0`. Upon failure, an error number is returned to
|
||||
/// indicate the error.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn ptsname_r(fd: c_int, buf: *mut c_char, buflen: size_t) -> c_int {
|
||||
if buf.is_null() {
|
||||
platform::ERRNO.set(EINVAL);
|
||||
pub unsafe extern "C" fn ptsname_r(fildes: c_int, name: *mut c_char, namesize: size_t) -> c_int {
|
||||
if name.is_null() {
|
||||
EINVAL
|
||||
} else {
|
||||
unsafe { __ptsname_r(fd, buf, buflen) }
|
||||
}
|
||||
}
|
||||
let mut pty: c_int = 0;
|
||||
|
||||
// ptsname_r is not allowed to set errno, but it has it as a return value.
|
||||
#[inline(always)]
|
||||
unsafe fn __ptsname_r(fd: c_int, buf: *mut c_char, buflen: size_t) -> c_int {
|
||||
let mut pty: c_int = 0;
|
||||
|
||||
if unsafe { ioctl(fd, TIOCGPTN, ptr::from_mut(&mut pty).cast::<c_void>()) } == 0 {
|
||||
// Linux and Redox use different resource names for PTS's.
|
||||
#[cfg(target_os = "linux")]
|
||||
let name = format!("/dev/pts/{}", pty);
|
||||
#[cfg(target_os = "redox")]
|
||||
let name = format!("/scheme/pty/{}", pty);
|
||||
let len = name.len();
|
||||
// We need + 1 to account for the NUL terminator.
|
||||
if len + 1 > buflen {
|
||||
ERANGE
|
||||
if unsafe { ioctl(fildes, TIOCGPTN, ptr::from_mut(&mut pty).cast::<c_void>()) } == 0 {
|
||||
// Linux and Redox use different resource names for PTS's.
|
||||
#[cfg(target_os = "linux")]
|
||||
let inner_name = format!("/dev/pts/{}", pty);
|
||||
#[cfg(target_os = "redox")]
|
||||
let inner_name = format!("/scheme/pty/{}", pty);
|
||||
let len = inner_name.len();
|
||||
// We need + 1 to account for the NUL terminator.
|
||||
if len + 1 > namesize {
|
||||
ERANGE
|
||||
} else {
|
||||
// we have checked the string will fit in the buffer
|
||||
// so can use strcpy safely
|
||||
let s = inner_name.as_ptr().cast();
|
||||
unsafe { ptr::copy_nonoverlapping(s, name, len) };
|
||||
// NUL-terminate the result.
|
||||
unsafe { *(name.add(len + 1)) = 0 };
|
||||
0
|
||||
}
|
||||
} else {
|
||||
// we have checked the string will fit in the buffer
|
||||
// so can use strcpy safely
|
||||
let s = name.as_ptr().cast();
|
||||
unsafe { ptr::copy_nonoverlapping(s, buf, len) };
|
||||
// NUL-terminate the result.
|
||||
unsafe { *(buf.add(len + 1)) = 0 };
|
||||
0
|
||||
platform::ERRNO.get()
|
||||
}
|
||||
} else {
|
||||
platform::ERRNO.get()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -95,7 +95,3 @@ pub const CS5: usize = 0o000_000;
|
||||
/// Enable echo.
|
||||
pub const ECHO: usize = 0o000_010;
|
||||
/* } c_lflag */
|
||||
|
||||
// POSIX extensions
|
||||
/// Sentinel value to disable a control char.
|
||||
pub const _POSIX_VDISABLE: u8 = 0;
|
||||
|
||||
@@ -87,6 +87,10 @@ pub const STDERR_FILENO: c_int = 2;
|
||||
|
||||
pub const L_cuserid: usize = 9;
|
||||
|
||||
/// This symbol shall be defined to be the value of a character that shall
|
||||
/// disable terminal special character handling.
|
||||
pub const _POSIX_VDISABLE: u8 = 0;
|
||||
|
||||
// confstr constants
|
||||
// These are copied from Rust's libc and match musl as well.
|
||||
pub const _CS_PATH: c_int = 0;
|
||||
@@ -437,6 +441,20 @@ pub extern "C" fn fdatasync(fildes: c_int) -> c_int {
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/fork.html>.
|
||||
///
|
||||
/// Creates a new process. After `fork()`, both the parent and the child
|
||||
/// processes shall be capable of executing independently before either one
|
||||
/// terminates.
|
||||
///
|
||||
/// Upon success, returns `0` to the child process and returns the process ID
|
||||
/// of the child process to the parent process. Upon failure, returns `-1` to
|
||||
/// the parent process, no child process shall be created, and sets errno to
|
||||
/// indicate the error.
|
||||
///
|
||||
/// # Safety
|
||||
/// For locks held by any thread in the calling process that have not been set
|
||||
/// to be process-shared, any attempt by the child process to perform any
|
||||
/// operation on the lock results in undefined behaviour.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn fork() -> pid_t {
|
||||
for prepare in unsafe { &fork_hooks[0] } {
|
||||
@@ -1039,6 +1057,17 @@ pub extern "C" fn setreuid(ruid: uid_t, euid: uid_t) -> c_int {
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/setsid.html>.
|
||||
///
|
||||
/// Creates a new session, if the calling process is not a process group
|
||||
/// leader. Upon return the calling process shall be the session leader of this
|
||||
/// new session, shall be the process group leader of a new process group, and
|
||||
/// shall have no controlling terminal. The process group ID of the calling
|
||||
/// process shall be set equal to the process ID of the calling process. The
|
||||
/// calling process shall be the only process in the new process group and the
|
||||
/// only process in the new session.
|
||||
///
|
||||
/// Upon success, returns the value of the new process group ID of the calling
|
||||
/// process. Upon failure, returns `-1` and sets errno to indicate the error.
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn setsid() -> pid_t {
|
||||
Sys::setsid().or_minus_one_errno()
|
||||
@@ -1123,22 +1152,45 @@ pub extern "C" fn sync() {
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/tcgetpgrp.html>.
|
||||
///
|
||||
/// Returns the value of the process group ID of the foreground process group
|
||||
/// associated with the terminal. Calling this function is allowed from a
|
||||
/// process that is a member of the background process group; however, the
|
||||
/// information may be subsequently changed by a process that is a member of
|
||||
/// the foreground process group.
|
||||
///
|
||||
/// Upon success, returns the value of the process group ID of the foreground
|
||||
/// process group associated with the terminal. If there is no foreground
|
||||
/// process group, returns a value greater than `1` that does not match the
|
||||
/// process group ID of any existing process group. Upon failure, returns `-1`
|
||||
/// and sets errno to indicate the error.
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn tcgetpgrp(fd: c_int) -> pid_t {
|
||||
pub extern "C" fn tcgetpgrp(fildes: c_int) -> pid_t {
|
||||
let mut pgrp = 0;
|
||||
if unsafe { sys_ioctl::ioctl(fd, sys_ioctl::TIOCGPGRP, (&raw mut pgrp).cast()) } < 0 {
|
||||
if unsafe { sys_ioctl::ioctl(fildes, sys_ioctl::TIOCGPGRP, (&raw mut pgrp).cast()) } < 0 {
|
||||
return -1;
|
||||
}
|
||||
pgrp
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/tcsetpgrp.html>.
|
||||
///
|
||||
/// If the process has a controlling terminal, sets the foreground process
|
||||
/// group ID associated with the terminal to `pgid_id`. Using this function
|
||||
/// from a process which is a member of the background process group on a
|
||||
/// `fildes` associated with its controlling terminal shall cause the process
|
||||
/// group to be sent a `SIGTTOU` signal. If the calling thread is blocking
|
||||
/// `SIGTTOU` signals or the process is ignoring `SIGTTOU` signals, the process
|
||||
/// shall be allowed to perform the operation, and no signal is sent.
|
||||
///
|
||||
/// Upon success, returns `0`. Upon failure, returns `-1` and sets errno to
|
||||
/// indicate the error.
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn tcsetpgrp(fd: c_int, pgrp: pid_t) -> c_int {
|
||||
if unsafe { sys_ioctl::ioctl(fd, sys_ioctl::TIOCSPGRP, &raw const pgrp as _) } < 0 {
|
||||
pub extern "C" fn tcsetpgrp(fildes: c_int, pgid_id: pid_t) -> c_int {
|
||||
if unsafe { sys_ioctl::ioctl(fildes, sys_ioctl::TIOCSPGRP, &raw const pgid_id as _) } < 0 {
|
||||
return -1;
|
||||
}
|
||||
pgrp
|
||||
pgid_id
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/truncate.html>.
|
||||
|
||||
@@ -5,7 +5,7 @@ use crate::{
|
||||
FILESIZEBITS, LINK_MAX, MAX_CANON, MAX_INPUT, NAME_MAX, PATH_MAX, PIPE_BUF,
|
||||
POSIX_ALLOC_SIZE_MIN, SYMLINK_MAX,
|
||||
},
|
||||
termios::_POSIX_VDISABLE,
|
||||
unistd::_POSIX_VDISABLE,
|
||||
},
|
||||
platform::{
|
||||
self,
|
||||
@@ -13,27 +13,50 @@ use crate::{
|
||||
},
|
||||
};
|
||||
|
||||
/// Corresponding pathconf constant for `LINK_MAX` from `limits.h`.
|
||||
pub const _PC_LINK_MAX: c_int = 0;
|
||||
/// Corresponding pathconf constant for `MAX_CANON` from `limits.h`.
|
||||
pub const _PC_MAX_CANON: c_int = 1;
|
||||
/// Corresponding pathconf constant for `MAX_INPUT` from `limits.h`.
|
||||
pub const _PC_MAX_INPUT: c_int = 2;
|
||||
/// Corresponding pathconf constant for `NAME_MAX` from `limits.h`.
|
||||
pub const _PC_NAME_MAX: c_int = 3;
|
||||
/// Corresponding pathconf constant for `PATH_MAX` from `limits.h`.
|
||||
pub const _PC_PATH_MAX: c_int = 4;
|
||||
/// Corresponding pathconf constant for `PIPE_BUF` from `limits.h`.
|
||||
pub const _PC_PIPE_BUF: c_int = 5;
|
||||
/// Corresponding pathconf constant for `_POSIX_CHOWN_RESTRICTED` from
|
||||
/// `unistd.h`.
|
||||
pub const _PC_CHOWN_RESTRICTED: c_int = 6;
|
||||
/// Corresponding pathconf constant for `_POSIX_NO_TRUNC` from `unistd.h`.
|
||||
pub const _PC_NO_TRUNC: c_int = 7;
|
||||
/// Check if file (terminal) supports disabling control chars (CC)
|
||||
/// Corresponding pathconf constant for `_POSIX_VDISABLE` from `unistd.h`.
|
||||
pub const _PC_VDISABLE: c_int = 8;
|
||||
/// Corresponding pathconf constant for `_POSIX_SYNC_IO` from `unistd.h`.
|
||||
pub const _PC_SYNC_IO: c_int = 9;
|
||||
/// Corresponding pathconf constant for `_POSIX_ASYNC_IO` from `unistd.h`.
|
||||
pub const _PC_ASYNC_IO: c_int = 10;
|
||||
/// Corresponding pathconf constant for `_POSIX_PRIO_IO` from `unistd.h`.
|
||||
pub const _PC_PRIO_IO: c_int = 11;
|
||||
pub const _PC_SOCK_MAXBUF: c_int = 12;
|
||||
/// Corresponding pathconf constant for `FILESIZEBITS` from `limits.h`.
|
||||
pub const _PC_FILESIZEBITS: c_int = 13;
|
||||
/// Corresponding pathconf constant for `POSIX_REC_INCR_XFER_SIZE` from
|
||||
/// `limits.h`.
|
||||
pub const _PC_REC_INCR_XFER_SIZE: c_int = 14;
|
||||
/// Corresponding pathconf constant for `POSIX_REC_MAX_XFER_SIZE` from
|
||||
/// `limits.h`.
|
||||
pub const _PC_REC_MAX_XFER_SIZE: c_int = 15;
|
||||
/// Corresponding pathconf constant for `POSIX_REC_MIN_XFER_SIZE` from
|
||||
/// `limits.h`.
|
||||
pub const _PC_REC_MIN_XFER_SIZE: c_int = 16;
|
||||
/// Corresponding pathconf constant for `POSIX_REC_XFER_ALIGN` from `limits.h`.
|
||||
pub const _PC_REC_XFER_ALIGN: c_int = 17;
|
||||
/// Corresponding pathconf constant for `POSIX_ALLOC_SIZE_MIN` from `limits.h`.
|
||||
pub const _PC_ALLOC_SIZE_MIN: c_int = 18;
|
||||
/// Corresponding pathconf constant for `SYMLINK_MAX` from `limits.h`.
|
||||
pub const _PC_SYMLINK_MAX: c_int = 19;
|
||||
/// Corresponding pathconf constant for `_POSIX2_SYMLINKS` from `unistd.h`.
|
||||
pub const _PC_2_SYMLINKS: c_int = 20;
|
||||
|
||||
fn pc(name: c_int) -> c_long {
|
||||
@@ -68,12 +91,30 @@ fn pc(name: c_int) -> c_long {
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/fpathconf.html>.
|
||||
///
|
||||
/// Determines the current value of a configurable limit or option (variable)
|
||||
/// that is associated with a file or directory.
|
||||
///
|
||||
/// Upon success, returns the value of the variable corresponding to `name`. If
|
||||
/// `name` is invalid, returns `-1` and sets errno to indicate the error.
|
||||
///
|
||||
/// # Implementation
|
||||
/// `_fildes` is ignored.
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn fpathconf(_fildes: c_int, name: c_int) -> c_long {
|
||||
pc(name)
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/fpathconf.html>.
|
||||
///
|
||||
/// Determines the current value of a configurable limit or option (variable)
|
||||
/// that is associated with a file or directory.
|
||||
///
|
||||
/// Upon success, returns the value of the variable corresponding to `name`. If
|
||||
/// `name` is invalid, returns `-1` and sets errno to indicate the error.
|
||||
///
|
||||
/// # Implementation
|
||||
/// `_path` is ignored.
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn pathconf(_path: *const c_char, name: c_int) -> c_long {
|
||||
pc(name)
|
||||
|
||||
Reference in New Issue
Block a user