From bfde89c7cca199469ab5742da14953e225f0e5a2 Mon Sep 17 00:00:00 2001 From: Peter Limkilde Svendsen Date: Sat, 1 Feb 2025 17:23:36 +0100 Subject: [PATCH 1/5] Add docs and deprecations for unistd.h --- src/header/unistd/mod.rs | 136 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 135 insertions(+), 1 deletion(-) diff --git a/src/header/unistd/mod.rs b/src/header/unistd/mod.rs index 59f16f2665..d4df033f4a 100644 --- a/src/header/unistd/mod.rs +++ b/src/header/unistd/mod.rs @@ -1,4 +1,6 @@ -//! unistd implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/unistd.h.html +//! `unistd.h` implementation. +//! +//! See . use core::{ convert::TryFrom, @@ -64,17 +66,20 @@ unsafe fn init_fork_hooks<'a>() -> &'a mut [LinkedList; 3] { ) } +/// See . #[no_mangle] pub extern "C" fn _exit(status: c_int) -> ! { Sys::exit(status) } +/// See . #[no_mangle] pub unsafe extern "C" fn access(path: *const c_char, mode: c_int) -> c_int { let path = CStr::from_ptr(path); Sys::access(path, mode).map(|()| 0).or_minus_one_errno() } +/// See . #[no_mangle] pub extern "C" fn alarm(seconds: c_uint) -> c_uint { let mut timer = sys_time::itimerval { @@ -97,12 +102,19 @@ pub extern "C" fn alarm(seconds: c_uint) -> c_uint { secs } +/// See . #[no_mangle] pub unsafe extern "C" fn chdir(path: *const c_char) -> c_int { let path = CStr::from_ptr(path); Sys::chdir(path).map(|()| 0).or_minus_one_errno() } +/// See . +/// +/// # Deprecation +/// The `chroot()` function was marked legacy in the System Interface & Headers +/// Issue 5, and removed in Issue 6. +#[deprecated] #[no_mangle] pub unsafe extern "C" fn chroot(path: *const c_char) -> c_int { // TODO: Implement @@ -119,6 +131,7 @@ pub unsafe extern "C" fn set_default_scheme(scheme: *const c_char) -> c_int { .or_minus_one_errno() } +/// See . #[no_mangle] pub unsafe extern "C" fn chown(path: *const c_char, owner: uid_t, group: gid_t) -> c_int { let path = CStr::from_ptr(path); @@ -127,22 +140,26 @@ pub unsafe extern "C" fn chown(path: *const c_char, owner: uid_t, group: gid_t) .or_minus_one_errno() } +/// See . #[no_mangle] pub extern "C" fn close(fildes: c_int) -> c_int { Sys::close(fildes).map(|()| 0).or_minus_one_errno() } +/// See . // #[no_mangle] pub extern "C" fn confstr(name: c_int, buf: *mut c_char, len: size_t) -> size_t { unimplemented!(); } +/// See . #[no_mangle] pub unsafe extern "C" fn crypt(key: *const c_char, salt: *const c_char) -> *mut c_char { let mut data = crypt_data::new(); crypt_r(key, salt, &mut data as *mut _) } +/// Non-POSIX, see . #[no_mangle] pub extern "C" fn daemon(nochdir: c_int, noclose: c_int) -> c_int { if nochdir == 0 { @@ -178,16 +195,23 @@ pub extern "C" fn daemon(nochdir: c_int, noclose: c_int) -> c_int { 0 } +/// See . #[no_mangle] pub extern "C" fn dup(fildes: c_int) -> c_int { Sys::dup(fildes).or_minus_one_errno() } +/// See . #[no_mangle] pub extern "C" fn dup2(fildes: c_int, fildes2: c_int) -> c_int { Sys::dup2(fildes, fildes2).or_minus_one_errno() } +/// See . +/// +/// # Deprecation +/// The `encrypt()` function was marked obsolescent in the Open Group Base Specifications Issue 8. +#[deprecated] // #[no_mangle] pub extern "C" fn encrypt(block: [c_char; 64], edflag: c_int) { unimplemented!(); @@ -238,6 +262,7 @@ unsafe fn with_argv( -1 } +/// See . #[no_mangle] pub unsafe extern "C" fn execl( path: *const c_char, @@ -249,6 +274,7 @@ pub unsafe extern "C" fn execl( }) } +/// See . #[no_mangle] pub unsafe extern "C" fn execle( path: *const c_char, @@ -261,6 +287,7 @@ pub unsafe extern "C" fn execle( }) } +/// See . #[no_mangle] pub unsafe extern "C" fn execlp( file: *const c_char, @@ -272,11 +299,13 @@ pub unsafe extern "C" fn execlp( }) } +/// See . #[no_mangle] pub unsafe extern "C" fn execv(path: *const c_char, argv: *const *mut c_char) -> c_int { execve(path, argv, platform::environ) } +/// See . #[no_mangle] pub unsafe extern "C" fn execve( path: *const c_char, @@ -295,6 +324,7 @@ const PATH_SEPARATOR: u8 = b':'; #[cfg(target_os = "redox")] const PATH_SEPARATOR: u8 = b';'; +/// See . #[no_mangle] pub unsafe extern "C" fn execvp(file: *const c_char, argv: *const *mut c_char) -> c_int { let file = CStr::from_ptr(file); @@ -333,6 +363,7 @@ pub unsafe extern "C" fn execvp(file: *const c_char, argv: *const *mut c_char) - } } +/// See . #[no_mangle] pub extern "C" fn fchown(fildes: c_int, owner: uid_t, group: gid_t) -> c_int { Sys::fchown(fildes, owner, group) @@ -340,16 +371,19 @@ pub extern "C" fn fchown(fildes: c_int, owner: uid_t, group: gid_t) -> c_int { .or_minus_one_errno() } +/// See . #[no_mangle] pub extern "C" fn fchdir(fildes: c_int) -> c_int { Sys::fchdir(fildes).map(|()| 0).or_minus_one_errno() } +/// See . #[no_mangle] pub extern "C" fn fdatasync(fildes: c_int) -> c_int { Sys::fdatasync(fildes).map(|()| 0).or_minus_one_errno() } +/// See . #[no_mangle] pub unsafe extern "C" fn fork() -> pid_t { let fork_hooks = init_fork_hooks(); @@ -369,11 +403,13 @@ pub unsafe extern "C" fn fork() -> pid_t { pid } +/// See . #[no_mangle] pub extern "C" fn fsync(fildes: c_int) -> c_int { Sys::fsync(fildes).map(|()| 0).or_minus_one_errno() } +/// See . #[no_mangle] pub extern "C" fn ftruncate(fildes: c_int, length: off_t) -> c_int { Sys::ftruncate(fildes, length) @@ -381,6 +417,7 @@ pub extern "C" fn ftruncate(fildes: c_int, length: off_t) -> c_int { .or_minus_one_errno() } +/// See . #[no_mangle] pub unsafe extern "C" fn getcwd(mut buf: *mut c_char, mut size: size_t) -> *mut c_char { let alloc = buf.is_null(); @@ -416,6 +453,12 @@ pub unsafe extern "C" fn getcwd(mut buf: *mut c_char, mut size: size_t) -> *mut } } +/// See . +/// +/// # Deprecation +/// The `getdtablesize()` function was marked legacy in the System Interface & +/// Headers Issue 5, and removed in Issue 6. +#[deprecated] #[no_mangle] pub extern "C" fn getdtablesize() -> c_int { let mut lim = mem::MaybeUninit::::uninit(); @@ -435,31 +478,37 @@ pub extern "C" fn getdtablesize() -> c_int { -1 } +/// See . #[no_mangle] pub extern "C" fn getegid() -> gid_t { Sys::getegid() } +/// See . #[no_mangle] pub extern "C" fn geteuid() -> uid_t { Sys::geteuid() } +/// See . #[no_mangle] pub extern "C" fn getgid() -> gid_t { Sys::getgid() } +/// See . #[no_mangle] pub unsafe extern "C" fn getgroups(size: c_int, list: *mut gid_t) -> c_int { Sys::getgroups(size, list).or_minus_one_errno() } +/// See . // #[no_mangle] pub extern "C" fn gethostid() -> c_long { unimplemented!(); } +/// See . #[no_mangle] pub unsafe extern "C" fn gethostname(mut name: *mut c_char, mut len: size_t) -> c_int { let mut uts = mem::MaybeUninit::::uninit(); @@ -489,6 +538,7 @@ pub unsafe extern "C" fn gethostname(mut name: *mut c_char, mut len: size_t) -> 0 } +/// See . #[no_mangle] pub unsafe extern "C" fn getlogin() -> *mut c_char { static mut LOGIN: [c_char; 256] = [0; 256]; @@ -499,6 +549,7 @@ pub unsafe extern "C" fn getlogin() -> *mut c_char { } } +/// See . #[no_mangle] pub extern "C" fn getlogin_r(name: *mut c_char, namesize: size_t) -> c_int { //TODO: Determine correct getlogin result on Redox @@ -506,6 +557,12 @@ pub extern "C" fn getlogin_r(name: *mut c_char, namesize: size_t) -> c_int { -1 } +/// See . +/// +/// # Deprecation +/// The `getpagesize()` function was marked legacy in the System Interface & +/// Headers Issue 5, and removed in Issue 6. +#[deprecated] #[no_mangle] pub extern "C" fn getpagesize() -> c_int { // Panic if we can't uphold the required behavior (no errors are specified for this function) @@ -514,41 +571,54 @@ pub extern "C" fn getpagesize() -> c_int { .expect("page size not representable as type `int`") } +/// See . #[no_mangle] pub extern "C" fn getpgid(pid: pid_t) -> pid_t { Sys::getpgid(pid).or_minus_one_errno() } +/// See . #[no_mangle] pub extern "C" fn getpgrp() -> pid_t { Sys::getpgid(Sys::getpid()).or_minus_one_errno() } +/// See . #[no_mangle] pub extern "C" fn getpid() -> pid_t { Sys::getpid() } +/// See . #[no_mangle] pub extern "C" fn getppid() -> pid_t { Sys::getppid() } +/// See . #[no_mangle] pub extern "C" fn getsid(pid: pid_t) -> pid_t { Sys::getsid(pid).or_minus_one_errno() } +/// See . #[no_mangle] pub extern "C" fn getuid() -> uid_t { Sys::getuid() } +/// See . +/// +/// # Deprecation +/// The `getwd()` function was marked legacy in the Open Group Base +/// Specifications Issue 6, and removed in Issue 7. +#[deprecated] #[no_mangle] pub unsafe extern "C" fn getwd(path_name: *mut c_char) -> *mut c_char { unsafe { getcwd(path_name, limits::PATH_MAX) } } +/// See . #[no_mangle] pub extern "C" fn isatty(fd: c_int) -> c_int { let mut t = termios::termios::default(); @@ -559,6 +629,7 @@ pub extern "C" fn isatty(fd: c_int) -> c_int { } } +/// See . #[no_mangle] pub unsafe extern "C" fn lchown(path: *const c_char, owner: uid_t, group: gid_t) -> c_int { let path = CStr::from_ptr(path); @@ -567,6 +638,7 @@ pub unsafe extern "C" fn lchown(path: *const c_char, owner: uid_t, group: gid_t) .or_minus_one_errno() } +/// See . #[no_mangle] pub unsafe extern "C" fn link(path1: *const c_char, path2: *const c_char) -> c_int { let path1 = CStr::from_ptr(path1); @@ -574,6 +646,7 @@ pub unsafe extern "C" fn link(path1: *const c_char, path2: *const c_char) -> c_i Sys::link(path1, path2).map(|()| 0).or_minus_one_errno() } +/// See . #[no_mangle] pub unsafe extern "C" fn lockf(fildes: c_int, function: c_int, size: off_t) -> c_int { let mut fl = fcntl::flock { @@ -613,26 +686,31 @@ pub unsafe extern "C" fn lockf(fildes: c_int, function: c_int, size: off_t) -> c }; } +/// See . #[no_mangle] pub extern "C" fn lseek(fildes: c_int, offset: off_t, whence: c_int) -> off_t { Sys::lseek(fildes, offset, whence).or_minus_one_errno() } +/// See . // #[no_mangle] pub extern "C" fn nice(incr: c_int) -> c_int { unimplemented!(); } +/// See . // #[no_mangle] pub extern "C" fn pause() -> c_int { unimplemented!(); } +/// See . #[no_mangle] pub unsafe extern "C" fn pipe(fildes: *mut c_int) -> c_int { pipe2(fildes, 0) } +/// See . #[no_mangle] pub unsafe extern "C" fn pipe2(fildes: *mut c_int, flags: c_int) -> c_int { Sys::pipe2(slice::from_raw_parts_mut(fildes, 2), flags) @@ -640,6 +718,7 @@ pub unsafe extern "C" fn pipe2(fildes: *mut c_int, flags: c_int) -> c_int { .or_minus_one_errno() } +/// See . #[no_mangle] pub unsafe extern "C" fn pread( fildes: c_int, @@ -656,6 +735,9 @@ pub unsafe extern "C" fn pread( .or_minus_one_errno() } +/// See . +/// +/// TODO: specified in `pthread.h` in modern POSIX #[no_mangle] pub extern "C" fn pthread_atfork( prepare: Option, @@ -675,6 +757,7 @@ pub extern "C" fn pthread_atfork( 0 } +/// See . #[no_mangle] pub unsafe extern "C" fn pwrite( fildes: c_int, @@ -691,6 +774,7 @@ pub unsafe extern "C" fn pwrite( .or_minus_one_errno() } +/// See . #[no_mangle] pub unsafe extern "C" fn read(fildes: c_int, buf: *const c_void, nbyte: size_t) -> ssize_t { let buf = unsafe { slice::from_raw_parts_mut(buf as *mut u8, nbyte as usize) }; @@ -705,6 +789,7 @@ pub unsafe extern "C" fn read(fildes: c_int, buf: *const c_void, nbyte: size_t) ) } +/// See . #[no_mangle] pub unsafe extern "C" fn readlink( path: *const c_char, @@ -718,12 +803,14 @@ pub unsafe extern "C" fn readlink( .or_minus_one_errno() } +/// See . #[no_mangle] pub unsafe extern "C" fn rmdir(path: *const c_char) -> c_int { let path = CStr::from_ptr(path); Sys::rmdir(path).map(|()| 0).or_minus_one_errno() } +/// See . #[no_mangle] pub extern "C" fn setgid(gid: gid_t) -> c_int { Sys::setresgid(gid, gid, -1) @@ -731,27 +818,40 @@ pub extern "C" fn setgid(gid: gid_t) -> c_int { .or_minus_one_errno() } +/// Non-POSIX, see . +/// +/// TODO: specified in `grp.h`? #[no_mangle] pub unsafe extern "C" fn setgroups(size: size_t, list: *const gid_t) -> c_int { Sys::setgroups(size, list).map(|()| 0).or_minus_one_errno() } +/// See . #[no_mangle] pub extern "C" fn setpgid(pid: pid_t, pgid: pid_t) -> c_int { Sys::setpgid(pid, pgid).map(|()| 0).or_minus_one_errno() } +/// See . +/// +/// # Deprecation +/// The `setpgrp()` function was marked obsolescent in the Open Group Base +/// Specifications Issue 7, and removed in Issue 8. +#[deprecated] #[no_mangle] pub extern "C" fn setpgrp() -> pid_t { setpgid(0, 0) } +/// See . #[no_mangle] pub extern "C" fn setregid(rgid: gid_t, egid: gid_t) -> c_int { Sys::setresgid(rgid, egid, -1) .map(|()| 0) .or_minus_one_errno() } + +/// See . #[no_mangle] pub extern "C" fn setresgid(rgid: gid_t, egid: gid_t, sgid: gid_t) -> c_int { Sys::setresgid(rgid, egid, sgid) @@ -759,6 +859,7 @@ pub extern "C" fn setresgid(rgid: gid_t, egid: gid_t, sgid: gid_t) -> c_int { .or_minus_one_errno() } +/// See . #[no_mangle] pub extern "C" fn setreuid(ruid: uid_t, euid: uid_t) -> c_int { Sys::setresuid(ruid, euid, -1) @@ -766,17 +867,21 @@ pub extern "C" fn setreuid(ruid: uid_t, euid: uid_t) -> c_int { .or_minus_one_errno() } +/// See . #[no_mangle] pub extern "C" fn setsid() -> pid_t { Sys::setsid().map(|()| 0).or_minus_one_errno() } +/// See . #[no_mangle] pub extern "C" fn setuid(uid: uid_t) -> c_int { Sys::setresuid(uid, uid, -1) .map(|()| 0) .or_minus_one_errno() } + +/// See . #[no_mangle] pub extern "C" fn setresuid(ruid: uid_t, euid: uid_t, suid: uid_t) -> c_int { Sys::setresuid(ruid, euid, suid) @@ -784,6 +889,7 @@ pub extern "C" fn setresuid(ruid: uid_t, euid: uid_t, suid: uid_t) -> c_int { .or_minus_one_errno() } +/// See . #[no_mangle] pub extern "C" fn sleep(seconds: c_uint) -> c_uint { let rqtp = timespec { @@ -804,6 +910,7 @@ pub extern "C" fn sleep(seconds: c_uint) -> c_uint { } } +/// See . #[no_mangle] pub extern "C" fn swab(src: *const c_void, dest: *mut c_void, nbytes: ssize_t) { if nbytes <= 0 { @@ -820,6 +927,7 @@ pub extern "C" fn swab(src: *const c_void, dest: *mut c_void, nbytes: ssize_t) { } } +/// See . #[no_mangle] pub unsafe extern "C" fn symlink(path1: *const c_char, path2: *const c_char) -> c_int { let path1 = CStr::from_ptr(path1); @@ -827,11 +935,13 @@ pub unsafe extern "C" fn symlink(path1: *const c_char, path2: *const c_char) -> Sys::symlink(path1, path2).map(|()| 0).or_minus_one_errno() } +/// See . #[no_mangle] pub extern "C" fn sync() { Sys::sync(); } +/// See . #[no_mangle] pub extern "C" fn tcgetpgrp(fd: c_int) -> pid_t { let mut pgrp = 0; @@ -841,6 +951,7 @@ pub extern "C" fn tcgetpgrp(fd: c_int) -> pid_t { pgrp } +/// See . #[no_mangle] pub extern "C" fn tcsetpgrp(fd: c_int, pgrp: pid_t) -> c_int { if unsafe { sys_ioctl::ioctl(fd, sys_ioctl::TIOCSPGRP, &pgrp as *const pid_t as _) } < 0 { @@ -849,6 +960,7 @@ pub extern "C" fn tcsetpgrp(fd: c_int, pgrp: pid_t) -> c_int { pgrp } +/// See . #[no_mangle] pub unsafe extern "C" fn truncate(path: *const c_char, length: off_t) -> c_int { let file = unsafe { CStr::from_ptr(path) }; @@ -865,6 +977,7 @@ pub unsafe extern "C" fn truncate(path: *const c_char, length: off_t) -> c_int { res } +/// See . #[no_mangle] pub unsafe extern "C" fn ttyname(fildes: c_int) -> *mut c_char { static mut TTYNAME: [c_char; 4096] = [0; 4096]; @@ -875,6 +988,7 @@ pub unsafe extern "C" fn ttyname(fildes: c_int) -> *mut c_char { } } +/// See . #[no_mangle] pub extern "C" fn ttyname_r(fildes: c_int, name: *mut c_char, namesize: size_t) -> c_int { let name = unsafe { slice::from_raw_parts_mut(name as *mut u8, namesize) }; @@ -893,6 +1007,12 @@ pub extern "C" fn ttyname_r(fildes: c_int, name: *mut c_char, namesize: size_t) 0 } +/// See . +/// +/// # Deprecation +/// The `ualarm()` function was marked obsolescent in the Open Group Base +/// Specifications Issue 6, and removed in Issue 7. +#[deprecated] #[no_mangle] pub extern "C" fn ualarm(usecs: useconds_t, interval: useconds_t) -> useconds_t { let mut timer = sys_time::itimerval { @@ -916,12 +1036,19 @@ pub extern "C" fn ualarm(usecs: useconds_t, interval: useconds_t) -> useconds_t ret } +/// See . #[no_mangle] pub unsafe extern "C" fn unlink(path: *const c_char) -> c_int { let path = CStr::from_ptr(path); Sys::unlink(path).map(|()| 0).or_minus_one_errno() } +/// See . +/// +/// # Deprecation +/// The `usleep()` function was marked obsolescent in the Open Group Base +/// Specifications Issue 6, and removed in Issue 7. +#[deprecated] #[no_mangle] pub extern "C" fn usleep(useconds: useconds_t) -> c_int { let rqtp = timespec { @@ -934,11 +1061,18 @@ pub extern "C" fn usleep(useconds: useconds_t) -> c_int { .or_minus_one_errno() } +/// See . +/// +/// # Deprecation +/// The `vfork()` function was marked obsolescent in the Open Group Base +/// Specifications Issue 6, and removed in Issue 7. +#[deprecated] // #[no_mangle] pub extern "C" fn vfork() -> pid_t { unimplemented!(); } +/// See . #[no_mangle] pub unsafe extern "C" fn write(fildes: c_int, buf: *const c_void, nbyte: size_t) -> ssize_t { let buf = slice::from_raw_parts(buf as *const u8, nbyte as usize); From 5116c80d2f374d940b0a0ecffdabedfdd044ed98 Mon Sep 17 00:00:00 2001 From: Peter Limkilde Svendsen Date: Sat, 1 Feb 2025 17:34:20 +0100 Subject: [PATCH 2/5] Reorder functions alphabetically --- src/header/unistd/mod.rs | 152 +++++++++++++++++++-------------------- 1 file changed, 76 insertions(+), 76 deletions(-) diff --git a/src/header/unistd/mod.rs b/src/header/unistd/mod.rs index d4df033f4a..259255e1a8 100644 --- a/src/header/unistd/mod.rs +++ b/src/header/unistd/mod.rs @@ -109,6 +109,15 @@ pub unsafe extern "C" fn chdir(path: *const c_char) -> c_int { Sys::chdir(path).map(|()| 0).or_minus_one_errno() } +/// See . +#[no_mangle] +pub unsafe extern "C" fn chown(path: *const c_char, owner: uid_t, group: gid_t) -> c_int { + let path = CStr::from_ptr(path); + Sys::chown(path, owner, group) + .map(|()| 0) + .or_minus_one_errno() +} + /// See . /// /// # Deprecation @@ -123,23 +132,6 @@ pub unsafe extern "C" fn chroot(path: *const c_char) -> c_int { -1 } -#[no_mangle] -pub unsafe extern "C" fn set_default_scheme(scheme: *const c_char) -> c_int { - let scheme = CStr::from_ptr(scheme); - Sys::set_default_scheme(scheme) - .map(|_| 0) - .or_minus_one_errno() -} - -/// See . -#[no_mangle] -pub unsafe extern "C" fn chown(path: *const c_char, owner: uid_t, group: gid_t) -> c_int { - let path = CStr::from_ptr(path); - Sys::chown(path, owner, group) - .map(|()| 0) - .or_minus_one_errno() -} - /// See . #[no_mangle] pub extern "C" fn close(fildes: c_int) -> c_int { @@ -217,51 +209,6 @@ pub extern "C" fn encrypt(block: [c_char; 64], edflag: c_int) { unimplemented!(); } -unsafe fn with_argv( - mut va: VaListImpl, - arg0: *const c_char, - f: impl FnOnce(&[*const c_char], VaListImpl) -> c_int, -) -> c_int { - let argc = 1 + va.with_copy(|mut copy| { - core::iter::from_fn(|| Some(copy.arg::<*const c_char>())) - .position(|p| p.is_null()) - .unwrap() - }); - - let mut stack: [MaybeUninit<*const c_char>; 32] = MaybeUninit::uninit_array(); - - let out = if argc < 32 { - stack.as_mut_slice() - } else if argc < 4096 { - // TODO: Use ARG_MAX, not this hardcoded constant - let ptr = crate::header::stdlib::malloc(argc * mem::size_of::<*const c_char>()); - if ptr.is_null() { - platform::ERRNO.set(ENOMEM); - return -1; - } - slice::from_raw_parts_mut(ptr.cast::>(), argc) - } else { - platform::ERRNO.set(E2BIG); - return -1; - }; - out[0].write(arg0); - - for i in 1..argc { - out[i].write(va.arg::<*const c_char>()); - } - out[argc].write(core::ptr::null()); - // NULL - va.arg::<*const c_char>(); - - f(MaybeUninit::slice_assume_init_ref(&*out), va); - - // f only returns if it fails - if argc >= 32 { - crate::header::stdlib::free(out.as_mut_ptr().cast()); - } - -1 -} - /// See . #[no_mangle] pub unsafe extern "C" fn execl( @@ -363,6 +310,12 @@ pub unsafe extern "C" fn execvp(file: *const c_char, argv: *const *mut c_char) - } } +/// See . +#[no_mangle] +pub extern "C" fn fchdir(fildes: c_int) -> c_int { + Sys::fchdir(fildes).map(|()| 0).or_minus_one_errno() +} + /// See . #[no_mangle] pub extern "C" fn fchown(fildes: c_int, owner: uid_t, group: gid_t) -> c_int { @@ -371,12 +324,6 @@ pub extern "C" fn fchown(fildes: c_int, owner: uid_t, group: gid_t) -> c_int { .or_minus_one_errno() } -/// See . -#[no_mangle] -pub extern "C" fn fchdir(fildes: c_int) -> c_int { - Sys::fchdir(fildes).map(|()| 0).or_minus_one_errno() -} - /// See . #[no_mangle] pub extern "C" fn fdatasync(fildes: c_int) -> c_int { @@ -810,6 +757,14 @@ pub unsafe extern "C" fn rmdir(path: *const c_char) -> c_int { Sys::rmdir(path).map(|()| 0).or_minus_one_errno() } +#[no_mangle] +pub unsafe extern "C" fn set_default_scheme(scheme: *const c_char) -> c_int { + let scheme = CStr::from_ptr(scheme); + Sys::set_default_scheme(scheme) + .map(|_| 0) + .or_minus_one_errno() +} + /// See . #[no_mangle] pub extern "C" fn setgid(gid: gid_t) -> c_int { @@ -859,6 +814,14 @@ pub extern "C" fn setresgid(rgid: gid_t, egid: gid_t, sgid: gid_t) -> c_int { .or_minus_one_errno() } +/// See . +#[no_mangle] +pub extern "C" fn setresuid(ruid: uid_t, euid: uid_t, suid: uid_t) -> c_int { + Sys::setresuid(ruid, euid, suid) + .map(|()| 0) + .or_minus_one_errno() +} + /// See . #[no_mangle] pub extern "C" fn setreuid(ruid: uid_t, euid: uid_t) -> c_int { @@ -881,14 +844,6 @@ pub extern "C" fn setuid(uid: uid_t) -> c_int { .or_minus_one_errno() } -/// See . -#[no_mangle] -pub extern "C" fn setresuid(ruid: uid_t, euid: uid_t, suid: uid_t) -> c_int { - Sys::setresuid(ruid, euid, suid) - .map(|()| 0) - .or_minus_one_errno() -} - /// See . #[no_mangle] pub extern "C" fn sleep(seconds: c_uint) -> c_uint { @@ -1072,6 +1027,51 @@ pub extern "C" fn vfork() -> pid_t { unimplemented!(); } +unsafe fn with_argv( + mut va: VaListImpl, + arg0: *const c_char, + f: impl FnOnce(&[*const c_char], VaListImpl) -> c_int, +) -> c_int { + let argc = 1 + va.with_copy(|mut copy| { + core::iter::from_fn(|| Some(copy.arg::<*const c_char>())) + .position(|p| p.is_null()) + .unwrap() + }); + + let mut stack: [MaybeUninit<*const c_char>; 32] = MaybeUninit::uninit_array(); + + let out = if argc < 32 { + stack.as_mut_slice() + } else if argc < 4096 { + // TODO: Use ARG_MAX, not this hardcoded constant + let ptr = crate::header::stdlib::malloc(argc * mem::size_of::<*const c_char>()); + if ptr.is_null() { + platform::ERRNO.set(ENOMEM); + return -1; + } + slice::from_raw_parts_mut(ptr.cast::>(), argc) + } else { + platform::ERRNO.set(E2BIG); + return -1; + }; + out[0].write(arg0); + + for i in 1..argc { + out[i].write(va.arg::<*const c_char>()); + } + out[argc].write(core::ptr::null()); + // NULL + va.arg::<*const c_char>(); + + f(MaybeUninit::slice_assume_init_ref(&*out), va); + + // f only returns if it fails + if argc >= 32 { + crate::header::stdlib::free(out.as_mut_ptr().cast()); + } + -1 +} + /// See . #[no_mangle] pub unsafe extern "C" fn write(fildes: c_int, buf: *const c_void, nbyte: size_t) -> ssize_t { From 99e0948e0cd99d10c4042eff40c1dc7d07582b17 Mon Sep 17 00:00:00 2001 From: Peter Limkilde Svendsen Date: Sat, 1 Feb 2025 18:07:23 +0100 Subject: [PATCH 3/5] Reexport ctermid, cuserid --- src/header/unistd/mod.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/header/unistd/mod.rs b/src/header/unistd/mod.rs index 259255e1a8..f2bce45388 100644 --- a/src/header/unistd/mod.rs +++ b/src/header/unistd/mod.rs @@ -26,6 +26,11 @@ use alloc::collections::LinkedList; pub use self::{brk::*, getopt::*, getpass::getpass, pathconf::*, sysconf::*}; +// Inclusion of ctermid() prototype marked as obsolescent since Issue 7, cf. +// . +// cuserid() marked legacy in Issue 5. +pub use crate::header::stdio::{ctermid, cuserid}; + use super::errno::{E2BIG, ENOMEM}; mod brk; From 26fdc200bfc37b00afe54e8f3fcebebbacf9cdc8 Mon Sep 17 00:00:00 2001 From: Peter Limkilde Svendsen Date: Sat, 1 Feb 2025 18:07:51 +0100 Subject: [PATCH 4/5] Add docs for unistd submodules --- src/header/unistd/brk.rs | 12 ++++++++++++ src/header/unistd/getopt.rs | 15 ++++++++++----- src/header/unistd/getpass.rs | 6 ++++++ src/header/unistd/pathconf.rs | 2 ++ src/header/unistd/sysconf.rs | 1 + 5 files changed, 31 insertions(+), 5 deletions(-) diff --git a/src/header/unistd/brk.rs b/src/header/unistd/brk.rs index 47907758cf..73e7029040 100644 --- a/src/header/unistd/brk.rs +++ b/src/header/unistd/brk.rs @@ -8,6 +8,12 @@ use crate::{ static mut BRK: *mut c_void = ptr::null_mut(); +/// See . +/// +/// # Deprecation +/// The `brk()` function was marked legacy in the System Interface & Headers +/// Issue 5, and removed in Issue 6. +#[deprecated] #[no_mangle] pub unsafe extern "C" fn brk(addr: *mut c_void) -> c_int { BRK = Sys::brk(addr).or_errno_null_mut(); @@ -20,6 +26,12 @@ pub unsafe extern "C" fn brk(addr: *mut c_void) -> c_int { 0 } +/// See . +/// +/// # Deprecation +/// The `sbrk()` function was marked legacy in the System Interface & Headers +/// Issue 5, and removed in Issue 6. +#[deprecated] #[no_mangle] pub unsafe extern "C" fn sbrk(incr: intptr_t) -> *mut c_void { if BRK.is_null() { diff --git a/src/header/unistd/getopt.rs b/src/header/unistd/getopt.rs index e0b82c569f..5a3f28378c 100644 --- a/src/header/unistd/getopt.rs +++ b/src/header/unistd/getopt.rs @@ -4,26 +4,31 @@ use core::ptr; use crate::{header::getopt, platform::types::*}; +/// See . #[allow(non_upper_case_globals)] #[no_mangle] #[linkage = "weak"] // often redefined in GNU programs pub static mut optarg: *mut c_char = ptr::null_mut(); -#[allow(non_upper_case_globals)] -#[no_mangle] -#[linkage = "weak"] // often redefined in GNU programs -pub static mut optind: c_int = 1; - +/// See . #[allow(non_upper_case_globals)] #[no_mangle] #[linkage = "weak"] // often redefined in GNU programs pub static mut opterr: c_int = 1; +/// See . +#[allow(non_upper_case_globals)] +#[no_mangle] +#[linkage = "weak"] // often redefined in GNU programs +pub static mut optind: c_int = 1; + +/// See . #[allow(non_upper_case_globals)] #[no_mangle] #[linkage = "weak"] // often redefined in GNU programs pub static mut optopt: c_int = -1; +/// See . #[no_mangle] #[linkage = "weak"] // often redefined in GNU programs pub unsafe extern "C" fn getopt( diff --git a/src/header/unistd/getpass.rs b/src/header/unistd/getpass.rs index 6776cad85b..0385cc71bb 100644 --- a/src/header/unistd/getpass.rs +++ b/src/header/unistd/getpass.rs @@ -60,6 +60,12 @@ fn getpass_rs(prompt: CStr, passbuff: &mut [u8]) -> Result<*mut c_char, io::Erro Ok(passbuff.as_mut_ptr() as *mut c_char) } +/// See . +/// +/// # Deprecation +/// The `getpass()` function was marked legacy in the Open Group System +/// Interface & Headers Issue 5, and removed in Issue 6. +#[deprecated] #[no_mangle] pub unsafe extern "C" fn getpass(prompt: *const c_char) -> *mut c_char { static mut PASSBUFF: [u8; PASS_MAX] = [0; PASS_MAX]; diff --git a/src/header/unistd/pathconf.rs b/src/header/unistd/pathconf.rs index 074b65092f..0d81dade9c 100644 --- a/src/header/unistd/pathconf.rs +++ b/src/header/unistd/pathconf.rs @@ -56,11 +56,13 @@ fn pc(name: c_int) -> c_long { } } +/// See . #[no_mangle] pub extern "C" fn fpathconf(_fildes: c_int, name: c_int) -> c_long { pc(name) } +/// See . #[no_mangle] pub extern "C" fn pathconf(_path: *const c_char, name: c_int) -> c_long { pc(name) diff --git a/src/header/unistd/sysconf.rs b/src/header/unistd/sysconf.rs index 5e13346019..23b4fc385e 100644 --- a/src/header/unistd/sysconf.rs +++ b/src/header/unistd/sysconf.rs @@ -33,6 +33,7 @@ pub const _SC_SYMLOOP_MAX: c_int = 173; pub const _SC_HOST_NAME_MAX: c_int = 180; // } POSIX.1 +/// See . #[no_mangle] pub extern "C" fn sysconf(name: c_int) -> c_long { //TODO: Real values From 85f01e8412417ef1a09e338fa771b5f1bfd73705 Mon Sep 17 00:00:00 2001 From: Peter Limkilde Svendsen Date: Sat, 1 Feb 2025 18:36:07 +0100 Subject: [PATCH 5/5] Add stubs for missing functions --- src/header/unistd/mod.rs | 51 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/src/header/unistd/mod.rs b/src/header/unistd/mod.rs index f2bce45388..9863c063ea 100644 --- a/src/header/unistd/mod.rs +++ b/src/header/unistd/mod.rs @@ -31,6 +31,9 @@ pub use self::{brk::*, getopt::*, getpass::getpass, pathconf::*, sysconf::*}; // cuserid() marked legacy in Issue 5. pub use crate::header::stdio::{ctermid, cuserid}; +// TODO: implement and reexport fcntl functions: +//pub use crate::header::fcntl::{faccessat, fchownat, fexecve, linkat, readlinkat, symlinkat, unlinkat}; + use super::errno::{E2BIG, ENOMEM}; mod brk; @@ -71,6 +74,12 @@ unsafe fn init_fork_hooks<'a>() -> &'a mut [LinkedList; 3] { ) } +/// See . +// #[no_mangle] +pub unsafe extern "C" fn _Fork() -> pid_t { + unimplemented!(); +} + /// See . #[no_mangle] pub extern "C" fn _exit(status: c_int) -> ! { @@ -204,6 +213,12 @@ pub extern "C" fn dup2(fildes: c_int, fildes2: c_int) -> c_int { Sys::dup2(fildes, fildes2).or_minus_one_errno() } +/// See . +// #[no_mangle] +pub extern "C" fn dup3(fildes: c_int, fildes2: c_int, flag: c_int) -> c_int { + unimplemented!(); +} + /// See . /// /// # Deprecation @@ -436,6 +451,12 @@ pub extern "C" fn getegid() -> gid_t { Sys::getegid() } +/// See . +// #[no_mangle] +pub extern "C" fn getentropy(buffer: *mut c_void, length: size_t) -> c_int { + unimplemented!(); +} + /// See . #[no_mangle] pub extern "C" fn geteuid() -> uid_t { @@ -547,6 +568,18 @@ pub extern "C" fn getppid() -> pid_t { Sys::getppid() } +/// See . +// #[no_mangle] +pub extern "C" fn getresgid(rgid: *mut gid_t, egid: *mut gid_t, sgid: *mut gid_t) -> c_int { + unimplemented!(); +} + +/// See . +// #[no_mangle] +pub extern "C" fn getresuid(ruid: *mut uid_t, euid: *mut uid_t, suid: *mut uid_t) -> c_int { + unimplemented!(); +} + /// See . #[no_mangle] pub extern "C" fn getsid(pid: pid_t) -> pid_t { @@ -670,6 +703,12 @@ pub unsafe extern "C" fn pipe2(fildes: *mut c_int, flags: c_int) -> c_int { .or_minus_one_errno() } +/// See . +// #[no_mangle] +pub extern "C" fn posix_close(fildes: c_int, flag: c_int) -> c_int { + unimplemented!(); +} + /// See . #[no_mangle] pub unsafe extern "C" fn pread( @@ -770,6 +809,18 @@ pub unsafe extern "C" fn set_default_scheme(scheme: *const c_char) -> c_int { .or_minus_one_errno() } +/// See . +// #[no_mangle] +pub extern "C" fn setegid(gid: gid_t) -> c_int { + unimplemented!(); +} + +/// See . +// #[no_mangle] +pub extern "C" fn seteuid(uid: uid_t) -> c_int { + unimplemented!(); +} + /// See . #[no_mangle] pub extern "C" fn setgid(gid: gid_t) -> c_int {