Use unsafe blocks in unistd.h implementation

This commit is contained in:
sourceturner
2026-01-18 21:23:24 +01:00
parent 2cf1a2d16a
commit 61e098eb2c
3 changed files with 107 additions and 81 deletions
+11 -8
View File
@@ -1,3 +1,6 @@
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use core::ptr;
use crate::{
@@ -16,9 +19,9 @@ static mut BRK: *mut c_void = ptr::null_mut();
#[deprecated]
#[unsafe(no_mangle)]
pub unsafe extern "C" fn brk(addr: *mut c_void) -> c_int {
BRK = Sys::brk(addr).or_errno_null_mut();
unsafe { BRK = Sys::brk(addr).or_errno_null_mut() };
if BRK < addr {
if unsafe { BRK } < addr {
platform::ERRNO.set(ENOMEM);
return -1;
}
@@ -34,18 +37,18 @@ pub unsafe extern "C" fn brk(addr: *mut c_void) -> c_int {
#[deprecated]
#[unsafe(no_mangle)]
pub unsafe extern "C" fn sbrk(incr: intptr_t) -> *mut c_void {
if BRK.is_null() {
BRK = Sys::brk(ptr::null_mut()).or_errno_null_mut();
if unsafe { BRK }.is_null() {
unsafe { BRK = Sys::brk(ptr::null_mut()).or_errno_null_mut() };
}
let old_brk = BRK;
let old_brk = unsafe { BRK };
if incr != 0 {
let addr = old_brk.offset(incr);
let addr = unsafe { old_brk.offset(incr) };
BRK = Sys::brk(addr).or_errno_null_mut();
unsafe { BRK = Sys::brk(addr).or_errno_null_mut() };
if BRK < addr {
if unsafe { BRK } < addr {
platform::ERRNO.set(ENOMEM);
return -1isize as *mut c_void;
}
+4 -1
View File
@@ -2,6 +2,9 @@
//!
//! See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/getopt.html>.
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use core::ptr;
use crate::{
@@ -36,5 +39,5 @@ pub unsafe extern "C" fn getopt(
argv: *const *mut c_char,
optstring: *const c_char,
) -> c_int {
getopt::getopt_long(argc, argv, optstring, ptr::null(), ptr::null_mut())
unsafe { getopt::getopt_long(argc, argv, optstring, ptr::null(), ptr::null_mut()) }
}
+92 -72
View File
@@ -2,6 +2,9 @@
//!
//! See <https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/unistd.h.html>.
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use core::{
convert::TryFrom,
ffi::VaListImpl,
@@ -125,7 +128,7 @@ unsafe extern "C" {
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/fork.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn _Fork() -> pid_t {
Sys::fork().or_minus_one_errno()
unsafe { Sys::fork() }.or_minus_one_errno()
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/_Exit.html>.
@@ -137,7 +140,7 @@ pub extern "C" fn _exit(status: c_int) -> ! {
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/access.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn access(path: *const c_char, mode: c_int) -> c_int {
let path = CStr::from_ptr(path);
let path = unsafe { CStr::from_ptr(path) };
Sys::access(path, mode).map(|()| 0).or_minus_one_errno()
}
@@ -168,14 +171,14 @@ pub extern "C" fn alarm(seconds: c_uint) -> c_uint {
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/chdir.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn chdir(path: *const c_char) -> c_int {
let path = CStr::from_ptr(path);
let path = unsafe { CStr::from_ptr(path) };
Sys::chdir(path).map(|()| 0).or_minus_one_errno()
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/chown.html>.
#[unsafe(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);
let path = unsafe { CStr::from_ptr(path) };
Sys::chown(path, owner, group)
.map(|()| 0)
.or_minus_one_errno()
@@ -228,7 +231,7 @@ pub unsafe extern "C" fn confstr(name: c_int, buf: *mut c_char, len: size_t) ->
#[unsafe(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 _)
unsafe { crypt_r(key, salt, &mut data as *mut _) }
}
/// Non-POSIX, see <https://www.man7.org/linux/man-pages/man3/daemon.3.html>.
@@ -302,9 +305,11 @@ pub unsafe extern "C" fn execl(
arg0: *const c_char,
mut __valist: ...
) -> c_int {
with_argv(__valist, arg0, |args, _remaining_va| {
execv(path, args.as_ptr().cast())
})
unsafe {
with_argv(__valist, arg0, |args, _remaining_va| {
execv(path, args.as_ptr().cast())
})
}
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/exec.html>.
@@ -314,10 +319,12 @@ pub unsafe extern "C" fn execle(
arg0: *const c_char,
mut __valist: ...
) -> c_int {
with_argv(__valist, arg0, |args, mut remaining_va| {
let envp = remaining_va.arg::<*const *mut c_char>();
execve(path, args.as_ptr().cast(), envp)
})
unsafe {
with_argv(__valist, arg0, |args, mut remaining_va| {
let envp = remaining_va.arg::<*const *mut c_char>();
execve(path, args.as_ptr().cast(), envp)
})
}
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/exec.html>.
@@ -327,15 +334,17 @@ pub unsafe extern "C" fn execlp(
arg0: *const c_char,
mut __valist: ...
) -> c_int {
with_argv(__valist, arg0, |args, _remaining_va| {
execvp(file, args.as_ptr().cast())
})
unsafe {
with_argv(__valist, arg0, |args, _remaining_va| {
execvp(file, args.as_ptr().cast())
})
}
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/exec.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn execv(path: *const c_char, argv: *const *mut c_char) -> c_int {
execve(path, argv, platform::environ)
unsafe { execve(path, argv, platform::environ) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/exec.html>.
@@ -345,8 +354,8 @@ pub unsafe extern "C" fn execve(
argv: *const *mut c_char,
envp: *const *mut c_char,
) -> c_int {
let path = CStr::from_ptr(path);
Sys::execve(path, argv, envp)
let path = unsafe { CStr::from_ptr(path) };
unsafe { Sys::execve(path, argv, envp) }
.map(|()| unreachable!())
.or_minus_one_errno()
}
@@ -358,7 +367,7 @@ pub unsafe extern "C" fn fexecve(
argv: *const *mut c_char,
envp: *const *mut c_char,
) -> c_int {
Sys::fexecve(fd, argv, envp)
unsafe { Sys::fexecve(fd, argv, envp) }
.map(|()| unreachable!())
.or_minus_one_errno()
}
@@ -368,18 +377,18 @@ const PATH_SEPARATOR: u8 = b':';
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/exec.html>.
#[unsafe(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);
let file = unsafe { CStr::from_ptr(file) };
if file.to_bytes().contains(&b'/')
|| (cfg!(target_os = "redox") && file.to_bytes().contains(&b':'))
{
execv(file.as_ptr(), argv)
unsafe { execv(file.as_ptr(), argv) }
} else {
let mut error = errno::ENOENT;
let path_env = getenv(c"PATH".as_ptr());
let path_env = unsafe { getenv(c"PATH".as_ptr()) };
if !path_env.is_null() {
let path_env = CStr::from_ptr(path_env);
let path_env = unsafe { CStr::from_ptr(path_env) };
for path in path_env.to_bytes().split(|&b| b == PATH_SEPARATOR) {
let file = file.to_bytes();
let length = file.len() + path.len() + 2;
@@ -390,7 +399,7 @@ pub unsafe extern "C" fn execvp(file: *const c_char, argv: *const *mut c_char) -
program.push(b'\0');
let program_c = CStr::from_bytes_with_nul(&program).unwrap();
execv(program_c.as_ptr(), argv);
unsafe { execv(program_c.as_ptr(), argv) };
match platform::ERRNO.get() {
errno::ENOENT => (),
@@ -427,16 +436,16 @@ pub extern "C" fn fdatasync(fildes: c_int) -> c_int {
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/fork.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn fork() -> pid_t {
for prepare in &fork_hooks[0] {
for prepare in unsafe { &fork_hooks[0] } {
prepare();
}
let pid = Sys::fork().or_minus_one_errno();
let pid = unsafe { Sys::fork() }.or_minus_one_errno();
if pid == 0 {
for child in &fork_hooks[2] {
for child in unsafe { &fork_hooks[2] } {
child();
}
} else if pid != -1 {
for parent in &fork_hooks[1] {
for parent in unsafe { &fork_hooks[1] } {
parent();
}
}
@@ -467,7 +476,7 @@ pub unsafe extern "C" fn getcwd(mut buf: *mut c_char, mut size: size_t) -> *mut
size = stack_buf.len();
}
let ret = match Sys::getcwd(Out::from_raw_parts(buf.cast(), size)) {
let ret = match Sys::getcwd(unsafe { Out::from_raw_parts(buf.cast(), size) }) {
Ok(()) => buf,
Err(Errno(errno)) => {
ERRNO.set(errno);
@@ -551,7 +560,7 @@ pub unsafe extern "C" fn getgroups(size: c_int, list: *mut gid_t) -> c_int {
// where the actual number of entries in the group list is obviously nonnegative
.map_err(|_| Errno(EINVAL))?;
let list = Out::from_raw_parts(list, size);
let list = unsafe { Out::from_raw_parts(list, size) };
Sys::getgroups(list)
})()
@@ -576,20 +585,20 @@ pub unsafe extern "C" fn gethostname(mut name: *mut c_char, mut len: size_t) ->
mem::forget(uts);
return err;
}
for c in uts.assume_init().nodename.iter() {
for c in unsafe { uts.assume_init() }.nodename.iter() {
if len == 0 {
break;
}
len -= 1;
*name = *c;
unsafe { *name = *c };
if *name == 0 {
if unsafe { *name } == 0 {
// We do want to copy the zero also, so we check this after the copying.
break;
}
name = name.offset(1);
name = unsafe { name.offset(1) };
}
0
}
@@ -656,9 +665,9 @@ pub extern "C" fn getppid() -> pid_t {
#[unsafe(no_mangle)]
pub unsafe extern "C" fn getresgid(rgid: *mut gid_t, egid: *mut gid_t, sgid: *mut gid_t) -> c_int {
Sys::getresgid(
Out::nullable(rgid),
Out::nullable(egid),
Out::nullable(sgid),
unsafe { Out::nullable(rgid) },
unsafe { Out::nullable(egid) },
unsafe { Out::nullable(sgid) },
)
.map(|()| 0)
.or_minus_one_errno()
@@ -668,9 +677,9 @@ pub unsafe extern "C" fn getresgid(rgid: *mut gid_t, egid: *mut gid_t, sgid: *mu
#[unsafe(no_mangle)]
pub unsafe extern "C" fn getresuid(ruid: *mut uid_t, euid: *mut uid_t, suid: *mut uid_t) -> c_int {
Sys::getresuid(
Out::nullable(ruid),
Out::nullable(euid),
Out::nullable(suid),
unsafe { Out::nullable(ruid) },
unsafe { Out::nullable(euid) },
unsafe { Out::nullable(suid) },
)
.map(|()| 0)
.or_minus_one_errno()
@@ -713,7 +722,7 @@ pub extern "C" fn isatty(fd: c_int) -> c_int {
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/lchown.html>.
#[unsafe(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);
let path = unsafe { CStr::from_ptr(path) };
Sys::lchown(path, owner, group)
.map(|()| 0)
.or_minus_one_errno()
@@ -722,8 +731,8 @@ pub unsafe extern "C" fn lchown(path: *const c_char, owner: uid_t, group: gid_t)
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/link.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn link(path1: *const c_char, path2: *const c_char) -> c_int {
let path1 = CStr::from_ptr(path1);
let path2 = CStr::from_ptr(path2);
let path1 = unsafe { CStr::from_ptr(path1) };
let path2 = unsafe { CStr::from_ptr(path2) };
Sys::link(path1, path2).map(|()| 0).or_minus_one_errno()
}
@@ -741,7 +750,8 @@ pub unsafe extern "C" fn lockf(fildes: c_int, function: c_int, size: off_t) -> c
match function {
fcntl::F_TEST => {
fl.l_type = fcntl::F_RDLCK as c_short;
if fcntl::fcntl(fildes, fcntl::F_GETLK, &mut fl as *mut _ as c_ulonglong) < 0 {
if unsafe { fcntl::fcntl(fildes, fcntl::F_GETLK, &mut fl as *mut _ as c_ulonglong) } < 0
{
return -1;
}
if fl.l_type == fcntl::F_UNLCK as c_short || fl.l_pid == getpid() {
@@ -752,13 +762,19 @@ pub unsafe extern "C" fn lockf(fildes: c_int, function: c_int, size: off_t) -> c
}
fcntl::F_ULOCK => {
fl.l_type = fcntl::F_UNLCK as c_short;
return fcntl::fcntl(fildes, fcntl::F_SETLK, &mut fl as *mut _ as c_ulonglong);
return unsafe {
fcntl::fcntl(fildes, fcntl::F_SETLK, &mut fl as *mut _ as c_ulonglong)
};
}
fcntl::F_TLOCK => {
return fcntl::fcntl(fildes, fcntl::F_SETLK, &mut fl as *mut _ as c_ulonglong);
return unsafe {
fcntl::fcntl(fildes, fcntl::F_SETLK, &mut fl as *mut _ as c_ulonglong)
};
}
fcntl::F_LOCK => {
return fcntl::fcntl(fildes, fcntl::F_SETLKW, &mut fl as *mut _ as c_ulonglong);
return unsafe {
fcntl::fcntl(fildes, fcntl::F_SETLKW, &mut fl as *mut _ as c_ulonglong)
};
}
_ => {
platform::ERRNO.set(errno::EINVAL);
@@ -788,13 +804,13 @@ pub extern "C" fn pause() -> c_int {
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/pipe.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn pipe(fildes: *mut c_int) -> c_int {
pipe2(fildes, 0)
unsafe { pipe2(fildes, 0) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/pipe.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn pipe2(fildes: *mut c_int, flags: c_int) -> c_int {
Sys::pipe2(Out::nonnull(fildes.cast::<[c_int; 2]>()), flags)
Sys::pipe2(unsafe { Out::nonnull(fildes.cast::<[c_int; 2]>()) }, flags)
.map(|()| 0)
.or_minus_one_errno()
}
@@ -815,7 +831,7 @@ pub unsafe extern "C" fn pread(
) -> ssize_t {
Sys::pread(
fildes,
slice::from_raw_parts_mut(buf.cast::<u8>(), nbyte),
unsafe { slice::from_raw_parts_mut(buf.cast::<u8>(), nbyte) },
offset,
)
.map(|read| read as ssize_t)
@@ -832,7 +848,7 @@ pub unsafe extern "C" fn pwrite(
) -> ssize_t {
Sys::pwrite(
fildes,
slice::from_raw_parts(buf.cast::<u8>(), nbyte),
unsafe { slice::from_raw_parts(buf.cast::<u8>(), nbyte) },
offset,
)
.map(|read| read as ssize_t)
@@ -861,8 +877,8 @@ pub unsafe extern "C" fn readlink(
buf: *mut c_char,
bufsize: size_t,
) -> ssize_t {
let path = CStr::from_ptr(path);
let buf = slice::from_raw_parts_mut(buf as *mut u8, bufsize as usize);
let path = unsafe { CStr::from_ptr(path) };
let buf = unsafe { slice::from_raw_parts_mut(buf as *mut u8, bufsize as usize) };
Sys::readlink(path, buf)
.map(|read| read as ssize_t)
.or_minus_one_errno()
@@ -876,8 +892,8 @@ pub unsafe extern "C" fn readlinkat(
buf: *mut c_char,
len: size_t,
) -> ssize_t {
let pathname = CStr::from_ptr(pathname);
let mut buf = slice::from_raw_parts_mut(buf.cast(), len);
let pathname = unsafe { CStr::from_ptr(pathname) };
let mut buf = unsafe { slice::from_raw_parts_mut(buf.cast(), len) };
Sys::readlinkat(dirfd, pathname, &mut buf)
.map(|read| {
read.try_into()
@@ -890,7 +906,7 @@ pub unsafe extern "C" fn readlinkat(
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/rmdir.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn rmdir(path: *const c_char) -> c_int {
let path = CStr::from_ptr(path);
let path = unsafe { CStr::from_ptr(path) };
Sys::rmdir(path).map(|()| 0).or_minus_one_errno()
}
@@ -919,7 +935,9 @@ pub extern "C" fn setgid(gid: gid_t) -> c_int {
/// TODO: specified in `grp.h`?
#[unsafe(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()
unsafe { Sys::setgroups(size, list) }
.map(|()| 0)
.or_minus_one_errno()
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/setpgid.html>.
@@ -1026,8 +1044,8 @@ pub unsafe extern "C" fn swab(src: *const c_void, dest: *mut c_void, nbytes: ssi
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/symlink.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn symlink(path1: *const c_char, path2: *const c_char) -> c_int {
let path1 = CStr::from_ptr(path1);
let path2 = CStr::from_ptr(path2);
let path1 = unsafe { CStr::from_ptr(path1) };
let path2 = unsafe { CStr::from_ptr(path2) };
Sys::symlink(path1, path2).map(|()| 0).or_minus_one_errno()
}
@@ -1137,7 +1155,7 @@ pub extern "C" fn ualarm(usecs: useconds_t, interval: useconds_t) -> useconds_t
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/unlink.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn unlink(path: *const c_char) -> c_int {
let path = CStr::from_ptr(path);
let path = unsafe { CStr::from_ptr(path) };
Sys::unlink(path).map(|()| 0).or_minus_one_errno()
}
@@ -1175,11 +1193,13 @@ unsafe fn with_argv(
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 argc = 1 + unsafe {
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(); 32];
@@ -1187,12 +1207,12 @@ unsafe fn with_argv(
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>());
let ptr = unsafe { 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::<MaybeUninit<*const c_char>>(), argc)
unsafe { slice::from_raw_parts_mut(ptr.cast::<MaybeUninit<*const c_char>>(), argc) }
} else {
platform::ERRNO.set(E2BIG);
return -1;
@@ -1200,17 +1220,17 @@ unsafe fn with_argv(
out[0].write(arg0);
for i in 1..argc {
out[i].write(va.arg::<*const c_char>());
out[i].write(unsafe { va.arg::<*const c_char>() });
}
out[argc].write(core::ptr::null());
// NULL
va.arg::<*const c_char>();
unsafe { va.arg::<*const c_char>() };
f((&*out).assume_init_ref(), va);
f(unsafe { (&*out).assume_init_ref() }, va);
// f only returns if it fails
if argc >= 32 {
crate::header::stdlib::free(out.as_mut_ptr().cast());
unsafe { crate::header::stdlib::free(out.as_mut_ptr().cast()) };
}
-1
}
@@ -1218,7 +1238,7 @@ unsafe fn with_argv(
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/write.html>.
#[unsafe(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);
let buf = unsafe { slice::from_raw_parts(buf as *const u8, nbyte as usize) };
Sys::write(fildes, buf)
.map(|bytes| bytes as ssize_t)
.or_minus_one_errno()