Merge branch 'feature/deny-unsafe_op_in_unsafe_fn' into 'master'

Use unsafe blocks in headers and modules

See merge request redox-os/relibc!890
This commit is contained in:
Jeremy Soller
2026-01-18 18:56:50 -07:00
57 changed files with 1652 additions and 1299 deletions
+14 -11
View File
@@ -1,5 +1,8 @@
//! Nul-terminated byte strings.
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use core::{marker::PhantomData, ptr::NonNull, str::Utf8Error};
use alloc::{
@@ -49,13 +52,13 @@ impl Kind for Thin {
const IS_THIN_NOT_WIDE: bool = true;
unsafe fn strlen(s: *const c_char) -> usize {
crate::header::string::strlen(s)
unsafe { crate::header::string::strlen(s) }
}
unsafe fn strchr(s: *const c_char, c: c_char) -> *const c_char {
crate::header::string::strchr(s, c.into())
unsafe { crate::header::string::strchr(s, c.into()) }
}
unsafe fn strchrnul(s: *const c_char, c: c_char) -> *const c_char {
crate::header::string::strchrnul(s, c.into())
unsafe { crate::header::string::strchrnul(s, c.into()) }
}
fn r2c(c: u8) -> c_char {
c as _
@@ -78,15 +81,15 @@ impl Kind for Wide {
const IS_THIN_NOT_WIDE: bool = false;
unsafe fn strlen(s: *const Self::C) -> usize {
crate::header::wchar::wcslen(s)
unsafe { crate::header::wchar::wcslen(s) }
}
unsafe fn strchr(s: *const Self::C, c: Self::C) -> *const Self::C {
crate::header::wchar::wcschr(s, c)
unsafe { crate::header::wchar::wcschr(s, c) }
}
unsafe fn strchrnul(mut s: *const Self::C, c: Self::C) -> *const Self::C {
// TODO: optimized function
while s.read() != c && s.read() != 0 {
s = s.add(1);
while unsafe { s.read() } != c && unsafe { s.read() } != 0 {
s = unsafe { s.add(1) };
}
s
}
@@ -120,7 +123,7 @@ impl<'a, T: Kind> NulStr<'a, T> {
/// The ptr must be valid up to and including the first NUL byte from the base ptr.
pub const unsafe fn from_ptr(ptr: *const T::C) -> Self {
Self {
ptr: NonNull::new_unchecked(ptr as *mut T::C),
ptr: unsafe { NonNull::new_unchecked(ptr as *mut T::C) },
_marker: PhantomData,
}
}
@@ -128,7 +131,7 @@ impl<'a, T: Kind> NulStr<'a, T> {
if ptr.is_null() {
None
} else {
Some(Self::from_ptr(ptr))
Some(unsafe { Self::from_ptr(ptr) })
}
}
/// Look for the closest occurence of `c`, and if found, split the string into a slice up to
@@ -242,7 +245,7 @@ impl<'a, T: Kind> NulStr<'a, T> {
self.ptr.as_ptr()
}
pub const unsafe fn from_chars_with_nul_unchecked(chars: &'a [T::Char]) -> Self {
Self::from_ptr(chars.as_ptr().cast())
unsafe { Self::from_ptr(chars.as_ptr().cast()) }
}
pub fn from_chars_with_nul(chars: &'a [T::Char]) -> Result<Self, FromCharsWithNulError> {
if chars.last() != Some(&T::NUL) || chars[..chars.len() - 1].contains(&T::NUL) {
@@ -292,7 +295,7 @@ impl<'a> CStr<'a> {
}
#[inline]
pub const unsafe fn from_bytes_with_nul_unchecked(bytes: &'a [u8]) -> Self {
Self::from_chars_with_nul_unchecked(bytes)
unsafe { Self::from_chars_with_nul_unchecked(bytes) }
}
#[inline]
pub fn from_bytes_with_nul(bytes: &'a [u8]) -> Result<Self, FromCharsWithNulError> {
+12 -7
View File
@@ -1,5 +1,8 @@
//! Equivalent of Rust's `Vec<T>`, but using relibc's own allocator.
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use crate::{
io::{self, Write},
platform::{self, WriteByte, types::*},
@@ -61,21 +64,23 @@ impl<T> CVec<T> {
let ptr = if cap == 0 {
NonNull::dangling()
} else if self.cap > 0 {
NonNull::new(platform::realloc(self.ptr.as_ptr() as *mut c_void, size) as *mut T)
.ok_or(AllocError)?
NonNull::new(
unsafe { platform::realloc(self.ptr.as_ptr() as *mut c_void, size) } as *mut T,
)
.ok_or(AllocError)?
} else {
NonNull::new((platform::alloc(size)) as *mut T).ok_or(AllocError)?
NonNull::new((unsafe { platform::alloc(size) }) as *mut T).ok_or(AllocError)?
};
self.ptr = ptr;
self.cap = cap;
Ok(())
}
unsafe fn drop_range(&mut self, start: usize, end: usize) {
let mut start = self.ptr.as_ptr().add(start);
let end = self.ptr.as_ptr().add(end);
let mut start = unsafe { self.ptr.as_ptr().add(start) };
let end = unsafe { self.ptr.as_ptr().add(end) };
while start < end {
ptr::drop_in_place(start);
start = start.add(1);
unsafe { ptr::drop_in_place(start) };
start = unsafe { start.add(1) };
}
}
+50 -41
View File
@@ -1,3 +1,6 @@
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use alloc::{boxed::Box, str::SplitWhitespace, vec::Vec};
use core::{mem, ptr};
@@ -37,87 +40,93 @@ pub static mut HOST_STAYOPEN: c_int = 0;
#[unsafe(no_mangle)]
pub unsafe extern "C" fn endhostent() {
if HOSTDB >= 0 {
Sys::close(HOSTDB);
if unsafe { HOSTDB } >= 0 {
Sys::close(unsafe { HOSTDB });
}
HOSTDB = -1;
unsafe { HOSTDB = -1 };
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn sethostent(stayopen: c_int) {
HOST_STAYOPEN = stayopen;
if HOSTDB < 0 {
HOSTDB = Sys::open(c"/etc/hosts".into(), O_RDONLY, 0).or_minus_one_errno()
unsafe { HOST_STAYOPEN = stayopen };
if unsafe { HOSTDB } < 0 {
unsafe { HOSTDB = Sys::open(c"/etc/hosts".into(), O_RDONLY, 0).or_minus_one_errno() }
} else {
Sys::lseek(HOSTDB, 0, SEEK_SET);
Sys::lseek(unsafe { HOSTDB }, 0, SEEK_SET);
}
H_POS = 0;
unsafe { H_POS = 0 };
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn gethostent() -> *mut hostent {
if HOSTDB < 0 {
HOSTDB = Sys::open(c"/etc/hosts".into(), O_RDONLY, 0).or_minus_one_errno();
if unsafe { HOSTDB } < 0 {
unsafe { HOSTDB = Sys::open(c"/etc/hosts".into(), O_RDONLY, 0).or_minus_one_errno() };
}
let mut rlb = RawLineBuffer::new(HOSTDB);
rlb.seek(H_POS);
let mut rlb = RawLineBuffer::new(unsafe { HOSTDB });
rlb.seek(unsafe { H_POS });
let mut r: Box<str> = Box::default();
while r.is_empty() || r.split_whitespace().next() == None || r.starts_with('#') {
r = match rlb.next() {
Line::Some(s) => bytes_to_box_str(s),
_ => {
if HOST_STAYOPEN == 0 {
endhostent();
if unsafe { HOST_STAYOPEN } == 0 {
unsafe { endhostent() };
}
return ptr::null_mut();
}
};
}
rlb.next();
H_POS = rlb.line_pos();
unsafe { H_POS = rlb.line_pos() };
let mut iter: SplitWhitespace = r.split_whitespace();
let addr_vec: Vec<u8> = iter.next().unwrap().bytes().chain(Some(b'\0')).collect();
let addr_cstr = addr_vec.as_slice().as_ptr() as *const c_char;
let mut addr = mem::MaybeUninit::uninit();
inet_aton(addr_cstr, addr.as_mut_ptr());
let addr = addr.assume_init();
unsafe { inet_aton(addr_cstr, addr.as_mut_ptr()) };
let addr = unsafe { addr.assume_init() };
_HOST_ADDR_LIST = addr.s_addr.to_ne_bytes();
HOST_ADDR_LIST = [&raw mut _HOST_ADDR_LIST as *mut c_char, ptr::null_mut()];
unsafe {
_HOST_ADDR_LIST = addr.s_addr.to_ne_bytes();
HOST_ADDR_LIST = [&raw mut _HOST_ADDR_LIST as *mut c_char, ptr::null_mut()];
HOST_ADDR = Some(addr);
HOST_ADDR = Some(addr);
}
let host_name = iter.next().unwrap().bytes().chain(Some(b'\0')).collect();
let mut _host_aliases: Vec<Vec<u8>> = iter
.map(|alias| alias.bytes().chain(Some(b'\0')).collect())
.collect();
HOST_ALIASES.unsafe_set(Some(_host_aliases));
unsafe { HOST_ALIASES.unsafe_set(Some(_host_aliases)) };
let mut host_aliases: Vec<*mut c_char> = HOST_ALIASES
.unsafe_mut()
.as_mut()
.unwrap()
.iter_mut()
.map(|x| x.as_mut_ptr() as *mut c_char)
.chain([ptr::null_mut(), ptr::null_mut()])
.collect();
HOST_NAME.unsafe_set(Some(host_name));
HOST_ENTRY = hostent {
h_name: HOST_NAME.unsafe_mut().as_mut().unwrap().as_mut_ptr() as *mut c_char,
h_aliases: host_aliases.as_mut_slice().as_mut_ptr(),
h_addrtype: AF_INET,
h_length: 4,
h_addr_list: &raw mut HOST_ADDR_LIST as *mut _,
let mut host_aliases: Vec<*mut c_char> = unsafe {
HOST_ALIASES
.unsafe_mut()
.as_mut()
.unwrap()
.iter_mut()
.map(|x| x.as_mut_ptr() as *mut c_char)
.chain([ptr::null_mut(), ptr::null_mut()])
.collect()
};
_HOST_ALIASES.unsafe_set(Some(host_aliases));
if HOST_STAYOPEN == 0 {
endhostent();
unsafe { HOST_NAME.unsafe_set(Some(host_name)) };
unsafe {
HOST_ENTRY = hostent {
h_name: HOST_NAME.unsafe_mut().as_mut().unwrap().as_mut_ptr() as *mut c_char,
h_aliases: host_aliases.as_mut_slice().as_mut_ptr(),
h_addrtype: AF_INET,
h_length: 4,
h_addr_list: &raw mut HOST_ADDR_LIST as *mut _,
};
_HOST_ALIASES.unsafe_set(Some(host_aliases));
}
if unsafe { HOST_STAYOPEN } == 0 {
unsafe { endhostent() };
}
&raw mut HOST_ENTRY as *mut hostent
}
+227 -191
View File
@@ -2,6 +2,9 @@
//!
//! See <https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/netdb.h.html>.
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
mod dns;
use core::{
@@ -188,22 +191,22 @@ fn bytes_to_box_str(bytes: &[u8]) -> Box<str> {
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/endnetent.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn endnetent() {
Sys::close(NETDB);
NETDB = 0;
Sys::close(unsafe { NETDB });
unsafe { NETDB = 0 };
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/endprotoent.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn endprotoent() {
Sys::close(PROTODB);
PROTODB = 0;
Sys::close(unsafe { PROTODB });
unsafe { PROTODB = 0 };
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/endservent.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn endservent() {
Sys::close(SERVDB);
SERVDB = 0;
Sys::close(unsafe { SERVDB });
unsafe { SERVDB = 0 };
}
/// See <https://pubs.opengroup.org/onlinepubs/009696799/functions/gethostbyaddr.html>.
@@ -245,31 +248,31 @@ pub unsafe extern "C" fn gethostbyaddr(
H_ERRNO.set(NO_RECOVERY);
return ptr::null_mut();
}
let addr: in_addr = *(v as *mut in_addr);
let addr: in_addr = unsafe { *(v as *mut in_addr) };
// check the hosts file first
let mut p: *mut hostent;
sethostent(HOST_STAYOPEN);
unsafe { sethostent(HOST_STAYOPEN) };
while {
p = gethostent();
p = unsafe { gethostent() };
!p.is_null()
} {
let mut cp = (*p).h_addr_list;
let mut cp = unsafe { (*p).h_addr_list };
loop {
if cp.is_null() {
break;
}
if (*cp).is_null() {
if (unsafe { *cp }).is_null() {
break;
}
let mut cp_slice: [c_char; 4] = [0; 4];
(*cp).copy_to(cp_slice.as_mut_ptr(), 4);
let cp_s_addr = mem::transmute::<[c_char; 4], u32>(cp_slice);
unsafe { (*cp).copy_to(cp_slice.as_mut_ptr(), 4) };
let cp_s_addr = unsafe { mem::transmute::<[c_char; 4], u32>(cp_slice) };
if cp_s_addr == addr.s_addr {
sethostent(HOST_STAYOPEN);
unsafe { sethostent(HOST_STAYOPEN) };
return p;
}
cp = cp.offset(1);
cp = unsafe { cp.offset(1) };
}
}
@@ -278,19 +281,21 @@ pub unsafe extern "C" fn gethostbyaddr(
_host_aliases.push(vec![b'\0']);
let mut host_aliases: Vec<*mut c_char> = Vec::new();
host_aliases.push(ptr::null_mut());
HOST_ALIASES.unsafe_set(Some(_host_aliases));
unsafe { HOST_ALIASES.unsafe_set(Some(_host_aliases)) };
match lookup_addr(addr).map(|host_names| host_names.into_iter().next()) {
Ok(Some(host_name)) => {
_HOST_ADDR_LIST = addr.s_addr.to_ne_bytes();
HOST_ADDR_LIST = [&raw mut _HOST_ADDR_LIST as *mut c_char, ptr::null_mut()];
HOST_NAME.unsafe_set(Some(host_name));
HOST_ENTRY = hostent {
h_name: HOST_NAME.unsafe_mut().as_mut().unwrap().as_mut_ptr() as *mut c_char,
h_aliases: host_aliases.as_mut_slice().as_mut_ptr(),
h_addrtype: format,
h_length: length as i32,
h_addr_list: &raw mut HOST_ADDR_LIST as *mut _,
unsafe { _HOST_ADDR_LIST = addr.s_addr.to_ne_bytes() };
unsafe { HOST_ADDR_LIST = [&raw mut _HOST_ADDR_LIST as *mut c_char, ptr::null_mut()] };
unsafe { HOST_NAME.unsafe_set(Some(host_name)) };
unsafe {
HOST_ENTRY = hostent {
h_name: HOST_NAME.unsafe_mut().as_mut().unwrap().as_mut_ptr() as *mut c_char,
h_aliases: host_aliases.as_mut_slice().as_mut_ptr(),
h_addrtype: format,
h_length: length as i32,
h_addr_list: &raw mut HOST_ADDR_LIST as *mut _,
}
};
&raw mut HOST_ENTRY
}
@@ -327,8 +332,9 @@ pub unsafe extern "C" fn gethostbyaddr(
#[unsafe(no_mangle)]
#[deprecated]
pub unsafe extern "C" fn gethostbyname(name: *const c_char) -> *mut hostent {
let name_cstr =
CStr::from_nullable_ptr(name).expect("gethostbyname() called with a NULL pointer");
let name_cstr = unsafe {
CStr::from_nullable_ptr(name).expect("gethostbyname() called with a NULL pointer")
};
let Ok(name_str) = str::from_utf8(name_cstr.to_bytes()) else {
H_ERRNO.set(NO_RECOVERY);
return ptr::null_mut();
@@ -339,33 +345,33 @@ pub unsafe extern "C" fn gethostbyname(name: *const c_char) -> *mut hostent {
// Some implementations just skip resolution and copy the address to h_name
if let Some(s_addr) = parse_ipv4_string(name_str) {
let addr = in_addr { s_addr };
return gethostbyaddr(&addr as *const _ as *const c_void, 4, AF_INET);
return unsafe { gethostbyaddr(&addr as *const _ as *const c_void, 4, AF_INET) };
}
// check the hosts file first
let mut p: *mut hostent;
sethostent(HOST_STAYOPEN);
unsafe { sethostent(HOST_STAYOPEN) };
while {
p = gethostent();
p = unsafe { gethostent() };
!p.is_null()
} {
if strcasecmp((*p).h_name, name) == 0 {
sethostent(HOST_STAYOPEN);
if unsafe { strcasecmp((*p).h_name, name) } == 0 {
unsafe { sethostent(HOST_STAYOPEN) };
return p;
}
let mut cp = (*p).h_aliases;
let mut cp = unsafe { (*p).h_aliases };
loop {
if cp.is_null() {
break;
}
if (*cp).is_null() {
if (unsafe { *cp }).is_null() {
break;
}
if strcasecmp(*cp, name) == 0 {
sethostent(HOST_STAYOPEN);
if unsafe { strcasecmp(*cp, name) } == 0 {
unsafe { sethostent(HOST_STAYOPEN) };
return p;
}
cp = cp.offset(1);
cp = unsafe { cp.offset(1) };
}
}
@@ -385,10 +391,10 @@ pub unsafe extern "C" fn gethostbyname(name: *const c_char) -> *mut hostent {
};
let host_name: Vec<u8> = name_cstr.to_bytes().to_vec();
HOST_NAME.unsafe_set(Some(host_name));
_HOST_ADDR_LIST = host_addr.s_addr.to_ne_bytes();
HOST_ADDR_LIST = [&raw mut _HOST_ADDR_LIST as *mut c_char, ptr::null_mut()];
HOST_ADDR = Some(host_addr);
unsafe { HOST_NAME.unsafe_set(Some(host_name)) };
unsafe { _HOST_ADDR_LIST = host_addr.s_addr.to_ne_bytes() };
unsafe { HOST_ADDR_LIST = [&raw mut _HOST_ADDR_LIST as *mut c_char, ptr::null_mut()] };
unsafe { HOST_ADDR = Some(host_addr) };
//TODO actually get aliases
let mut _host_aliases: Vec<Vec<u8>> = Vec::new();
@@ -396,16 +402,18 @@ pub unsafe extern "C" fn gethostbyname(name: *const c_char) -> *mut hostent {
let mut host_aliases: Vec<*mut c_char> = Vec::new();
host_aliases.push(ptr::null_mut());
host_aliases.push(ptr::null_mut());
HOST_ALIASES.unsafe_set(Some(_host_aliases));
unsafe { HOST_ALIASES.unsafe_set(Some(_host_aliases)) };
HOST_ENTRY = hostent {
h_name: HOST_NAME.unsafe_mut().as_mut().unwrap().as_mut_ptr() as *mut c_char,
h_aliases: host_aliases.as_mut_slice().as_mut_ptr(),
h_addrtype: AF_INET,
h_length: 4,
h_addr_list: &raw mut HOST_ADDR_LIST as *mut _,
unsafe {
HOST_ENTRY = hostent {
h_name: unsafe { HOST_NAME.unsafe_mut().as_mut().unwrap().as_mut_ptr() } as *mut c_char,
h_aliases: host_aliases.as_mut_slice().as_mut_ptr(),
h_addrtype: AF_INET,
h_length: 4,
h_addr_list: &raw mut HOST_ADDR_LIST as *mut _,
}
};
sethostent(HOST_STAYOPEN);
unsafe { sethostent(HOST_STAYOPEN) };
&raw mut HOST_ENTRY as *mut hostent
}
@@ -418,17 +426,17 @@ pub unsafe extern "C" fn getnetbyaddr(net: u32, net_type: c_int) -> *mut netent
#[unsafe(no_mangle)]
pub unsafe extern "C" fn getnetbyname(name: *const c_char) -> *mut netent {
let mut n: *mut netent;
setnetent(NET_STAYOPEN);
unsafe { setnetent(NET_STAYOPEN) };
while {
n = getnetent();
n = unsafe { getnetent() };
!n.is_null()
} {
if strcasecmp((*n).n_name, name) == 0 {
setnetent(NET_STAYOPEN);
if unsafe { strcasecmp((*n).n_name, name) } == 0 {
unsafe { setnetent(NET_STAYOPEN) };
return n;
}
}
setnetent(NET_STAYOPEN);
unsafe { setnetent(NET_STAYOPEN) };
platform::ERRNO.set(ENOENT);
ptr::null_mut() as *mut netent
@@ -439,39 +447,39 @@ pub unsafe extern "C" fn getnetbyname(name: *const c_char) -> *mut netent {
pub unsafe extern "C" fn getnetent() -> *mut netent {
// TODO: Rustify implementation
if NETDB == 0 {
NETDB = Sys::open(c"/etc/networks".into(), O_RDONLY, 0).or_minus_one_errno();
if unsafe { NETDB } == 0 {
unsafe { NETDB = Sys::open(c"/etc/networks".into(), O_RDONLY, 0).or_minus_one_errno() };
}
let mut rlb = RawLineBuffer::new(NETDB);
rlb.seek(N_POS);
let mut rlb = RawLineBuffer::new(unsafe { NETDB });
rlb.seek(unsafe { N_POS });
let mut r: Box<str> = Box::default();
while r.is_empty() || r.split_whitespace().next() == None || r.starts_with('#') {
r = match rlb.next() {
Line::Some(s) => bytes_to_box_str(s),
_ => {
if NET_STAYOPEN == 0 {
endnetent();
if unsafe { NET_STAYOPEN } == 0 {
unsafe { endnetent() };
}
return ptr::null_mut();
}
};
}
rlb.next();
N_POS = rlb.line_pos();
unsafe { N_POS = rlb.line_pos() };
let mut iter: SplitWhitespace = r.split_whitespace();
let net_name = iter.next().unwrap().bytes().chain(Some(b'\0')).collect();
NET_NAME.unsafe_set(Some(net_name));
unsafe { NET_NAME.unsafe_set(Some(net_name)) };
let addr_vec: Vec<u8> = iter.next().unwrap().bytes().chain(Some(b'\0')).collect();
let addr_cstr = addr_vec.as_slice().as_ptr() as *const c_char;
let mut addr = mem::MaybeUninit::uninit();
inet_aton(addr_cstr, addr.as_mut_ptr());
let addr = addr.assume_init();
NET_ADDR = Some(ntohl(addr.s_addr));
unsafe { inet_aton(addr_cstr, addr.as_mut_ptr()) };
let addr = unsafe { addr.assume_init() };
unsafe { NET_ADDR = Some(ntohl(addr.s_addr)) };
let mut _net_aliases: Vec<Vec<u8>> = iter
.map(|alias| alias.bytes().chain(Some(b'\0')).collect())
@@ -481,13 +489,18 @@ pub unsafe extern "C" fn getnetent() -> *mut netent {
.map(|x| x.as_mut_ptr() as *mut c_char)
.chain(Some(ptr::null_mut()))
.collect();
NET_ALIASES.unsafe_set(Some(_net_aliases));
unsafe { NET_ALIASES.unsafe_set(Some(_net_aliases)) };
NET_ENTRY = netent {
n_name: NET_NAME.unsafe_mut().as_mut().unwrap().as_mut_ptr() as *mut c_char,
n_aliases: net_aliases.as_mut_slice().as_mut_ptr(),
n_addrtype: AF_INET,
n_net: NET_ADDR.unwrap() as c_ulong,
unsafe {
NET_ENTRY = netent {
n_name: unsafe { NET_NAME.unsafe_mut() }
.as_mut()
.unwrap()
.as_mut_ptr() as *mut c_char,
n_aliases: net_aliases.as_mut_slice().as_mut_ptr(),
n_addrtype: AF_INET,
n_net: NET_ADDR.unwrap() as c_ulong,
}
};
&raw mut NET_ENTRY as *mut netent
}
@@ -496,34 +509,34 @@ pub unsafe extern "C" fn getnetent() -> *mut netent {
#[unsafe(no_mangle)]
pub unsafe extern "C" fn getprotobyname(name: *const c_char) -> *mut protoent {
let mut p: *mut protoent;
setprotoent(PROTO_STAYOPEN);
unsafe { setprotoent(PROTO_STAYOPEN) };
while {
p = getprotoent();
p = unsafe { getprotoent() };
!p.is_null()
} {
if strcasecmp((*p).p_name, name) == 0 {
setprotoent(PROTO_STAYOPEN);
if unsafe { strcasecmp((*p).p_name, name) } == 0 {
unsafe { setprotoent(PROTO_STAYOPEN) };
return p;
}
let mut cp = (*p).p_aliases;
let mut cp = unsafe { (*p).p_aliases };
loop {
if cp.is_null() {
setprotoent(PROTO_STAYOPEN);
unsafe { setprotoent(PROTO_STAYOPEN) };
break;
}
if (*cp).is_null() {
setprotoent(PROTO_STAYOPEN);
if (unsafe { *cp }).is_null() {
unsafe { setprotoent(PROTO_STAYOPEN) };
break;
}
if strcasecmp(*cp, name) == 0 {
setprotoent(PROTO_STAYOPEN);
if unsafe { strcasecmp(*cp, name) } == 0 {
unsafe { setprotoent(PROTO_STAYOPEN) };
return p;
}
cp = cp.offset(1);
cp = unsafe { cp.offset(1) };
}
}
setprotoent(PROTO_STAYOPEN);
unsafe { setprotoent(PROTO_STAYOPEN) };
platform::ERRNO.set(ENOENT);
ptr::null_mut() as *mut protoent
@@ -532,18 +545,18 @@ pub unsafe extern "C" fn getprotobyname(name: *const c_char) -> *mut protoent {
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/endprotoent.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn getprotobynumber(number: c_int) -> *mut protoent {
setprotoent(PROTO_STAYOPEN);
unsafe { setprotoent(PROTO_STAYOPEN) };
let mut p: *mut protoent;
while {
p = getprotoent();
p = unsafe { getprotoent() };
!p.is_null()
} {
if (*p).p_proto == number {
setprotoent(PROTO_STAYOPEN);
if unsafe { (*p).p_proto } == number {
unsafe { setprotoent(PROTO_STAYOPEN) };
return p;
}
}
setprotoent(PROTO_STAYOPEN);
unsafe { setprotoent(PROTO_STAYOPEN) };
platform::ERRNO.set(ENOENT);
ptr::null_mut() as *mut protoent
}
@@ -551,27 +564,27 @@ pub unsafe extern "C" fn getprotobynumber(number: c_int) -> *mut protoent {
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/endprotoent.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn getprotoent() -> *mut protoent {
if PROTODB == 0 {
PROTODB = Sys::open(c"/etc/protocols".into(), O_RDONLY, 0).or_minus_one_errno();
if unsafe { PROTODB } == 0 {
unsafe { PROTODB = Sys::open(c"/etc/protocols".into(), O_RDONLY, 0).or_minus_one_errno() };
}
let mut rlb = RawLineBuffer::new(PROTODB);
rlb.seek(P_POS);
let mut rlb = RawLineBuffer::new(unsafe { PROTODB });
rlb.seek(unsafe { P_POS });
let mut r: Box<str> = Box::default();
while r.is_empty() || r.split_whitespace().next() == None || r.starts_with('#') {
r = match rlb.next() {
Line::Some(s) => bytes_to_box_str(s),
_ => {
if PROTO_STAYOPEN == 0 {
endprotoent();
if unsafe { PROTO_STAYOPEN } == 0 {
unsafe { endprotoent() };
}
return ptr::null_mut();
}
};
}
rlb.next();
P_POS = rlb.line_pos();
unsafe { P_POS = rlb.line_pos() };
let mut iter: SplitWhitespace = r.split_whitespace();
@@ -580,7 +593,7 @@ pub unsafe extern "C" fn getprotoent() -> *mut protoent {
let mut num = iter.next().unwrap().as_bytes().to_vec();
num.push(b'\0');
PROTO_NUM = Some(atoi(num.as_mut_slice().as_mut_ptr() as *mut c_char));
unsafe { PROTO_NUM = Some(atoi(num.as_mut_slice().as_mut_ptr() as *mut c_char)) };
let mut _proto_aliases: Vec<Vec<u8>> = iter
.map(|alias| alias.bytes().chain(Some(b'\0')).collect())
@@ -591,21 +604,25 @@ pub unsafe extern "C" fn getprotoent() -> *mut protoent {
.chain(Some(ptr::null_mut()))
.collect();
PROTO_ALIASES.unsafe_set(Some(_proto_aliases));
PROTO_NAME.unsafe_set(Some(proto_name));
unsafe { PROTO_ALIASES.unsafe_set(Some(_proto_aliases)) };
unsafe { PROTO_NAME.unsafe_set(Some(proto_name)) };
PROTO_ENTRY = protoent {
p_name: PROTO_NAME
.unsafe_mut()
.as_mut()
.unwrap()
.as_mut_slice()
.as_mut_ptr() as *mut c_char,
p_aliases: proto_aliases.as_mut_slice().as_mut_ptr() as *mut *mut c_char,
p_proto: PROTO_NUM.unwrap(),
unsafe {
PROTO_ENTRY = protoent {
p_name: unsafe {
PROTO_NAME
.unsafe_mut()
.as_mut()
.unwrap()
.as_mut_slice()
.as_mut_ptr()
} as *mut c_char,
p_aliases: proto_aliases.as_mut_slice().as_mut_ptr() as *mut *mut c_char,
p_proto: unsafe { PROTO_NUM }.unwrap(),
}
};
if PROTO_STAYOPEN == 0 {
endprotoent();
if unsafe { PROTO_STAYOPEN } == 0 {
unsafe { endprotoent() };
}
&raw mut PROTO_ENTRY as *mut protoent
}
@@ -613,30 +630,32 @@ pub unsafe extern "C" fn getprotoent() -> *mut protoent {
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/endservent.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn getservbyname(name: *const c_char, proto: *const c_char) -> *mut servent {
setservent(SERV_STAYOPEN);
unsafe { setservent(SERV_STAYOPEN) };
let mut p: *mut servent;
if proto.is_null() {
while {
p = getservent();
p = unsafe { getservent() };
!p.is_null()
} {
if strcasecmp((*p).s_name, name) == 0 {
setservent(SERV_STAYOPEN);
if unsafe { strcasecmp((*p).s_name, name) } == 0 {
unsafe { setservent(SERV_STAYOPEN) };
return p;
}
}
} else {
while {
p = getservent();
p = unsafe { getservent() };
!p.is_null()
} {
if strcasecmp((*p).s_name, name) == 0 && strcasecmp((*p).s_proto, proto) == 0 {
setservent(SERV_STAYOPEN);
if unsafe { strcasecmp((*p).s_name, name) } == 0
&& unsafe { strcasecmp((*p).s_proto, proto) } == 0
{
unsafe { setservent(SERV_STAYOPEN) };
return p;
}
}
}
setservent(SERV_STAYOPEN);
unsafe { setservent(SERV_STAYOPEN) };
platform::ERRNO.set(ENOENT);
ptr::null_mut() as *mut servent
}
@@ -644,30 +663,30 @@ pub unsafe extern "C" fn getservbyname(name: *const c_char, proto: *const c_char
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/endservent.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn getservbyport(port: c_int, proto: *const c_char) -> *mut servent {
setservent(SERV_STAYOPEN);
unsafe { setservent(SERV_STAYOPEN) };
let mut p: *mut servent;
if proto.is_null() {
while {
p = getservent();
p = unsafe { getservent() };
!p.is_null()
} {
if (*p).s_port == port {
setservent(SERV_STAYOPEN);
if unsafe { (*p).s_port } == port {
unsafe { setservent(SERV_STAYOPEN) };
return p;
}
}
} else {
while {
p = getservent();
p = unsafe { getservent() };
!p.is_null()
} {
if (*p).s_port == port && strcasecmp((*p).s_proto, proto) == 0 {
setservent(SERV_STAYOPEN);
if unsafe { (*p).s_port } == port && unsafe { strcasecmp((*p).s_proto, proto) } == 0 {
unsafe { setservent(SERV_STAYOPEN) };
return p;
}
}
}
setservent(SERV_STAYOPEN);
unsafe { setservent(SERV_STAYOPEN) };
platform::ERRNO.set(ENOENT);
ptr::null_mut()
}
@@ -675,12 +694,12 @@ pub unsafe extern "C" fn getservbyport(port: c_int, proto: *const c_char) -> *mu
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/endservent.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn getservent() -> *mut servent {
if SERVDB == 0 {
if unsafe { SERVDB } == 0 {
// TODO: Rustify
SERVDB = Sys::open(c"/etc/services".into(), O_RDONLY, 0).or_minus_one_errno();
unsafe { SERVDB = Sys::open(c"/etc/services".into(), O_RDONLY, 0).or_minus_one_errno() };
}
let mut rlb = RawLineBuffer::new(SERVDB);
rlb.seek(S_POS);
let mut rlb = RawLineBuffer::new(unsafe { SERVDB });
rlb.seek(unsafe { S_POS });
let r: Box<str> = Box::default();
@@ -688,8 +707,8 @@ pub unsafe extern "C" fn getservent() -> *mut servent {
let r = match rlb.next() {
Line::Some(s) => bytes_to_box_str(s),
_ => {
if SERV_STAYOPEN == 0 {
endservent();
if unsafe { SERV_STAYOPEN } == 0 {
unsafe { endservent() };
}
return ptr::null_mut();
}
@@ -709,15 +728,18 @@ pub unsafe extern "C" fn getservent() -> *mut servent {
Some(port) => port.bytes().chain(Some(b'\0')).collect(),
None => continue,
};
SERV_PORT =
Some(htons(atoi(port.as_mut_slice().as_mut_ptr() as *mut c_char) as u16) as u32 as i32);
unsafe {
SERV_PORT = Some(
htons(atoi(port.as_mut_slice().as_mut_ptr() as *mut c_char) as u16) as u32 as i32,
)
};
let proto = match split.next() {
Some(proto) => proto.bytes().chain(Some(b'\0')).collect(),
None => continue,
};
rlb.next();
S_POS = rlb.line_pos();
unsafe { S_POS = rlb.line_pos() };
/*
*let mut _serv_aliases: Vec<Vec<u8>> = Vec::new();
@@ -739,29 +761,31 @@ pub unsafe extern "C" fn getservent() -> *mut servent {
serv_aliases.push(ptr::null_mut());
serv_aliases.push(ptr::null_mut());
SERV_ALIASES.unsafe_set(Some(_serv_aliases));
SERV_NAME.unsafe_set(Some(serv_name));
SERV_PROTO.unsafe_set(Some(proto));
unsafe { SERV_ALIASES.unsafe_set(Some(_serv_aliases)) };
unsafe { SERV_NAME.unsafe_set(Some(serv_name)) };
unsafe { SERV_PROTO.unsafe_set(Some(proto)) };
SERV_ENTRY = servent {
s_name: SERV_NAME
.unsafe_mut()
.as_mut()
.unwrap()
.as_mut_slice()
.as_mut_ptr() as *mut c_char,
s_aliases: serv_aliases.as_mut_slice().as_mut_ptr() as *mut *mut c_char,
s_port: SERV_PORT.unwrap(),
s_proto: SERV_PROTO
.unsafe_mut()
.as_mut()
.unwrap()
.as_mut_slice()
.as_mut_ptr() as *mut c_char,
unsafe {
SERV_ENTRY = servent {
s_name: SERV_NAME
.unsafe_mut()
.as_mut()
.unwrap()
.as_mut_slice()
.as_mut_ptr() as *mut c_char,
s_aliases: serv_aliases.as_mut_slice().as_mut_ptr() as *mut *mut c_char,
s_port: SERV_PORT.unwrap(),
s_proto: SERV_PROTO
.unsafe_mut()
.as_mut()
.unwrap()
.as_mut_slice()
.as_mut_ptr() as *mut c_char,
}
};
if SERV_STAYOPEN == 0 {
endservent();
if unsafe { SERV_STAYOPEN } == 0 {
unsafe { endservent() };
}
break &raw mut SERV_ENTRY as *mut servent;
}
@@ -770,36 +794,36 @@ pub unsafe extern "C" fn getservent() -> *mut servent {
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/endnetent.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn setnetent(stayopen: c_int) {
NET_STAYOPEN = stayopen;
if NETDB == 0 {
NETDB = Sys::open(c"/etc/networks".into(), O_RDONLY, 0).or_minus_one_errno()
unsafe { NET_STAYOPEN = stayopen };
if unsafe { NETDB } == 0 {
unsafe { NETDB = Sys::open(c"/etc/networks".into(), O_RDONLY, 0).or_minus_one_errno() }
} else {
Sys::lseek(NETDB, 0, SEEK_SET);
N_POS = 0;
Sys::lseek(unsafe { NETDB }, 0, SEEK_SET);
unsafe { N_POS = 0 };
}
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/endprotoent.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn setprotoent(stayopen: c_int) {
PROTO_STAYOPEN = stayopen;
if PROTODB == 0 {
PROTODB = Sys::open(c"/etc/protocols".into(), O_RDONLY, 0).or_minus_one_errno()
unsafe { PROTO_STAYOPEN = stayopen };
if unsafe { PROTODB } == 0 {
unsafe { PROTODB = Sys::open(c"/etc/protocols".into(), O_RDONLY, 0).or_minus_one_errno() }
} else {
Sys::lseek(PROTODB, 0, SEEK_SET);
P_POS = 0;
Sys::lseek(unsafe { PROTODB }, 0, SEEK_SET);
unsafe { P_POS = 0 };
}
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/endservent.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn setservent(stayopen: c_int) {
SERV_STAYOPEN = stayopen;
if SERVDB == 0 {
SERVDB = Sys::open(c"/etc/services".into(), O_RDONLY, 0).or_minus_one_errno()
unsafe { SERV_STAYOPEN = stayopen };
if unsafe { SERVDB } == 0 {
unsafe { SERVDB = Sys::open(c"/etc/services".into(), O_RDONLY, 0).or_minus_one_errno() }
} else {
Sys::lseek(SERVDB, 0, SEEK_SET);
S_POS = 0;
Sys::lseek(unsafe { SERVDB }, 0, SEEK_SET);
unsafe { S_POS = 0 };
}
}
@@ -811,15 +835,19 @@ pub unsafe extern "C" fn getaddrinfo(
hints: *const addrinfo,
res: *mut *mut addrinfo,
) -> c_int {
let node_opt = CStr::from_nullable_ptr(node);
let service_opt = CStr::from_nullable_ptr(service);
let node_opt = unsafe { CStr::from_nullable_ptr(node) };
let service_opt = unsafe { CStr::from_nullable_ptr(service) };
let hints_opt = if hints.is_null() { None } else { Some(&*hints) };
let hints_opt = if hints.is_null() {
None
} else {
Some(unsafe { &*hints })
};
trace!(
"getaddrinfo({:?}, {:?}, {:?})",
node_opt.map(|c| str::from_utf8_unchecked(c.to_bytes())),
service_opt.map(|c| str::from_utf8_unchecked(c.to_bytes())),
node_opt.map(|c| unsafe { str::from_utf8_unchecked(c.to_bytes()) }),
service_opt.map(|c| unsafe { str::from_utf8_unchecked(c.to_bytes()) }),
hints_opt
);
@@ -829,12 +857,12 @@ pub unsafe extern "C" fn getaddrinfo(
let ai_socktype = hints_opt.map_or(0, |hints| hints.ai_socktype);
let mut ai_protocol; // = hints_opt.map_or(0, |hints| hints.ai_protocol);
*res = ptr::null_mut();
unsafe { *res = ptr::null_mut() };
let mut port = 0;
if let Some(service) = service_opt {
//TODO: Support other service definitions as well as AI_NUMERICSERV
match str::from_utf8_unchecked(service.to_bytes()).parse::<u16>() {
match unsafe { str::from_utf8_unchecked(service.to_bytes()) }.parse::<u16>() {
Ok(ok) => port = ok,
Err(_err) => (),
}
@@ -849,14 +877,14 @@ pub unsafe extern "C" fn getaddrinfo(
});
let lookuphost = if ai_flags & AI_NUMERICHOST > 0 {
match parse_ipv4_string(str::from_utf8_unchecked(node.to_bytes())) {
match parse_ipv4_string(unsafe { str::from_utf8_unchecked(node.to_bytes()) }) {
Some(s_addr) => s_addr.into(),
None => {
return EAI_NONAME;
}
}
} else {
match lookup_host(str::from_utf8_unchecked(node.to_bytes())) {
match lookup_host(unsafe { str::from_utf8_unchecked(node.to_bytes()) }) {
Ok(lookuphost) => lookuphost,
Err(e) => {
platform::ERRNO.set(e);
@@ -900,10 +928,10 @@ pub unsafe extern "C" fn getaddrinfo(
});
let mut indirect = res;
while !(*indirect).is_null() {
indirect = &mut (**indirect).ai_next;
while !(unsafe { *indirect }).is_null() {
indirect = &mut unsafe { (**indirect).ai_next };
}
*indirect = Box::into_raw(addrinfo);
unsafe { *indirect = Box::into_raw(addrinfo) };
}
0
@@ -924,7 +952,7 @@ pub unsafe extern "C" fn getnameinfo(
return EAI_FAMILY;
}
let sa = &*(addr as *const sockaddr_in);
let sa = unsafe { &*(addr as *const sockaddr_in) };
if !serv.is_null() && servlen > 0 {
if flags & NI_NUMERICSERV != 0 {
@@ -933,11 +961,17 @@ pub unsafe extern "C" fn getnameinfo(
if (servlen as usize) <= port_bytes.len() {
return EAI_MEMORY; // Buffer too small
}
ptr::copy_nonoverlapping(port_bytes.as_ptr() as *const c_char, serv, port_bytes.len());
*serv.add(port_bytes.len()) = 0;
unsafe {
ptr::copy_nonoverlapping(
port_bytes.as_ptr() as *const c_char,
serv,
port_bytes.len(),
)
};
unsafe { *serv.add(port_bytes.len()) = 0 };
} else {
// TODO: Implement service name lookup (e.g., from /etc/services)
*serv = 0;
unsafe { *serv = 0 };
}
}
@@ -949,8 +983,10 @@ pub unsafe extern "C" fn getnameinfo(
if (hostlen as usize) <= ip_bytes.len() {
return EAI_MEMORY; // Buffer too small
}
ptr::copy_nonoverlapping(ip_bytes.as_ptr() as *const c_char, host, ip_bytes.len());
*host.add(ip_bytes.len()) = 0;
unsafe {
ptr::copy_nonoverlapping(ip_bytes.as_ptr() as *const c_char, host, ip_bytes.len())
};
unsafe { *host.add(ip_bytes.len()) = 0 };
} else {
match lookup_addr(sa.sin_addr.clone()).map(|host_names| host_names.into_iter().next()) {
Ok(Some(hostname)) => {
@@ -1002,15 +1038,15 @@ pub unsafe extern "C" fn getnameinfo(
pub unsafe extern "C" fn freeaddrinfo(res: *mut addrinfo) {
let mut ai = res;
while !ai.is_null() {
let bai = Box::from_raw(ai);
let bai = unsafe { Box::from_raw(ai) };
if !bai.ai_canonname.is_null() {
drop(CString::from_raw(bai.ai_canonname));
drop(unsafe { CString::from_raw(bai.ai_canonname) });
}
if !bai.ai_addr.is_null() {
if bai.ai_addrlen == mem::size_of::<sockaddr_in>() as socklen_t {
Box::from_raw(bai.ai_addr as *mut sockaddr_in);
unsafe { Box::from_raw(bai.ai_addr as *mut sockaddr_in) };
} else if bai.ai_addrlen == mem::size_of::<sockaddr_in6>() as socklen_t {
Box::from_raw(bai.ai_addr as *mut sockaddr_in6);
unsafe { Box::from_raw(bai.ai_addr as *mut sockaddr_in6) };
} else {
eprintln!("freeaddrinfo: unknown ai_addrlen {}", bai.ai_addrlen);
}
+26 -23
View File
@@ -1,3 +1,6 @@
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use core::{ptr, sync::atomic::Ordering};
use super::*;
@@ -36,7 +39,7 @@ impl Default for RlctAttr {
#[unsafe(no_mangle)]
pub unsafe extern "C" fn pthread_attr_destroy(attr: *mut pthread_attr_t) -> c_int {
core::ptr::drop_in_place(attr);
unsafe { core::ptr::drop_in_place(attr) };
0
}
@@ -45,7 +48,7 @@ pub unsafe extern "C" fn pthread_attr_getdetachstate(
attr: *const pthread_attr_t,
detachstate: *mut c_int,
) -> c_int {
core::ptr::write(detachstate, (*attr.cast::<RlctAttr>()).detachstate as _);
unsafe { core::ptr::write(detachstate, (*attr.cast::<RlctAttr>()).detachstate as _) };
0
}
@@ -54,7 +57,7 @@ pub unsafe extern "C" fn pthread_attr_getguardsize(
attr: *const pthread_attr_t,
size: *mut size_t,
) -> c_int {
core::ptr::write(size, (*attr.cast::<RlctAttr>()).guardsize);
unsafe { core::ptr::write(size, (*attr.cast::<RlctAttr>()).guardsize) };
0
}
@@ -63,7 +66,7 @@ pub unsafe extern "C" fn pthread_attr_getinheritsched(
attr: *const pthread_attr_t,
inheritsched: *mut c_int,
) -> c_int {
core::ptr::write(inheritsched, (*attr.cast::<RlctAttr>()).inheritsched as _);
unsafe { core::ptr::write(inheritsched, (*attr.cast::<RlctAttr>()).inheritsched as _) };
0
}
@@ -72,7 +75,7 @@ pub unsafe extern "C" fn pthread_attr_getschedparam(
attr: *const pthread_attr_t,
param: *mut sched_param,
) -> c_int {
param.write((*attr.cast::<RlctAttr>()).param);
unsafe { param.write((*attr.cast::<RlctAttr>()).param) };
0
}
@@ -81,7 +84,7 @@ pub unsafe extern "C" fn pthread_attr_getschedpolicy(
attr: *const pthread_attr_t,
policy: *mut c_int,
) -> c_int {
core::ptr::write(policy, (*attr.cast::<RlctAttr>()).schedpolicy as _);
unsafe { core::ptr::write(policy, (*attr.cast::<RlctAttr>()).schedpolicy as _) };
0
}
@@ -90,7 +93,7 @@ pub unsafe extern "C" fn pthread_attr_getscope(
attr: *const pthread_attr_t,
scope: *mut c_int,
) -> c_int {
core::ptr::write(scope, (*attr.cast::<RlctAttr>()).scope as _);
unsafe { core::ptr::write(scope, (*attr.cast::<RlctAttr>()).scope as _) };
0
}
@@ -100,8 +103,8 @@ pub unsafe extern "C" fn pthread_attr_getstack(
stackaddr: *mut *mut c_void,
stacksize: *mut size_t,
) -> c_int {
core::ptr::write(stackaddr, (*attr.cast::<RlctAttr>()).stack as _);
core::ptr::write(stacksize, (*attr.cast::<RlctAttr>()).stacksize as _);
unsafe { core::ptr::write(stackaddr, (*attr.cast::<RlctAttr>()).stack as _) };
unsafe { core::ptr::write(stacksize, (*attr.cast::<RlctAttr>()).stacksize as _) };
0
}
@@ -110,13 +113,13 @@ pub unsafe extern "C" fn pthread_attr_getstacksize(
attr: *const pthread_attr_t,
stacksize: *mut size_t,
) -> c_int {
core::ptr::write(stacksize, (*attr.cast::<RlctAttr>()).stacksize as _);
unsafe { core::ptr::write(stacksize, (*attr.cast::<RlctAttr>()).stacksize as _) };
0
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn pthread_attr_init(attr: *mut pthread_attr_t) -> c_int {
core::ptr::write(attr.cast::<RlctAttr>(), RlctAttr::default());
unsafe { core::ptr::write(attr.cast::<RlctAttr>(), RlctAttr::default()) };
0
}
@@ -125,7 +128,7 @@ pub unsafe extern "C" fn pthread_attr_setdetachstate(
attr: *mut pthread_attr_t,
detachstate: c_int,
) -> c_int {
(*attr.cast::<RlctAttr>()).detachstate = detachstate as _;
(unsafe { *attr.cast::<RlctAttr>() }).detachstate = detachstate as _;
0
}
@@ -134,7 +137,7 @@ pub unsafe extern "C" fn pthread_attr_setguardsize(
attr: *mut pthread_attr_t,
guardsize: c_int,
) -> c_int {
(*attr.cast::<RlctAttr>()).guardsize = guardsize as _;
(unsafe { *attr.cast::<RlctAttr>() }).guardsize = guardsize as _;
0
}
@@ -143,7 +146,7 @@ pub unsafe extern "C" fn pthread_attr_setinheritsched(
attr: *mut pthread_attr_t,
inheritsched: c_int,
) -> c_int {
(*attr.cast::<RlctAttr>()).inheritsched = inheritsched as _;
(unsafe { *attr.cast::<RlctAttr>() }).inheritsched = inheritsched as _;
0
}
@@ -152,7 +155,7 @@ pub unsafe extern "C" fn pthread_attr_setschedparam(
attr: *mut pthread_attr_t,
param: *const sched_param,
) -> c_int {
(*attr.cast::<RlctAttr>()).param = param.read();
(unsafe { *attr.cast::<RlctAttr>() }).param = unsafe { param.read() };
0
}
@@ -161,13 +164,13 @@ pub unsafe extern "C" fn pthread_attr_setschedpolicy(
attr: *mut pthread_attr_t,
policy: c_int,
) -> c_int {
(*attr.cast::<RlctAttr>()).schedpolicy = policy as u8;
(unsafe { *attr.cast::<RlctAttr>() }).schedpolicy = policy as u8;
0
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn pthread_attr_setscope(attr: *mut pthread_attr_t, scope: c_int) -> c_int {
(*attr.cast::<RlctAttr>()).scope = scope as u8;
(unsafe { *attr.cast::<RlctAttr>() }).scope = scope as u8;
0
}
@@ -177,8 +180,8 @@ pub unsafe extern "C" fn pthread_attr_setstack(
stackaddr: *mut c_void,
stacksize: size_t,
) -> c_int {
(*attr.cast::<RlctAttr>()).stack = stackaddr as usize;
(*attr.cast::<RlctAttr>()).stacksize = stacksize;
(unsafe { *attr.cast::<RlctAttr>() }).stack = stackaddr as usize;
(unsafe { *attr.cast::<RlctAttr>() }).stacksize = stacksize;
0
}
@@ -187,7 +190,7 @@ pub unsafe extern "C" fn pthread_attr_setstacksize(
attr: *mut pthread_attr_t,
stacksize: size_t,
) -> c_int {
(*attr.cast::<RlctAttr>()).stacksize = stacksize;
(unsafe { *attr.cast::<RlctAttr>() }).stacksize = stacksize;
0
}
@@ -196,10 +199,10 @@ pub unsafe extern "C" fn pthread_getattr_np(
thread_ptr: pthread_t,
attr_ptr: *mut pthread_attr_t,
) -> c_int {
let thread = &*thread_ptr.cast::<Pthread>();
let thread = unsafe { &*thread_ptr.cast::<Pthread>() };
let attr_ptr = attr_ptr.cast::<RlctAttr>();
ptr::write(attr_ptr, RlctAttr::default());
let attr = &mut *attr_ptr;
unsafe { ptr::write(attr_ptr, RlctAttr::default()) };
let attr = unsafe { &mut *attr_ptr };
if thread.flags.load(Ordering::Acquire) & PthreadFlags::DETACHED.bits() != 0 {
attr.detachstate = PTHREAD_CREATE_DETACHED as _;
}
+11 -10
View File
@@ -1,3 +1,6 @@
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use crate::header::errno::*;
use core::num::NonZeroU32;
@@ -27,7 +30,7 @@ pub unsafe extern "C" fn pthread_barrier_destroy(barrier: *mut pthread_barrier_t
// Behavior is undefined if any thread is currently waiting when this is called.
// No-op, currently.
core::ptr::drop_in_place(barrier.cast::<RlctBarrier>());
unsafe { core::ptr::drop_in_place(barrier.cast::<RlctBarrier>()) };
0
}
@@ -39,9 +42,7 @@ pub unsafe extern "C" fn pthread_barrier_init(
attr: *const pthread_barrierattr_t,
count: c_uint,
) -> c_int {
let attr = attr
.cast::<RlctBarrierAttr>()
.as_ref()
let attr = unsafe { attr.cast::<RlctBarrierAttr>().as_ref() }
.copied()
.unwrap_or_default();
@@ -49,7 +50,7 @@ pub unsafe extern "C" fn pthread_barrier_init(
return EINVAL;
};
barrier.cast::<RlctBarrier>().write(RlctBarrier::new(count));
unsafe { barrier.cast::<RlctBarrier>().write(RlctBarrier::new(count)) };
0
}
@@ -60,7 +61,7 @@ fn unlikely(condition: bool) -> bool {
// Not async-signal-safe.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn pthread_barrier_wait(barrier: *mut pthread_barrier_t) -> c_int {
let barrier = &*barrier.cast::<RlctBarrier>();
let barrier = unsafe { &*barrier.cast::<RlctBarrier>() };
match barrier.wait() {
WaitResult::NotifiedAll => PTHREAD_BARRIER_SERIAL_THREAD,
@@ -71,7 +72,7 @@ pub unsafe extern "C" fn pthread_barrier_wait(barrier: *mut pthread_barrier_t) -
// Not async-signal-safe.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn pthread_barrierattr_init(attr: *mut pthread_barrierattr_t) -> c_int {
core::ptr::write(attr.cast::<RlctBarrierAttr>(), RlctBarrierAttr::default());
unsafe { core::ptr::write(attr.cast::<RlctBarrierAttr>(), RlctBarrierAttr::default()) };
0
}
@@ -82,7 +83,7 @@ pub unsafe extern "C" fn pthread_barrierattr_setpshared(
attr: *mut pthread_barrierattr_t,
pshared: c_int,
) -> c_int {
(*attr.cast::<RlctBarrierAttr>()).pshared = pshared;
(unsafe { *attr.cast::<RlctBarrierAttr>() }).pshared = pshared;
0
}
@@ -92,13 +93,13 @@ pub unsafe extern "C" fn pthread_barrierattr_getpshared(
attr: *const pthread_barrierattr_t,
pshared: *mut c_int,
) -> c_int {
core::ptr::write(pshared, (*attr.cast::<RlctBarrierAttr>()).pshared);
unsafe { core::ptr::write(pshared, (*attr.cast::<RlctBarrierAttr>()).pshared) };
0
}
// Not async-signal-safe.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn pthread_barrierattr_destroy(attr: *mut pthread_barrierattr_t) -> c_int {
core::ptr::drop_in_place(attr);
unsafe { core::ptr::drop_in_place(attr) };
0
}
+26 -19
View File
@@ -1,5 +1,8 @@
// Used design from https://www.remlab.net/op/futex-condvar.shtml
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use crate::header::time::CLOCK_REALTIME;
use super::*;
@@ -8,13 +11,13 @@ use super::*;
#[unsafe(no_mangle)]
pub unsafe extern "C" fn pthread_cond_broadcast(cond: *mut pthread_cond_t) -> c_int {
e((&*cond.cast::<RlctCond>()).broadcast())
e((unsafe { &*cond.cast::<RlctCond>() }).broadcast())
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn pthread_cond_destroy(cond: *mut pthread_cond_t) -> c_int {
// No-op
core::ptr::drop_in_place(cond.cast::<RlctCond>());
unsafe { core::ptr::drop_in_place(cond.cast::<RlctCond>()) };
0
}
@@ -23,9 +26,7 @@ pub unsafe extern "C" fn pthread_cond_init(
cond: *mut pthread_cond_t,
attr: *const pthread_condattr_t,
) -> c_int {
let attr = attr
.cast::<RlctCondAttr>()
.as_ref()
let attr = unsafe { attr.cast::<RlctCondAttr>().as_ref() }
.copied()
.unwrap_or_default();
@@ -34,14 +35,14 @@ pub unsafe extern "C" fn pthread_cond_init(
println!("TODO: pthread_cond_init with monotonic clock");
}
cond.cast::<RlctCond>().write(RlctCond::new());
unsafe { cond.cast::<RlctCond>().write(RlctCond::new()) };
0
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn pthread_cond_signal(cond: *mut pthread_cond_t) -> c_int {
e((&*cond.cast::<RlctCond>()).signal())
e((unsafe { &*cond.cast::<RlctCond>() }).signal())
}
#[unsafe(no_mangle)]
@@ -50,7 +51,8 @@ pub unsafe extern "C" fn pthread_cond_timedwait(
mutex: *mut pthread_mutex_t,
timeout: *const timespec,
) -> c_int {
e((&*cond.cast::<RlctCond>()).timedwait(&*mutex.cast::<RlctMutex>(), &*timeout))
e((unsafe { &*cond.cast::<RlctCond>() })
.timedwait(unsafe { &*mutex.cast::<RlctMutex>() }, unsafe { &*timeout }))
}
#[unsafe(no_mangle)]
@@ -60,7 +62,11 @@ pub unsafe extern "C" fn pthread_cond_clockwait(
clock_id: clockid_t,
timeout: *const timespec,
) -> c_int {
e((&*cond.cast::<RlctCond>()).clockwait(&*mutex.cast::<RlctMutex>(), &*timeout, clock_id))
e((unsafe { &*cond.cast::<RlctCond>() }).clockwait(
unsafe { &*mutex.cast::<RlctMutex>() },
unsafe { &*timeout },
clock_id,
))
}
#[unsafe(no_mangle)]
@@ -68,12 +74,12 @@ pub unsafe extern "C" fn pthread_cond_wait(
cond: *mut pthread_cond_t,
mutex: *mut pthread_mutex_t,
) -> c_int {
e((&*cond.cast::<RlctCond>()).wait(&*mutex.cast::<RlctMutex>()))
e((unsafe { &*cond.cast::<RlctCond>() }).wait(unsafe { &*mutex.cast::<RlctMutex>() }))
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn pthread_condattr_destroy(condattr: *mut pthread_condattr_t) -> c_int {
core::ptr::drop_in_place(condattr.cast::<RlctCondAttr>());
unsafe { core::ptr::drop_in_place(condattr.cast::<RlctCondAttr>()) };
// No-op
0
}
@@ -83,7 +89,7 @@ pub unsafe extern "C" fn pthread_condattr_getclock(
condattr: *const pthread_condattr_t,
clock: *mut clockid_t,
) -> c_int {
core::ptr::write(clock, (*condattr.cast::<RlctCondAttr>()).clock);
unsafe { core::ptr::write(clock, (*condattr.cast::<RlctCondAttr>()).clock) };
0
}
@@ -92,16 +98,17 @@ pub unsafe extern "C" fn pthread_condattr_getpshared(
condattr: *const pthread_condattr_t,
pshared: *mut c_int,
) -> c_int {
core::ptr::write(pshared, (*condattr.cast::<RlctCondAttr>()).pshared);
unsafe { core::ptr::write(pshared, (*condattr.cast::<RlctCondAttr>()).pshared) };
0
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn pthread_condattr_init(condattr: *mut pthread_condattr_t) -> c_int {
condattr
.cast::<RlctCondAttr>()
.write(RlctCondAttr::default());
unsafe {
condattr
.cast::<RlctCondAttr>()
.write(RlctCondAttr::default())
};
0
}
@@ -110,7 +117,7 @@ pub unsafe extern "C" fn pthread_condattr_setclock(
condattr: *mut pthread_condattr_t,
clock: clockid_t,
) -> c_int {
(*condattr.cast::<RlctCondAttr>()).clock = clock;
(unsafe { *condattr.cast::<RlctCondAttr>() }).clock = clock;
0
}
@@ -119,7 +126,7 @@ pub unsafe extern "C" fn pthread_condattr_setpshared(
condattr: *mut pthread_condattr_t,
pshared: c_int,
) -> c_int {
(*condattr.cast::<RlctCondAttr>()).pshared = pshared;
(unsafe { *condattr.cast::<RlctCondAttr>() }).pshared = pshared;
0
}
+32 -23
View File
@@ -2,6 +2,9 @@
//!
//! See <https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/pthread.h.html>.
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use alloc::collections::LinkedList;
use core::{cell::Cell, ptr::NonNull};
@@ -92,7 +95,7 @@ pub static mut fork_hooks: [LinkedList<extern "C" fn()>; 3] = [const { LinkedLis
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/pthread_cancel.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn pthread_cancel(thread: pthread_t) -> c_int {
match pthread::cancel(&*thread.cast()) {
match unsafe { pthread::cancel(&*thread.cast()) } {
Ok(()) => 0,
Err(Errno(error)) => error,
}
@@ -106,11 +109,11 @@ pub unsafe extern "C" fn pthread_create(
start_routine: extern "C" fn(arg: *mut c_void) -> *mut c_void,
arg: *mut c_void,
) -> c_int {
let attr = attr.cast::<RlctAttr>().as_ref();
let attr = unsafe { attr.cast::<RlctAttr>().as_ref() };
match pthread::create(attr, start_routine, arg) {
match unsafe { pthread::create(attr, start_routine, arg) } {
Ok(ptr) => {
core::ptr::write(pthread, ptr);
unsafe { core::ptr::write(pthread, ptr) };
0
}
Err(Errno(code)) => code,
@@ -120,7 +123,7 @@ pub unsafe extern "C" fn pthread_create(
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/pthread_detach.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn pthread_detach(pthread: pthread_t) -> c_int {
match pthread::detach(&*pthread.cast()) {
match unsafe { pthread::detach(&*pthread.cast()) } {
Ok(()) => 0,
Err(Errno(errno)) => errno,
}
@@ -160,7 +163,7 @@ pub extern "C" fn pthread_atfork(
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/pthread_exit.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn pthread_exit(retval: *mut c_void) -> ! {
pthread::exit_current_thread(pthread::Retval(retval))
unsafe { pthread::exit_current_thread(pthread::Retval(retval)) }
}
// Not in latest POSIX, mark as depreciated?
@@ -177,9 +180,9 @@ pub unsafe extern "C" fn pthread_getcpuclockid(
thread: pthread_t,
clock_out: *mut clockid_t,
) -> c_int {
match pthread::get_cpu_clkid(&*thread.cast()) {
match pthread::get_cpu_clkid(unsafe { &*thread.cast() }) {
Ok(clock) => {
clock_out.write(clock);
unsafe { clock_out.write(clock) };
0
}
Err(Errno(error)) => error,
@@ -193,11 +196,10 @@ pub unsafe extern "C" fn pthread_getschedparam(
policy_out: *mut c_int,
param_out: *mut sched_param,
) -> c_int {
match pthread::get_sched_param(&*thread.cast()) {
match pthread::get_sched_param(unsafe { &*thread.cast() }) {
Ok((policy, param)) => {
policy_out.write(policy);
param_out.write(param);
unsafe { policy_out.write(policy) };
unsafe { param_out.write(param) };
0
}
Err(Errno(error)) => error,
@@ -210,10 +212,10 @@ pub use tls::*;
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/pthread_join.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn pthread_join(thread: pthread_t, retval: *mut *mut c_void) -> c_int {
match pthread::join(&*thread.cast()) {
match unsafe { pthread::join(&*thread.cast()) } {
Ok(pthread::Retval(ret)) => {
if !retval.is_null() {
core::ptr::write(retval, ret);
unsafe { core::ptr::write(retval, ret) };
}
0
}
@@ -233,7 +235,7 @@ pub use self::rwlock::*;
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/pthread_self.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn pthread_self() -> pthread_t {
pthread::current_thread().unwrap_unchecked() as *const _ as *mut _
(unsafe { pthread::current_thread().unwrap_unchecked() }) as *const _ as *mut _
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/pthread_setcancelstate.html>.
@@ -244,7 +246,7 @@ pub unsafe extern "C" fn pthread_setcancelstate(state: c_int, oldstate: *mut c_i
// POSIX doesn't imply oldstate can be NULL anywhere, but a lot of C code probably
// relies on it...
if let Some(oldstate) = NonNull::new(oldstate) {
oldstate.write(old);
unsafe { oldstate.write(old) };
}
0
}
@@ -260,7 +262,7 @@ pub unsafe extern "C" fn pthread_setcanceltype(ty: c_int, oldty: *mut c_int) ->
// POSIX doesn't imply oldty can be NULL anywhere, but a lot of C code probably relies
// on it...
if let Some(oldty) = NonNull::new(oldty) {
oldty.write(old);
unsafe { oldty.write(old) };
}
0
}
@@ -283,13 +285,20 @@ pub unsafe extern "C" fn pthread_setschedparam(
policy: c_int,
param: *const sched_param,
) -> c_int {
e(pthread::set_sched_param(&*thread.cast(), policy, &*param))
e(pthread::set_sched_param(
unsafe { &*thread.cast() },
policy,
unsafe { &*param },
))
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/pthread_setschedprio.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn pthread_setschedprio(thread: pthread_t, prio: c_int) -> c_int {
e(pthread::set_sched_priority(&*thread.cast(), prio))
e(pthread::set_sched_priority(
unsafe { &*thread.cast() },
prio,
))
}
pub mod spin;
@@ -298,7 +307,7 @@ pub use self::spin::*;
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/pthread_setcancelstate.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn pthread_testcancel() {
pthread::testcancel();
unsafe { pthread::testcancel() };
}
// Must be the same struct as defined in the pthread_cleanup_push macro.
@@ -317,14 +326,14 @@ pub(crate) static CLEANUP_LL_HEAD: Cell<*const CleanupLinkedListEntry> =
#[unsafe(no_mangle)]
pub unsafe extern "C" fn __relibc_internal_pthread_cleanup_push(new_entry: *mut c_void) {
let new_entry = &mut *new_entry.cast::<CleanupLinkedListEntry>();
let new_entry = unsafe { &mut *new_entry.cast::<CleanupLinkedListEntry>() };
new_entry.prev = CLEANUP_LL_HEAD.get().cast();
CLEANUP_LL_HEAD.set(new_entry);
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn __relibc_internal_pthread_cleanup_pop(execute: c_int) {
let prev_head = CLEANUP_LL_HEAD.get().read();
let prev_head = unsafe { CLEANUP_LL_HEAD.get().read() };
CLEANUP_LL_HEAD.set(prev_head.prev.cast());
if execute != 0 {
@@ -338,7 +347,7 @@ pub(crate) unsafe fn run_destructor_stack() {
let mut ptr = CLEANUP_LL_HEAD.get();
while !ptr.is_null() {
let entry = ptr.read();
let entry = unsafe { ptr.read() };
ptr = entry.prev.cast();
(entry.routine)(entry.arg);
+28 -27
View File
@@ -1,3 +1,6 @@
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use super::*;
use crate::{
@@ -12,12 +15,12 @@ use crate::{
#[unsafe(no_mangle)]
pub unsafe extern "C" fn pthread_mutex_consistent(mutex: *mut pthread_mutex_t) -> c_int {
e((&*mutex.cast::<RlctMutex>()).make_consistent())
e((unsafe { &*mutex.cast::<RlctMutex>() }).make_consistent())
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn pthread_mutex_destroy(mutex: *mut pthread_mutex_t) -> c_int {
// No-op
core::ptr::drop_in_place(mutex.cast::<RlctMutex>());
unsafe { core::ptr::drop_in_place(mutex.cast::<RlctMutex>()) };
0
}
@@ -26,9 +29,9 @@ pub unsafe extern "C" fn pthread_mutex_getprioceiling(
mutex: *const pthread_mutex_t,
prioceiling: *mut c_int,
) -> c_int {
match (&*mutex.cast::<RlctMutex>()).prioceiling() {
match (unsafe { &*mutex.cast::<RlctMutex>() }).prioceiling() {
Ok(value) => {
prioceiling.write(value);
unsafe { prioceiling.write(value) };
0
}
Err(Errno(errno)) => errno,
@@ -40,15 +43,13 @@ pub unsafe extern "C" fn pthread_mutex_init(
mutex: *mut pthread_mutex_t,
attr: *const pthread_mutexattr_t,
) -> c_int {
let attr = attr
.cast::<RlctMutexAttr>()
.as_ref()
let attr = unsafe { attr.cast::<RlctMutexAttr>().as_ref() }
.copied()
.unwrap_or_default();
match RlctMutex::new(&attr) {
Ok(new) => {
mutex.cast::<RlctMutex>().write(new);
unsafe { mutex.cast::<RlctMutex>().write(new) };
0
}
@@ -57,7 +58,7 @@ pub unsafe extern "C" fn pthread_mutex_init(
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn pthread_mutex_lock(mutex: *mut pthread_mutex_t) -> c_int {
e((&*mutex.cast::<RlctMutex>()).lock())
e((unsafe { &*mutex.cast::<RlctMutex>() }).lock())
}
#[unsafe(no_mangle)]
@@ -66,9 +67,9 @@ pub unsafe extern "C" fn pthread_mutex_setprioceiling(
prioceiling: c_int,
old_prioceiling: *mut c_int,
) -> c_int {
match (&*mutex.cast::<RlctMutex>()).replace_prioceiling(prioceiling) {
match (unsafe { &*mutex.cast::<RlctMutex>() }).replace_prioceiling(prioceiling) {
Ok(old) => {
old_prioceiling.write(old);
unsafe { old_prioceiling.write(old) };
0
}
Err(Errno(errno)) => errno,
@@ -80,27 +81,27 @@ pub unsafe extern "C" fn pthread_mutex_timedlock(
mutex: *mut pthread_mutex_t,
abstime: *const timespec,
) -> c_int {
let relative = match timespec_realtime_to_monotonic(*abstime) {
let relative = match timespec_realtime_to_monotonic(unsafe { *abstime }) {
Ok(relative) => relative,
Err(err) => return e(Err(err)),
};
e((&*mutex.cast::<RlctMutex>()).lock_with_timeout(&relative))
e((unsafe { &*mutex.cast::<RlctMutex>() }).lock_with_timeout(&relative))
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn pthread_mutex_trylock(mutex: *mut pthread_mutex_t) -> c_int {
e((&*mutex.cast::<RlctMutex>()).try_lock())
e((unsafe { &*mutex.cast::<RlctMutex>() }).try_lock())
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn pthread_mutex_unlock(mutex: *mut pthread_mutex_t) -> c_int {
e((&*mutex.cast::<RlctMutex>()).unlock())
e((unsafe { &*mutex.cast::<RlctMutex>() }).unlock())
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn pthread_mutexattr_destroy(attr: *mut pthread_mutexattr_t) -> c_int {
// No-op
core::ptr::drop_in_place(attr.cast::<RlctMutexAttr>());
unsafe { core::ptr::drop_in_place(attr.cast::<RlctMutexAttr>()) };
0
}
@@ -109,7 +110,7 @@ pub unsafe extern "C" fn pthread_mutexattr_getprioceiling(
attr: *const pthread_mutexattr_t,
prioceiling: *mut c_int,
) -> c_int {
prioceiling.write((*attr.cast::<RlctMutexAttr>()).prioceiling);
unsafe { prioceiling.write((*attr.cast::<RlctMutexAttr>()).prioceiling) };
0
}
@@ -118,7 +119,7 @@ pub unsafe extern "C" fn pthread_mutexattr_getprotocol(
attr: *const pthread_mutexattr_t,
protocol: *mut c_int,
) -> c_int {
protocol.write((*attr.cast::<RlctMutexAttr>()).protocol);
unsafe { protocol.write((*attr.cast::<RlctMutexAttr>()).protocol) };
0
}
@@ -127,7 +128,7 @@ pub unsafe extern "C" fn pthread_mutexattr_getpshared(
attr: *const pthread_mutexattr_t,
pshared: *mut c_int,
) -> c_int {
pshared.write((*attr.cast::<RlctMutexAttr>()).pshared);
unsafe { pshared.write((*attr.cast::<RlctMutexAttr>()).pshared) };
0
}
@@ -136,7 +137,7 @@ pub unsafe extern "C" fn pthread_mutexattr_getrobust(
attr: *const pthread_mutexattr_t,
robust: *mut c_int,
) -> c_int {
robust.write((*attr.cast::<RlctMutexAttr>()).robust);
unsafe { robust.write((*attr.cast::<RlctMutexAttr>()).robust) };
0
}
#[unsafe(no_mangle)]
@@ -144,12 +145,12 @@ pub unsafe extern "C" fn pthread_mutexattr_gettype(
attr: *const pthread_mutexattr_t,
ty: *mut c_int,
) -> c_int {
ty.write((*attr.cast::<RlctMutexAttr>()).ty);
unsafe { ty.write((*attr.cast::<RlctMutexAttr>()).ty) };
0
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn pthread_mutexattr_init(attr: *mut pthread_mutexattr_t) -> c_int {
attr.cast::<RlctMutexAttr>().write(RlctMutexAttr::default());
unsafe { attr.cast::<RlctMutexAttr>().write(RlctMutexAttr::default()) };
0
}
@@ -158,7 +159,7 @@ pub unsafe extern "C" fn pthread_mutexattr_setprioceiling(
attr: *mut pthread_mutexattr_t,
prioceiling: c_int,
) -> c_int {
(*attr.cast::<RlctMutexAttr>()).prioceiling = prioceiling;
(unsafe { *attr.cast::<RlctMutexAttr>() }).prioceiling = prioceiling;
0
}
@@ -167,7 +168,7 @@ pub unsafe extern "C" fn pthread_mutexattr_setprotocol(
attr: *mut pthread_mutexattr_t,
protocol: c_int,
) -> c_int {
(*attr.cast::<RlctMutexAttr>()).protocol = protocol;
(unsafe { *attr.cast::<RlctMutexAttr>() }).protocol = protocol;
0
}
@@ -176,7 +177,7 @@ pub unsafe extern "C" fn pthread_mutexattr_setpshared(
attr: *mut pthread_mutexattr_t,
pshared: c_int,
) -> c_int {
(*attr.cast::<RlctMutexAttr>()).pshared = pshared;
(unsafe { *attr.cast::<RlctMutexAttr>() }).pshared = pshared;
0
}
@@ -185,7 +186,7 @@ pub unsafe extern "C" fn pthread_mutexattr_setrobust(
attr: *mut pthread_mutexattr_t,
robust: c_int,
) -> c_int {
(*attr.cast::<RlctMutexAttr>()).robust = robust;
(unsafe { *attr.cast::<RlctMutexAttr>() }).robust = robust;
0
}
#[unsafe(no_mangle)]
@@ -193,7 +194,7 @@ pub unsafe extern "C" fn pthread_mutexattr_settype(
attr: *mut pthread_mutexattr_t,
ty: c_int,
) -> c_int {
(*attr.cast::<RlctMutexAttr>()).ty = ty;
(unsafe { *attr.cast::<RlctMutexAttr>() }).ty = ty;
0
}
+4 -1
View File
@@ -1,3 +1,6 @@
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use super::*;
// PTHREAD_ONCE_INIT
@@ -7,7 +10,7 @@ pub unsafe extern "C" fn pthread_once(
once: *mut pthread_once_t,
constructor: extern "C" fn(),
) -> c_int {
let once = &*once.cast::<RlctOnce>();
let once = unsafe { &*once.cast::<RlctOnce>() };
// TODO: Cancellation points
+25 -20
View File
@@ -1,3 +1,6 @@
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use super::*;
use crate::header::errno::EBUSY;
@@ -9,21 +12,21 @@ pub unsafe extern "C" fn pthread_rwlock_init(
rwlock: *mut pthread_rwlock_t,
attr: *const pthread_rwlockattr_t,
) -> c_int {
let attr = attr
.cast::<RlctRwlockAttr>()
.as_ref()
let attr = unsafe { attr.cast::<RlctRwlockAttr>().as_ref() }
.copied()
.unwrap_or_default();
rwlock
.cast::<RlctRwlock>()
.write(RlctRwlock::new(attr.pshared));
unsafe {
rwlock
.cast::<RlctRwlock>()
.write(RlctRwlock::new(attr.pshared))
};
0
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn pthread_rwlock_rdlock(rwlock: *mut pthread_rwlock_t) -> c_int {
get(rwlock).acquire_read_lock(None);
unsafe { get(rwlock) }.acquire_read_lock(None);
0
}
@@ -32,7 +35,7 @@ pub unsafe extern "C" fn pthread_rwlock_timedrdlock(
rwlock: *mut pthread_rwlock_t,
timeout: *const timespec,
) -> c_int {
get(rwlock).acquire_read_lock(Some(&*timeout));
unsafe { get(rwlock) }.acquire_read_lock(Some(unsafe { &*timeout }));
0
}
@@ -41,41 +44,43 @@ pub unsafe extern "C" fn pthread_rwlock_timedwrlock(
rwlock: *mut pthread_rwlock_t,
timeout: *const timespec,
) -> c_int {
get(rwlock).acquire_write_lock(Some(&*timeout));
unsafe { get(rwlock) }.acquire_write_lock(Some(unsafe { &*timeout }));
0
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn pthread_rwlock_tryrdlock(rwlock: *mut pthread_rwlock_t) -> c_int {
match get(rwlock).try_acquire_read_lock() {
match unsafe { get(rwlock) }.try_acquire_read_lock() {
Ok(()) => 0,
Err(_) => EBUSY,
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn pthread_rwlock_trywrlock(rwlock: *mut pthread_rwlock_t) -> c_int {
match get(rwlock).try_acquire_write_lock() {
match unsafe { get(rwlock) }.try_acquire_write_lock() {
Ok(()) => 0,
Err(_) => EBUSY,
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn pthread_rwlock_unlock(rwlock: *mut pthread_rwlock_t) -> c_int {
get(rwlock).unlock();
unsafe { get(rwlock) }.unlock();
0
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn pthread_rwlock_wrlock(rwlock: *mut pthread_rwlock_t) -> c_int {
get(rwlock).acquire_write_lock(None);
unsafe { get(rwlock) }.acquire_write_lock(None);
0
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn pthread_rwlockattr_init(attr: *mut pthread_rwlockattr_t) -> c_int {
attr.cast::<RlctRwlockAttr>()
.write(RlctRwlockAttr::default());
unsafe {
attr.cast::<RlctRwlockAttr>()
.write(RlctRwlockAttr::default())
};
0
}
@@ -85,7 +90,7 @@ pub unsafe extern "C" fn pthread_rwlockattr_getpshared(
attr: *const pthread_rwlockattr_t,
pshared_out: *mut c_int,
) -> c_int {
core::ptr::write(pshared_out, (*attr.cast::<RlctRwlockAttr>()).pshared.raw());
unsafe { core::ptr::write(pshared_out, (*attr.cast::<RlctRwlockAttr>()).pshared.raw()) };
0
}
@@ -95,7 +100,7 @@ pub unsafe extern "C" fn pthread_rwlockattr_setpshared(
attr: *mut pthread_rwlockattr_t,
pshared: c_int,
) -> c_int {
(*attr.cast::<RlctRwlockAttr>()).pshared =
(unsafe { *attr.cast::<RlctRwlockAttr>() }).pshared =
Pshared::from_raw(pshared).expect("invalid pshared in pthread_rwlockattr_setpshared");
0
@@ -103,13 +108,13 @@ pub unsafe extern "C" fn pthread_rwlockattr_setpshared(
#[unsafe(no_mangle)]
pub unsafe extern "C" fn pthread_rwlockattr_destroy(attr: *mut pthread_rwlockattr_t) -> c_int {
core::ptr::drop_in_place(attr);
unsafe { core::ptr::drop_in_place(attr) };
0
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn pthread_rwlock_destroy(rwlock: *mut pthread_rwlock_t) -> c_int {
core::ptr::drop_in_place(rwlock);
unsafe { core::ptr::drop_in_place(rwlock) };
0
}
@@ -122,5 +127,5 @@ pub(crate) struct RlctRwlockAttr {
}
#[inline]
unsafe fn get<'a>(ptr: *mut pthread_rwlock_t) -> &'a RlctRwlock {
&*ptr.cast()
unsafe { &*ptr.cast() }
}
+12 -7
View File
@@ -1,3 +1,6 @@
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use core::sync::atomic::{AtomicI32 as AtomicInt, Ordering};
use crate::header::errno::EBUSY;
@@ -9,7 +12,7 @@ const LOCKED: c_int = 1;
#[unsafe(no_mangle)]
pub unsafe extern "C" fn pthread_spin_destroy(spinlock: *mut pthread_spinlock_t) -> c_int {
let _spinlock = &mut *spinlock.cast::<RlctSpinlock>();
let _spinlock = unsafe { &mut *spinlock.cast::<RlctSpinlock>() };
// No-op
0
@@ -22,15 +25,17 @@ pub unsafe extern "C" fn pthread_spin_init(
// TODO: pshared doesn't matter in most situations, as memory is just memory, but this may be
// different on some architectures...
spinlock.cast::<RlctSpinlock>().write(RlctSpinlock {
inner: AtomicInt::new(UNLOCKED),
});
unsafe {
spinlock.cast::<RlctSpinlock>().write(RlctSpinlock {
inner: AtomicInt::new(UNLOCKED),
})
};
0
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn pthread_spin_lock(spinlock: *mut pthread_spinlock_t) -> c_int {
let spinlock = &*spinlock.cast::<RlctSpinlock>();
let spinlock = unsafe { &*spinlock.cast::<RlctSpinlock>() };
loop {
match spinlock.inner.compare_exchange_weak(
@@ -48,7 +53,7 @@ pub unsafe extern "C" fn pthread_spin_lock(spinlock: *mut pthread_spinlock_t) ->
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn pthread_spin_trylock(spinlock: *mut pthread_spinlock_t) -> c_int {
let spinlock = &*spinlock.cast::<RlctSpinlock>();
let spinlock = unsafe { &*spinlock.cast::<RlctSpinlock>() };
match spinlock
.inner
@@ -62,7 +67,7 @@ pub unsafe extern "C" fn pthread_spin_trylock(spinlock: *mut pthread_spinlock_t)
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn pthread_spin_unlock(spinlock: *mut pthread_spinlock_t) -> c_int {
let spinlock = &*spinlock.cast::<RlctSpinlock>();
let spinlock = unsafe { &*spinlock.cast::<RlctSpinlock>() };
spinlock.inner.store(UNLOCKED, Ordering::Release);
+4 -1
View File
@@ -1,3 +1,6 @@
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use super::*;
// TODO: Hashmap?
@@ -52,7 +55,7 @@ pub unsafe extern "C" fn pthread_key_create(
},
);
key_ptr.write(key);
unsafe { key_ptr.write(key) };
0
}
+25 -16
View File
@@ -1,3 +1,6 @@
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use crate::{
header::{fcntl, sys_ioctl, unistd},
io::{Cursor, Write},
@@ -6,28 +9,32 @@ use crate::{
pub(super) unsafe fn openpty(name: &mut [u8]) -> Result<(c_int, c_int), ()> {
//TODO: wrap in auto-close struct
let master = fcntl::open(c"/dev/ptmx".as_ptr(), fcntl::O_RDWR | fcntl::O_NOCTTY, 0);
let master = unsafe { fcntl::open(c"/dev/ptmx".as_ptr(), fcntl::O_RDWR | fcntl::O_NOCTTY, 0) };
if master < 0 {
return Err(());
}
let mut lock: c_int = 0;
if sys_ioctl::ioctl(
master,
sys_ioctl::TIOCSPTLCK,
&mut lock as *mut c_int as *mut c_void,
) != 0
if unsafe {
sys_ioctl::ioctl(
master,
sys_ioctl::TIOCSPTLCK,
&mut lock as *mut c_int as *mut c_void,
)
} != 0
{
unistd::close(master);
return Err(());
}
let mut ptn: c_int = 0;
if sys_ioctl::ioctl(
master,
sys_ioctl::TIOCGPTN,
&mut ptn as *mut c_int as *mut c_void,
) != 0
if unsafe {
sys_ioctl::ioctl(
master,
sys_ioctl::TIOCGPTN,
&mut ptn as *mut c_int as *mut c_void,
)
} != 0
{
unistd::close(master);
return Err(());
@@ -36,11 +43,13 @@ pub(super) unsafe fn openpty(name: &mut [u8]) -> Result<(c_int, c_int), ()> {
let mut cursor = Cursor::new(name);
write!(cursor, "/dev/pts/{}\0", ptn);
let slave = fcntl::open(
cursor.get_ref().as_ptr() as *const c_char,
fcntl::O_RDWR | fcntl::O_NOCTTY,
0,
);
let slave = unsafe {
fcntl::open(
cursor.get_ref().as_ptr() as *const c_char,
fcntl::O_RDWR | fcntl::O_NOCTTY,
0,
)
};
if slave < 0 {
unistd::close(master);
return Err(());
+36 -29
View File
@@ -2,6 +2,9 @@
//!
//! Non-POSIX, see <https://www.man7.org/linux/man-pages/man3/openpty.3.html>.
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use core::{mem, ptr, slice};
use crate::{
@@ -31,26 +34,26 @@ pub unsafe extern "C" fn openpty(
) -> c_int {
let mut tmp_name = [0; limits::PATH_MAX];
let name = if !namep.is_null() {
slice::from_raw_parts_mut(namep as *mut u8, limits::PATH_MAX)
unsafe { slice::from_raw_parts_mut(namep as *mut u8, limits::PATH_MAX) }
} else {
&mut tmp_name
};
let (master, slave) = match imp::openpty(name) {
let (master, slave) = match unsafe { imp::openpty(name) } {
Ok(ok) => ok,
Err(()) => return -1,
};
if !termp.is_null() {
termios::tcsetattr(slave, termios::TCSANOW, termp);
unsafe { termios::tcsetattr(slave, termios::TCSANOW, termp) };
}
if !winp.is_null() {
sys_ioctl::ioctl(slave, sys_ioctl::TIOCSWINSZ, winp as *mut c_void);
unsafe { sys_ioctl::ioctl(slave, sys_ioctl::TIOCSWINSZ, winp as *mut c_void) };
}
*amaster = master;
*aslave = slave;
unsafe { *amaster = master };
unsafe { *aslave = slave };
return 0;
}
@@ -72,57 +75,61 @@ pub unsafe extern "C" fn forkpty(
let mut set = signal::sigset_t::default();
let mut oldset = signal::sigset_t::default();
if openpty(&mut m, &mut s, name, tio, ws) < 0 {
if unsafe { openpty(&mut m, &mut s, name, tio, ws) } < 0 {
return -1;
}
signal::sigfillset(&mut set);
signal::pthread_sigmask(signal::SIG_BLOCK, &mut set, &mut oldset);
pthread::pthread_setcancelstate(pthread::PTHREAD_CANCEL_DISABLE, &mut cs);
unsafe { signal::sigfillset(&mut set) };
unsafe { signal::pthread_sigmask(signal::SIG_BLOCK, &mut set, &mut oldset) };
unsafe { pthread::pthread_setcancelstate(pthread::PTHREAD_CANCEL_DISABLE, &mut cs) };
if unistd::pipe2(p.as_mut_ptr(), fcntl::O_CLOEXEC) != 0 {
if unsafe { unistd::pipe2(p.as_mut_ptr(), fcntl::O_CLOEXEC) } != 0 {
unistd::close(s);
} else {
pid = unistd::fork();
pid = unsafe { unistd::fork() };
if pid == 0 {
unistd::close(m);
unistd::close(p[0]);
if utmp::login_tty(s) != 0 {
unistd::write(
p[1],
platform::ERRNO.as_ptr().cast(),
mem::size_of_val(&platform::ERRNO),
);
if unsafe { utmp::login_tty(s) } != 0 {
unsafe {
unistd::write(
p[1],
platform::ERRNO.as_ptr().cast(),
mem::size_of_val(&platform::ERRNO),
)
};
unistd::_exit(127);
}
unistd::close(p[1]);
pthread::pthread_setcancelstate(cs, ptr::null_mut());
signal::pthread_sigmask(signal::SIG_SETMASK, &mut oldset, ptr::null_mut());
unsafe { pthread::pthread_setcancelstate(cs, ptr::null_mut()) };
unsafe { signal::pthread_sigmask(signal::SIG_SETMASK, &mut oldset, ptr::null_mut()) };
return 0;
}
unistd::close(s);
unistd::close(p[1]);
if unistd::read(
p[0],
&mut ec as *mut c_int as *mut c_void,
mem::size_of::<c_int>(),
) > 0
if unsafe {
unistd::read(
p[0],
&mut ec as *mut c_int as *mut c_void,
mem::size_of::<c_int>(),
)
} > 0
{
let mut status = 0;
sys_wait::waitpid(pid, &mut status, 0);
unsafe { sys_wait::waitpid(pid, &mut status, 0) };
pid = -1;
platform::ERRNO.set(ec);
}
unistd::close(p[0]);
}
if pid > 0 {
*pm = m;
unsafe { *pm = m };
} else {
unistd::close(m);
}
pthread::pthread_setcancelstate(cs, ptr::null_mut());
signal::pthread_sigmask(signal::SIG_SETMASK, &mut oldset, ptr::null_mut());
unsafe { pthread::pthread_setcancelstate(cs, ptr::null_mut()) };
unsafe { signal::pthread_sigmask(signal::SIG_SETMASK, &mut oldset, ptr::null_mut()) };
pid
}
+194 -167
View File
@@ -2,6 +2,9 @@
//!
//! See <https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/stdlib.h.html>.
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use core::{convert::TryFrom, intrinsics, iter, mem, ptr, slice};
use rand::{
Rng, SeedableRng,
@@ -82,7 +85,7 @@ pub unsafe extern "C" fn a64l(s: *const c_char) -> c_long {
// Handle up to 6 input characters (excl. null terminator)
for i in 0..6 {
let digit_char = *s.offset(i);
let digit_char = unsafe { *s.offset(i) };
let digit_value = match digit_char {
0 => break, // Null terminator encountered
@@ -124,7 +127,7 @@ static __stack_chk_guard: uintptr_t = 0xd048c37519fcadfe;
#[unsafe(no_mangle)]
unsafe extern "C" fn __stack_chk_fail() -> ! {
abort();
unsafe { abort() };
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/abs.html>.
@@ -139,7 +142,7 @@ pub unsafe extern "C" fn aligned_alloc(alignment: size_t, size: size_t) -> *mut
if size % alignment == 0 {
/* The size-is-multiple-of-alignment requirement is the only
* difference between aligned_alloc() and memalign(). */
memalign(alignment, size)
unsafe { memalign(alignment, size) }
} else {
platform::ERRNO.set(EINVAL);
ptr::null_mut()
@@ -149,9 +152,9 @@ pub unsafe extern "C" fn aligned_alloc(alignment: size_t, size: size_t) -> *mut
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/at_quick_exit.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn at_quick_exit(func: Option<extern "C" fn()>) -> c_int {
for i in 0..AT_QUICK_EXIT_FUNCS.unsafe_ref().len() {
if AT_QUICK_EXIT_FUNCS.unsafe_ref()[i] == None {
AT_QUICK_EXIT_FUNCS.unsafe_mut()[i] = func;
for i in 0..unsafe { AT_QUICK_EXIT_FUNCS.unsafe_ref().len() } {
if unsafe { AT_QUICK_EXIT_FUNCS.unsafe_ref() }[i] == None {
(unsafe { AT_QUICK_EXIT_FUNCS.unsafe_mut() })[i] = func;
return 0;
}
}
@@ -162,9 +165,9 @@ pub unsafe extern "C" fn at_quick_exit(func: Option<extern "C" fn()>) -> c_int {
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/atexit.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn atexit(func: Option<extern "C" fn()>) -> c_int {
for i in 0..ATEXIT_FUNCS.unsafe_ref().len() {
if ATEXIT_FUNCS.unsafe_ref()[i] == None {
ATEXIT_FUNCS.unsafe_mut()[i] = func;
for i in 0..unsafe { ATEXIT_FUNCS.unsafe_ref().len() } {
if unsafe { ATEXIT_FUNCS.unsafe_ref() }[i] == None {
(unsafe { ATEXIT_FUNCS.unsafe_mut() })[i] = func;
return 0;
}
}
@@ -175,35 +178,35 @@ pub unsafe extern "C" fn atexit(func: Option<extern "C" fn()>) -> c_int {
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/atof.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn atof(s: *const c_char) -> c_double {
strtod(s, ptr::null_mut())
unsafe { strtod(s, ptr::null_mut()) }
}
macro_rules! dec_num_from_ascii {
($s:expr, $t:ty) => {{
let mut s = $s;
// Iterate past whitespace
while ctype::isspace(*s as c_int) != 0 {
s = s.offset(1);
while ctype::isspace(unsafe { *s } as c_int) != 0 {
s = unsafe { s.offset(1) };
}
// Find out if there is a - sign
let neg_sign = match *s {
let neg_sign = match unsafe { *s } {
0x2d => {
s = s.offset(1);
s = unsafe { s.offset(1) };
true
}
// '+' increment s and continue parsing
0x2b => {
s = s.offset(1);
s = unsafe { s.offset(1) };
false
}
_ => false,
};
let mut n: $t = 0;
while ctype::isdigit(*s as c_int) != 0 {
n = 10 * n - (*s as $t - 0x30);
s = s.offset(1);
while ctype::isdigit(unsafe { *s } as c_int) != 0 {
n = 10 * n - (unsafe { *s } as $t - 0x30);
s = unsafe { s.offset(1) };
}
if neg_sign { n } else { -n }
@@ -213,7 +216,7 @@ macro_rules! dec_num_from_ascii {
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/atoi.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn atoi(s: *const c_char) -> c_int {
dec_num_from_ascii!(s, c_int)
unsafe { dec_num_from_ascii!(s, c_int) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/atol.html>.
@@ -229,7 +232,7 @@ pub unsafe extern "C" fn atoll(s: *const c_char) -> c_longlong {
}
unsafe extern "C" fn void_cmp(a: *const c_void, b: *const c_void) -> c_int {
*(a as *const i32) - *(b as *const i32) as c_int
(unsafe { *(a as *const i32) }) - unsafe { *(b as *const i32) } as c_int
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/bsearch.html>.
@@ -246,7 +249,7 @@ pub unsafe extern "C" fn bsearch(
let cmp_fn = compar.unwrap_or(void_cmp);
while len > 0 {
let med = (start as size_t + (len >> 1) * width) as *const c_void;
let diff = cmp_fn(key, med);
let diff = unsafe { cmp_fn(key, med) };
if diff == 0 {
return med as *mut c_void;
} else if diff > 0 {
@@ -266,9 +269,9 @@ pub unsafe extern "C" fn calloc(nelem: size_t, elsize: size_t) -> *mut c_void {
Some(size) => {
/* If allocation fails here, errno setting will be handled
* by malloc() */
let ptr = malloc(size);
let ptr = unsafe { malloc(size) };
if !ptr.is_null() {
ptr.write_bytes(0, size);
unsafe { ptr.write_bytes(0, size) };
}
ptr
}
@@ -337,7 +340,8 @@ pub extern "C" fn ecvt(
#[unsafe(no_mangle)]
pub unsafe extern "C" fn erand48(xsubi: *mut c_ushort) -> c_double {
let params = rand48::params();
let xsubi_mut: &mut [c_ushort; 3] = slice::from_raw_parts_mut(xsubi, 3).try_into().unwrap();
let xsubi_mut: &mut [c_ushort; 3] =
unsafe { slice::from_raw_parts_mut(xsubi, 3).try_into().unwrap() };
let new_xsubi_value = params.step(xsubi_mut.into());
*xsubi_mut = new_xsubi_value.into();
new_xsubi_value.get_f64()
@@ -353,30 +357,30 @@ pub unsafe extern "C" fn exit(status: c_int) -> ! {
fn _fini();
}
for i in (0..ATEXIT_FUNCS.unsafe_ref().len()).rev() {
if let Some(func) = ATEXIT_FUNCS.unsafe_ref()[i] {
for i in (0..unsafe { ATEXIT_FUNCS.unsafe_ref().len() }).rev() {
if let Some(func) = unsafe { ATEXIT_FUNCS.unsafe_ref() }[i] {
(func)();
}
}
// Look for the neighbor functions in memory until the end
let mut f = &__fini_array_end as *const _;
let mut f = unsafe { &__fini_array_end } as *const _;
#[allow(clippy::op_ref)]
while f > &__fini_array_start {
f = f.offset(-1);
(*f)();
while f > unsafe { &__fini_array_start } {
f = unsafe { f.offset(-1) };
(unsafe { *f })();
}
#[cfg(not(target_arch = "riscv64"))] // risc-v uses arrays exclusively
{
_fini();
unsafe { _fini() };
}
ld_so::fini();
unsafe { ld_so::fini() };
crate::pthread::terminate_from_main_thread();
unsafe { crate::pthread::terminate_from_main_thread() };
flush_io_streams();
unsafe { flush_io_streams() };
Sys::exit(status);
}
@@ -400,7 +404,7 @@ pub extern "C" fn fcvt(
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/free.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn free(ptr: *mut c_void) {
platform::free(ptr);
unsafe { platform::free(ptr) };
}
/// See <https://pubs.opengroup.org/onlinepubs/009695399/functions/ecvt.html>.
@@ -418,26 +422,26 @@ unsafe fn find_env(search: *const c_char) -> Option<(usize, *mut c_char)> {
for (i, mut item) in platform::environ_iter().enumerate() {
let mut search = search;
loop {
let end_of_query = *search == 0 || *search == b'=' as c_char;
if *item == 0 {
let end_of_query = unsafe { *search } == 0 || unsafe { *search } == b'=' as c_char;
if unsafe { *item } == 0 {
//TODO: environ has an item without value, is this a problem?
break;
}
if *item == b'=' as c_char || end_of_query {
if *item == b'=' as c_char && end_of_query {
if unsafe { *item } == b'=' as c_char || end_of_query {
if unsafe { *item } == b'=' as c_char && end_of_query {
// Both keys env here
return Some((i, item.add(1)));
return Some((i, unsafe { item.add(1) }));
} else {
break;
}
}
if *item != *search {
if unsafe { *item } != unsafe { *search } {
break;
}
item = item.add(1);
search = search.add(1);
item = unsafe { item.add(1) };
search = unsafe { search.add(1) };
}
}
@@ -447,7 +451,9 @@ unsafe fn find_env(search: *const c_char) -> Option<(usize, *mut c_char)> {
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/getenv.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn getenv(name: *const c_char) -> *mut c_char {
find_env(name).map(|val| val.1).unwrap_or(ptr::null_mut())
unsafe { find_env(name) }
.map(|val| val.1)
.unwrap_or(ptr::null_mut())
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/getsubopt.html>.
@@ -457,48 +463,52 @@ pub unsafe extern "C" fn getsubopt(
keylistp: *const *mut c_char,
valuep: *mut *mut c_char,
) -> c_int {
if optionp.is_null() || (*optionp).is_null() || keylistp.is_null() || valuep.is_null() {
if optionp.is_null()
|| (unsafe { *optionp }).is_null()
|| keylistp.is_null()
|| valuep.is_null()
{
return -1;
}
let start = *optionp;
let start = unsafe { *optionp };
let mut cursor = start;
let mut found_comma = false;
while *cursor != 0 {
if *cursor == b',' as c_char {
*cursor = 0;
*optionp = cursor.add(1);
while unsafe { *cursor } != 0 {
if unsafe { *cursor } == b',' as c_char {
unsafe { *cursor = 0 };
unsafe { *optionp = cursor.add(1) };
found_comma = true;
break;
}
cursor = cursor.add(1);
cursor = unsafe { cursor.add(1) };
}
if !found_comma {
*optionp = cursor;
unsafe { *optionp = cursor };
}
let mut i = 0;
while !(*keylistp.add(i)).is_null() {
let token = *keylistp.add(i);
let token_len = strlen(token);
while !(unsafe { *keylistp.add(i) }).is_null() {
let token = unsafe { *keylistp.add(i) };
let token_len = unsafe { strlen(token) };
if strncmp(start, token, token_len) == 0 {
let suffix_char = *start.add(token_len);
if unsafe { strncmp(start, token, token_len) } == 0 {
let suffix_char = unsafe { *start.add(token_len) };
if suffix_char == b'=' as c_char {
*valuep = start.add(token_len + 1);
unsafe { *valuep = start.add(token_len + 1) };
return i as c_int;
} else if suffix_char == 0 {
*valuep = ptr::null_mut();
unsafe { *valuep = ptr::null_mut() };
return i as c_int;
}
}
i += 1;
}
*valuep = start;
unsafe { *valuep = start };
-1
}
@@ -517,7 +527,7 @@ pub unsafe extern "C" fn initstate(seed: c_uint, state: *mut c_char, size: size_
ptr::null_mut()
} else {
let mut random_state = random::state_lock();
let old_state = random_state.save();
let old_state = unsafe { random_state.save() };
random_state.n = match size {
0..=7 => unreachable!(), // ensured above
8..=31 => 0,
@@ -527,9 +537,9 @@ pub unsafe extern "C" fn initstate(seed: c_uint, state: *mut c_char, size: size_
_ => 63,
};
random_state.x_ptr = (state.cast::<[u8; 4]>()).offset(1);
random_state.seed(seed);
random_state.save();
random_state.x_ptr = unsafe { (state.cast::<[u8; 4]>()).offset(1) };
unsafe { random_state.seed(seed) };
unsafe { random_state.save() };
old_state.cast::<_>()
}
@@ -547,7 +557,9 @@ pub unsafe extern "C" fn initstate(seed: c_uint, state: *mut c_char, size: size_
#[unsafe(no_mangle)]
pub unsafe extern "C" fn jrand48(xsubi: *mut c_ushort) -> c_long {
let params = rand48::params();
let xsubi_mut: &mut [c_ushort; 3] = slice::from_raw_parts_mut(xsubi, 3).try_into().unwrap();
let xsubi_mut: &mut [c_ushort; 3] = unsafe { slice::from_raw_parts_mut(xsubi, 3) }
.try_into()
.unwrap();
let new_xsubi_value = params.step(xsubi_mut.into());
*xsubi_mut = new_xsubi_value.into();
new_xsubi_value.get_i32()
@@ -567,13 +579,13 @@ pub unsafe extern "C" fn l64a(value: c_long) -> *mut c_char {
let num_output_digits = usize::try_from(6 - (value_as_i32.leading_zeros() + 4) / 6).unwrap();
// Reset buffer (and have null terminator in place for any result)
L64A_BUFFER.unsafe_set([0; 7]);
unsafe { L64A_BUFFER.unsafe_set([0; 7]) };
for i in 0..num_output_digits {
// Conversion to c_char always succeeds for the range 0..=63
let digit_value = c_char::try_from((value_as_i32 >> 6 * i) & 63).unwrap();
L64A_BUFFER.unsafe_mut()[i] = match digit_value {
(unsafe { L64A_BUFFER.unsafe_mut() })[i] = match digit_value {
0..=11 => {
// ./0123456789 for values 0 to 11. b'.' == 46
46 + digit_value
@@ -590,7 +602,7 @@ pub unsafe extern "C" fn l64a(value: c_long) -> *mut c_char {
};
}
L64A_BUFFER.unsafe_mut().as_mut_ptr()
unsafe { L64A_BUFFER.unsafe_mut().as_mut_ptr() }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/labs.html>.
@@ -613,7 +625,7 @@ pub unsafe extern "C" fn lcong48(param: *mut c_ushort) {
let mut xsubi = rand48::xsubi_lock();
let mut params = rand48::params_mut();
let param_slice = slice::from_raw_parts(param, 7);
let param_slice = unsafe { slice::from_raw_parts(param, 7) };
let xsubi_ref: &[c_ushort; 3] = param_slice[0..3].try_into().unwrap();
let a_ref: &[c_ushort; 3] = param_slice[3..6].try_into().unwrap();
@@ -677,7 +689,7 @@ pub extern "C" fn lrand48() -> c_long {
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/malloc.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn malloc(size: size_t) -> *mut c_void {
let ptr = platform::alloc(size);
let ptr = unsafe { platform::alloc(size) };
if ptr.is_null() {
platform::ERRNO.set(ENOMEM);
}
@@ -689,7 +701,7 @@ pub unsafe extern "C" fn malloc(size: size_t) -> *mut c_void {
#[unsafe(no_mangle)]
pub unsafe extern "C" fn memalign(alignment: size_t, size: size_t) -> *mut c_void {
if alignment.is_power_of_two() {
let ptr = platform::alloc_align(size, alignment);
let ptr = unsafe { platform::alloc_align(size, alignment) };
if ptr.is_null() {
platform::ERRNO.set(ENOMEM);
}
@@ -705,7 +717,7 @@ pub unsafe extern "C" fn memalign(alignment: size_t, size: size_t) -> *mut c_voi
pub unsafe extern "C" fn mblen(s: *const c_char, n: size_t) -> c_int {
let mut wc: wchar_t = 0;
let mut state: mbstate_t = mbstate_t {};
let result: usize = mbrtowc(&mut wc, s, n, &mut state);
let result: usize = unsafe { mbrtowc(&mut wc, s, n, &mut state) };
if result == -1isize as usize {
return -1;
@@ -721,14 +733,14 @@ pub unsafe extern "C" fn mblen(s: *const c_char, n: size_t) -> c_int {
#[unsafe(no_mangle)]
pub unsafe extern "C" fn mbstowcs(pwcs: *mut wchar_t, mut s: *const c_char, n: size_t) -> size_t {
let mut state: mbstate_t = mbstate_t {};
mbsrtowcs(pwcs, &mut s, n, &mut state)
unsafe { mbsrtowcs(pwcs, &mut s, n, &mut state) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/mbtowc.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn mbtowc(pwc: *mut wchar_t, s: *const c_char, n: size_t) -> c_int {
let mut state: mbstate_t = mbstate_t {};
mbrtowc(pwc, s, n, &mut state) as c_int
(unsafe { mbrtowc(pwc, s, n, &mut state) }) as c_int
}
fn inner_mktemp<T, F>(name: *mut c_char, suffix_len: c_int, mut attempt: F) -> Option<T>
@@ -786,7 +798,7 @@ fn get_nstime() -> u64 {
#[unsafe(no_mangle)]
pub unsafe extern "C" fn mkdtemp(name: *mut c_char) -> *mut c_char {
inner_mktemp(name, 0, || {
let name_c = CStr::from_ptr(name);
let name_c = unsafe { CStr::from_ptr(name) };
match Sys::mkdir(name_c, 0o700) {
Ok(()) => Some(name),
Err(_) => None,
@@ -798,7 +810,7 @@ pub unsafe extern "C" fn mkdtemp(name: *mut c_char) -> *mut c_char {
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/mkdtemp.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn mkostemp(name: *mut c_char, flags: c_int) -> c_int {
mkostemps(name, 0, flags)
unsafe { mkostemps(name, 0, flags) }
}
/// Non-POSIX, see <https://www.man7.org/linux/man-pages/man3/mkstemp.3.html>.
@@ -814,7 +826,7 @@ pub unsafe extern "C" fn mkostemps(
flags |= O_RDWR | O_CREAT | O_EXCL;
inner_mktemp(name, suffix_len, || {
let name = CStr::from_ptr(name);
let name = unsafe { CStr::from_ptr(name) };
let fd = Sys::open(name, flags, 0o600).or_minus_one_errno();
if fd >= 0 { Some(fd) } else { None }
@@ -825,13 +837,13 @@ pub unsafe extern "C" fn mkostemps(
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/mkdtemp.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn mkstemp(name: *mut c_char) -> c_int {
mkostemps(name, 0, 0)
unsafe { mkostemps(name, 0, 0) }
}
/// Non-POSIX, see <https://www.man7.org/linux/man-pages/man3/mkstemp.3.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn mkstemps(name: *mut c_char, suffix_len: c_int) -> c_int {
mkostemps(name, suffix_len, 0)
unsafe { mkostemps(name, suffix_len, 0) }
}
/// See <https://pubs.opengroup.org/onlinepubs/009695399/functions/mktemp.html>.
@@ -843,7 +855,7 @@ pub unsafe extern "C" fn mkstemps(name: *mut c_char, suffix_len: c_int) -> c_int
#[unsafe(no_mangle)]
pub unsafe extern "C" fn mktemp(name: *mut c_char) -> *mut c_char {
if inner_mktemp(name, 0, || {
let name = CStr::from_ptr(name);
let name = unsafe { CStr::from_ptr(name) };
if Sys::access(name, 0) == Err(Errno(ENOENT)) {
Some(())
} else {
@@ -852,7 +864,7 @@ pub unsafe extern "C" fn mktemp(name: *mut c_char) -> *mut c_char {
})
.is_none()
{
*name = 0;
unsafe { *name = 0 };
}
name
}
@@ -882,7 +894,9 @@ pub extern "C" fn mrand48() -> c_long {
#[unsafe(no_mangle)]
pub unsafe extern "C" fn nrand48(xsubi: *mut c_ushort) -> c_long {
let params = rand48::params();
let xsubi_mut: &mut [c_ushort; 3] = slice::from_raw_parts_mut(xsubi, 3).try_into().unwrap();
let xsubi_mut: &mut [c_ushort; 3] = unsafe { slice::from_raw_parts_mut(xsubi, 3) }
.try_into()
.unwrap();
let new_xsubi_value = params.step(xsubi_mut.into());
*xsubi_mut = new_xsubi_value.into();
new_xsubi_value.get_u31()
@@ -898,11 +912,11 @@ pub unsafe extern "C" fn posix_memalign(
const VOID_PTR_SIZE: usize = mem::size_of::<*mut c_void>();
if alignment % VOID_PTR_SIZE == 0 && alignment.is_power_of_two() {
let ptr = platform::alloc_align(size, alignment);
*memptr = ptr;
let ptr = unsafe { platform::alloc_align(size, alignment) };
unsafe { *memptr = ptr };
if ptr.is_null() { ENOMEM } else { 0 }
} else {
*memptr = ptr::null_mut();
unsafe { *memptr = ptr::null_mut() };
EINVAL
}
}
@@ -914,7 +928,7 @@ pub unsafe extern "C" fn posix_openpt(flags: c_int) -> c_int {
let r = open((b"/scheme/pty\0" as *const u8).cast(), O_CREAT);
#[cfg(target_os = "linux")]
let r = open((b"/dev/ptmx\0" as *const u8).cast(), flags);
let r = unsafe { open((b"/dev/ptmx\0" as *const u8).cast(), flags) };
if r < 0 && platform::ERRNO.get() == ENOSPC {
platform::ERRNO.set(EAGAIN);
@@ -928,7 +942,7 @@ pub unsafe extern "C" fn posix_openpt(flags: c_int) -> c_int {
pub unsafe extern "C" fn ptsname(fd: c_int) -> *mut c_char {
const PTS_BUFFER_LEN: usize = 9 + mem::size_of::<c_int>() * 3 + 1;
static mut PTS_BUFFER: [c_char; PTS_BUFFER_LEN] = [0; PTS_BUFFER_LEN];
if ptsname_r(fd, &raw mut PTS_BUFFER as *mut _, PTS_BUFFER_LEN) != 0 {
if unsafe { ptsname_r(fd, &raw mut PTS_BUFFER as *mut _, PTS_BUFFER_LEN) } != 0 {
ptr::null_mut()
} else {
&raw mut PTS_BUFFER as *mut _
@@ -942,7 +956,7 @@ pub unsafe extern "C" fn ptsname_r(fd: c_int, buf: *mut c_char, buflen: size_t)
platform::ERRNO.set(EINVAL);
EINVAL
} else {
__ptsname_r(fd, buf, buflen)
unsafe { __ptsname_r(fd, buf, buflen) }
}
}
@@ -975,7 +989,7 @@ unsafe fn __ptsname_r(fd: c_int, buf: *mut c_char, buflen: size_t) -> c_int {
let mut pty = 0;
let err = platform::ERRNO.get();
if ioctl(fd, TIOCGPTN, &mut pty as *mut _ as *mut c_void) == 0 {
if unsafe { ioctl(fd, TIOCGPTN, &mut pty as *mut _ as *mut c_void) } == 0 {
let name = format!("/dev/pts/{}", pty);
let len = name.len();
if len > buflen {
@@ -985,7 +999,7 @@ unsafe fn __ptsname_r(fd: c_int, buf: *mut c_char, buflen: size_t) -> c_int {
// we have checked the string will fit in the buffer
// so can use strcpy safely
let s = name.as_ptr().cast();
ptr::copy_nonoverlapping(s, buf, len);
unsafe { ptr::copy_nonoverlapping(s, buf, len) };
platform::ERRNO.set(err);
0
}
@@ -997,23 +1011,23 @@ unsafe fn __ptsname_r(fd: c_int, buf: *mut c_char, buflen: size_t) -> c_int {
unsafe fn put_new_env(insert: *mut c_char) {
// XXX: Another problem is that `environ` can be set to any pointer, which means there is a
// chance of a memory leak. But we can check if it was the same as before, like musl does.
if platform::environ == platform::OUR_ENVIRON.unsafe_mut().as_mut_ptr() {
if unsafe { platform::environ } == unsafe { platform::OUR_ENVIRON.unsafe_mut().as_mut_ptr() } {
{
let mut our_environ = &mut *platform::OUR_ENVIRON.as_mut_ptr();
let mut our_environ = unsafe { &mut *platform::OUR_ENVIRON.as_mut_ptr() };
*our_environ.last_mut().unwrap() = insert;
our_environ.push(core::ptr::null_mut());
}
// Likely a no-op but is needed due to Stacked Borrows.
platform::environ = platform::OUR_ENVIRON.unsafe_mut().as_mut_ptr();
unsafe { platform::environ = platform::OUR_ENVIRON.unsafe_mut().as_mut_ptr() };
} else {
{
let mut our_environ = &mut *platform::OUR_ENVIRON.as_mut_ptr();
let mut our_environ = unsafe { &mut *platform::OUR_ENVIRON.as_mut_ptr() };
our_environ.clear();
our_environ.extend(platform::environ_iter());
our_environ.push(insert);
our_environ.push(core::ptr::null_mut());
}
platform::environ = platform::OUR_ENVIRON.unsafe_mut().as_mut_ptr();
unsafe { platform::environ = platform::OUR_ENVIRON.unsafe_mut().as_mut_ptr() };
}
}
@@ -1021,13 +1035,13 @@ unsafe fn put_new_env(insert: *mut c_char) {
#[unsafe(no_mangle)]
pub unsafe extern "C" fn putenv(insert: *mut c_char) -> c_int {
assert_ne!(insert, ptr::null_mut(), "putenv(NULL)");
if let Some((i, _)) = find_env(insert) {
if let Some((i, _)) = unsafe { find_env(insert) } {
// XXX: The POSIX manual states that environment variables can be *set* via the `environ`
// global variable. While we can check if a pointer belongs to our allocator, or check
// `environ` against a vector which we control, it is likely not worth the effort.
platform::environ.add(i).write(insert);
unsafe { platform::environ.add(i).write(insert) };
} else {
put_new_env(insert);
unsafe { put_new_env(insert) };
}
0
}
@@ -1045,7 +1059,7 @@ pub unsafe extern "C" fn qsort(
if nel > 0 {
// XXX: maybe try to do mergesort/timsort first and fallback to introsort if memory
// allocation fails? not sure what is ideal
sort::introsort(base as *mut c_char, nel, width, comp);
unsafe { sort::introsort(base as *mut c_char, nel, width, comp) };
}
}
}
@@ -1065,8 +1079,8 @@ pub unsafe extern "C" fn qsort_r(
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/quick_exit.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn quick_exit(status: c_int) -> ! {
for i in (0..AT_QUICK_EXIT_FUNCS.unsafe_ref().len()).rev() {
if let Some(func) = AT_QUICK_EXIT_FUNCS.unsafe_ref()[i] {
for i in (0..unsafe { AT_QUICK_EXIT_FUNCS.unsafe_ref() }.len()).rev() {
if let Some(func) = unsafe { AT_QUICK_EXIT_FUNCS.unsafe_ref() }[i] {
(func)();
}
}
@@ -1077,13 +1091,15 @@ pub unsafe extern "C" fn quick_exit(status: c_int) -> ! {
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/rand.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn rand() -> c_int {
match RNG {
Some(ref mut rng) => rng_sampler().sample(rng),
None => {
let mut rng = XorShiftRng::from_seed([1; 16]);
let ret = rng_sampler().sample(&mut rng);
RNG = Some(rng);
ret
unsafe {
match RNG {
Some(ref mut rng) => rng_sampler().sample(rng),
None => {
let mut rng = XorShiftRng::from_seed([1; 16]);
let ret = rng_sampler().sample(&mut rng);
unsafe { RNG = Some(rng) };
ret
}
}
}
}
@@ -1099,12 +1115,12 @@ pub unsafe extern "C" fn rand_r(seed: *mut c_uint) -> c_int {
errno::EINVAL
} else {
// set the type explicitly so this will fail if the array size for XorShiftRng changes
let seed_arr: [u8; 16] = mem::transmute([*seed; 16 / mem::size_of::<c_uint>()]);
let seed_arr: [u8; 16] = unsafe { mem::transmute([*seed; 16 / mem::size_of::<c_uint>()]) };
let mut rng = XorShiftRng::from_seed(seed_arr);
let ret = rng_sampler().sample(&mut rng);
*seed = ret as _;
unsafe { *seed = ret as _ };
ret
}
@@ -1118,19 +1134,21 @@ pub unsafe extern "C" fn random() -> c_long {
let k: u32;
random_state.ensure_x_ptr_init();
unsafe { random_state.ensure_x_ptr_init() };
if random_state.n == 0 {
let x_old = u32::from_ne_bytes(*random_state.x_ptr);
let x_old = u32::from_ne_bytes(unsafe { *random_state.x_ptr });
let x_new = random::lcg31_step(x_old);
*random_state.x_ptr = x_new.to_ne_bytes();
unsafe { *random_state.x_ptr = x_new.to_ne_bytes() };
k = x_new;
} else {
// The non-u32-aligned way of saying x[i] += x[j]...
let x_i_old = u32::from_ne_bytes(*random_state.x_ptr.add(usize::from(random_state.i)));
let x_j = u32::from_ne_bytes(*random_state.x_ptr.add(usize::from(random_state.j)));
let x_i_old =
u32::from_ne_bytes(unsafe { *random_state.x_ptr.add(usize::from(random_state.i)) });
let x_j =
u32::from_ne_bytes(unsafe { *random_state.x_ptr.add(usize::from(random_state.j)) });
let x_i_new = x_i_old.wrapping_add(x_j);
*random_state.x_ptr.add(usize::from(random_state.i)) = x_i_new.to_ne_bytes();
unsafe { *random_state.x_ptr.add(usize::from(random_state.i)) = x_i_new.to_ne_bytes() };
k = x_i_new >> 1;
@@ -1153,7 +1171,7 @@ pub unsafe extern "C" fn random() -> c_long {
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/realloc.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn realloc(ptr: *mut c_void, size: size_t) -> *mut c_void {
let new_ptr = platform::realloc(ptr, size);
let new_ptr = unsafe { platform::realloc(ptr, size) };
if new_ptr.is_null() {
platform::ERRNO.set(ENOMEM);
}
@@ -1165,7 +1183,7 @@ pub unsafe extern "C" fn realloc(ptr: *mut c_void, size: size_t) -> *mut c_void
pub unsafe extern "C" fn reallocarray(ptr: *mut c_void, m: size_t, n: size_t) -> *mut c_void {
//Handle possible integer overflow in size calculation
match m.checked_mul(n) {
Some(size) => realloc(ptr, size),
Some(size) => unsafe { realloc(ptr, size) },
None => {
// For overflowing multiplication, we have to set errno here
platform::ERRNO.set(ENOMEM);
@@ -1178,14 +1196,14 @@ pub unsafe extern "C" fn reallocarray(ptr: *mut c_void, m: size_t, n: size_t) ->
#[unsafe(no_mangle)]
pub unsafe extern "C" fn realpath(pathname: *const c_char, resolved: *mut c_char) -> *mut c_char {
let ptr = if resolved.is_null() {
malloc(limits::PATH_MAX) as *mut c_char
(unsafe { malloc(limits::PATH_MAX) }) as *mut c_char
} else {
resolved
};
let out = slice::from_raw_parts_mut(ptr as *mut u8, limits::PATH_MAX);
let out = unsafe { slice::from_raw_parts_mut(ptr as *mut u8, limits::PATH_MAX) };
{
let file = match File::open(CStr::from_ptr(pathname), O_PATH | O_CLOEXEC) {
let file = match File::open(unsafe { CStr::from_ptr(pathname) }, O_PATH | O_CLOEXEC) {
Ok(file) => file,
Err(_) => return ptr::null_mut(),
};
@@ -1228,9 +1246,11 @@ pub unsafe extern "C" fn seed48(seed16v: *mut c_ushort) -> *mut c_ushort {
let mut params = rand48::params_mut();
let mut xsubi = rand48::xsubi_lock();
let seed16v_ref: &[c_ushort; 3] = slice::from_raw_parts(seed16v, 3).try_into().unwrap();
let seed16v_ref: &[c_ushort; 3] = unsafe { slice::from_raw_parts(seed16v, 3) }
.try_into()
.unwrap();
BUFFER = (*xsubi).into();
unsafe { BUFFER = (*xsubi).into() };
*xsubi = seed16v_ref.into();
params.reset();
&raw mut BUFFER as *mut _
@@ -1243,10 +1263,10 @@ unsafe fn copy_kv(
key_len: usize,
value_len: usize,
) {
core::ptr::copy_nonoverlapping(key, existing, key_len);
core::ptr::write(existing.add(key_len), b'=' as c_char);
core::ptr::copy_nonoverlapping(value, existing.add(key_len + 1), value_len);
core::ptr::write(existing.add(key_len + 1 + value_len), 0);
unsafe { core::ptr::copy_nonoverlapping(key, existing, key_len) };
unsafe { core::ptr::write(existing.add(key_len), b'=' as c_char) };
unsafe { core::ptr::copy_nonoverlapping(value, existing.add(key_len + 1), value_len) };
unsafe { core::ptr::write(existing.add(key_len + 1 + value_len), 0) };
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/setenv.html>.
@@ -1256,32 +1276,34 @@ pub unsafe extern "C" fn setenv(
value: *const c_char,
overwrite: c_int,
) -> c_int {
let key_len = strlen(key);
let value_len = strlen(value);
let key_len = unsafe { strlen(key) };
let value_len = unsafe { strlen(value) };
if let Some((i, existing)) = find_env(key) {
if let Some((i, existing)) = unsafe { find_env(key) } {
if overwrite == 0 {
return 0;
}
let existing_len = strlen(existing);
let existing_len = unsafe { strlen(existing) };
if existing_len >= value_len {
// Reuse existing element's allocation
core::ptr::copy_nonoverlapping(value, existing, value_len);
unsafe { core::ptr::copy_nonoverlapping(value, existing, value_len) };
//TODO: fill to end with zeroes
core::ptr::write(existing.add(value_len), 0);
unsafe { core::ptr::write(existing.add(value_len), 0) };
} else {
// Reuse platform::environ slot, but allocate a new pointer.
let ptr = platform::alloc(key_len as usize + 1 + value_len as usize + 1) as *mut c_char;
copy_kv(ptr, key, value, key_len, value_len);
platform::environ.add(i).write(ptr);
let ptr = unsafe { platform::alloc(key_len as usize + 1 + value_len as usize + 1) }
as *mut c_char;
unsafe { copy_kv(ptr, key, value, key_len, value_len) };
unsafe { platform::environ.add(i).write(ptr) };
}
} else {
// Expand platform::environ and allocate a new pointer.
let ptr = platform::alloc(key_len as usize + 1 + value_len as usize + 1) as *mut c_char;
copy_kv(ptr, key, value, key_len, value_len);
put_new_env(ptr);
let ptr = unsafe { platform::alloc(key_len as usize + 1 + value_len as usize + 1) }
as *mut c_char;
unsafe { copy_kv(ptr, key, value, key_len, value_len) };
unsafe { put_new_env(ptr) };
}
//platform::free(platform::inner_environ[index] as *mut c_void);
@@ -1306,8 +1328,8 @@ pub unsafe extern "C" fn setkey(key: *const c_char) {
pub unsafe extern "C" fn setstate(state: *mut c_char) -> *mut c_char {
let mut random_state = random::state_lock();
let old_state = random_state.save();
random_state.load(state.cast::<_>());
let old_state = unsafe { random_state.save() };
unsafe { random_state.load(state.cast::<_>()) };
old_state.cast::<_>()
}
@@ -1315,7 +1337,7 @@ pub unsafe extern "C" fn setstate(state: *mut c_char) -> *mut c_char {
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/rand.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn srand(seed: c_uint) {
RNG = Some(XorShiftRng::from_seed([seed as u8; 16]));
unsafe { RNG = Some(XorShiftRng::from_seed([seed as u8; 16])) };
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/drand48.html>.
@@ -1343,7 +1365,7 @@ pub extern "C" fn srand48(seedval: c_long) {
pub unsafe extern "C" fn srandom(seed: c_uint) {
let mut random_state = random::state_lock();
random_state.seed(seed);
unsafe { random_state.seed(seed) };
}
pub fn is_positive(ch: c_char) -> Option<(bool, isize)> {
@@ -1356,11 +1378,11 @@ pub fn is_positive(ch: c_char) -> Option<(bool, isize)> {
}
pub unsafe fn detect_base(s: *const c_char) -> Option<(c_int, isize)> {
let first = *s as u8;
let first = unsafe { *s } as u8;
match first {
0 => None,
b'0' => {
let second = *s.offset(1) as u8;
let second = unsafe { *s.offset(1) } as u8;
if second == b'X' || second == b'x' {
Some((16, 2))
} else if second >= b'0' && second <= b'7' {
@@ -1375,8 +1397,8 @@ pub unsafe fn detect_base(s: *const c_char) -> Option<(c_int, isize)> {
}
pub unsafe fn convert_octal(s: *const c_char) -> Option<(c_ulong, isize, bool)> {
if *s != 0 && *s == b'0' as c_char {
if let Some((val, idx, overflow)) = convert_integer(s.offset(1), 8) {
if unsafe { *s } != 0 && unsafe { *s } == b'0' as c_char {
if let Some((val, idx, overflow)) = unsafe { convert_integer(s.offset(1), 8) } {
Some((val, idx + 1, overflow))
} else {
// in case the prefix is not actually a prefix
@@ -1388,12 +1410,15 @@ pub unsafe fn convert_octal(s: *const c_char) -> Option<(c_ulong, isize, bool)>
}
pub unsafe fn convert_hex(s: *const c_char) -> Option<(c_ulong, isize, bool)> {
if (*s != 0 && *s == b'0' as c_char)
&& (*s.offset(1) != 0 && (*s.offset(1) == b'x' as c_char || *s.offset(1) == b'X' as c_char))
if (unsafe { *s } != 0 && unsafe { *s } == b'0' as c_char)
&& (unsafe { *s.offset(1) } != 0
&& (unsafe { *s.offset(1) } == b'x' as c_char
|| unsafe { *s.offset(1) } == b'X' as c_char))
{
convert_integer(s.offset(2), 16).map(|(val, idx, overflow)| (val, idx + 2, overflow))
unsafe { convert_integer(s.offset(2), 16) }
.map(|(val, idx, overflow)| (val, idx + 2, overflow))
} else {
convert_integer(s, 16).map(|(val, idx, overflow)| (val, idx, overflow))
unsafe { convert_integer(s, 16) }.map(|(val, idx, overflow)| (val, idx, overflow))
}
}
@@ -1427,7 +1452,7 @@ pub unsafe fn convert_integer(s: *const c_char, base: c_int) -> Option<(c_ulong,
// `-1 as usize` is usize::MAX
// `-1 as u8 as usize` is u8::MAX
// It extends by the sign bit unless we cast it to unsigned first.
let val = LOOKUP_TABLE[*s.offset(idx) as u8 as usize];
let val = LOOKUP_TABLE[unsafe { *s.offset(idx) } as u8 as usize];
if val == -1 || val as c_int >= base {
break;
} else {
@@ -1543,7 +1568,7 @@ pub unsafe extern "C" fn system(command: *const c_char) -> c_int {
// handle shell detection on command == NULL
if command.is_null() {
let status = system("exit 0\0".as_ptr() as *const c_char);
let status = unsafe { system("exit 0\0".as_ptr() as *const c_char) };
if status == 0 {
return 1;
} else {
@@ -1551,7 +1576,7 @@ pub unsafe extern "C" fn system(command: *const c_char) -> c_int {
}
}
let child_pid = unistd::fork();
let child_pid = unsafe { unistd::fork() };
if child_pid == 0 {
let command_nonnull = command as *const u8;
@@ -1564,9 +1589,9 @@ pub unsafe extern "C" fn system(command: *const c_char) -> c_int {
ptr::null(),
];
unistd::execv(shell as *const c_char, args.as_ptr() as *const *mut c_char);
unsafe { unistd::execv(shell as *const c_char, args.as_ptr() as *const *mut c_char) };
exit(127);
unsafe { exit(127) };
unreachable!();
} else if child_pid > 0 {
@@ -1597,26 +1622,28 @@ pub extern "C" fn ttyslot() -> c_int {
#[unsafe(no_mangle)]
pub unsafe extern "C" fn unlockpt(fildes: c_int) -> c_int {
let mut u: c_int = 0;
ioctl(fildes, TIOCSPTLCK, &mut u as *mut i32 as *mut c_void)
unsafe { ioctl(fildes, TIOCSPTLCK, &mut u as *mut i32 as *mut c_void) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/unsetenv.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn unsetenv(key: *const c_char) -> c_int {
if let Some((i, _)) = find_env(key) {
if platform::environ == platform::OUR_ENVIRON.unsafe_mut().as_mut_ptr() {
if let Some((i, _)) = unsafe { find_env(key) } {
if unsafe { platform::environ }
== unsafe { platform::OUR_ENVIRON.unsafe_mut().as_mut_ptr() }
{
// No need to worry about updating the pointer, this does not
// reallocate in any way. And the final null is already shifted back.
{
let mut our_environ = &mut *platform::OUR_ENVIRON.as_mut_ptr();
let mut our_environ = unsafe { &mut *platform::OUR_ENVIRON.as_mut_ptr() };
our_environ.remove(i);
}
// My UB paranoia.
platform::environ = platform::OUR_ENVIRON.unsafe_mut().as_mut_ptr();
unsafe { platform::environ = platform::OUR_ENVIRON.unsafe_mut().as_mut_ptr() };
} else {
{
let mut our_environ = &mut *platform::OUR_ENVIRON.as_mut_ptr();
let mut our_environ = unsafe { &mut *platform::OUR_ENVIRON.as_mut_ptr() };
our_environ.clear();
our_environ.extend(
platform::environ_iter()
@@ -1626,7 +1653,7 @@ pub unsafe extern "C" fn unsetenv(key: *const c_char) -> c_int {
);
our_environ.push(core::ptr::null_mut());
}
platform::environ = platform::OUR_ENVIRON.unsafe_mut().as_mut_ptr();
unsafe { platform::environ = platform::OUR_ENVIRON.unsafe_mut().as_mut_ptr() };
}
}
0
@@ -1642,11 +1669,11 @@ pub unsafe extern "C" fn unsetenv(key: *const c_char) -> c_int {
pub unsafe extern "C" fn valloc(size: size_t) -> *mut c_void {
/* sysconf(_SC_PAGESIZE) is a c_long and may in principle not
* convert correctly to a size_t. */
match size_t::try_from(sysconf(_SC_PAGESIZE)) {
match size_t::try_from(unsafe { sysconf(_SC_PAGESIZE) }) {
Ok(page_size) => {
/* valloc() is not supposed to be able to set errno to
* EINVAL, hence no call to memalign(). */
let ptr = platform::alloc_align(size, page_size);
let ptr = unsafe { platform::alloc_align(size, page_size) };
if ptr.is_null() {
platform::ERRNO.set(ENOMEM);
}
@@ -1663,14 +1690,14 @@ pub unsafe extern "C" fn valloc(size: size_t) -> *mut c_void {
#[unsafe(no_mangle)]
pub unsafe extern "C" fn wcstombs(s: *mut c_char, mut pwcs: *const wchar_t, n: size_t) -> size_t {
let mut state: mbstate_t = mbstate_t {};
wcsrtombs(s, &mut pwcs, n, &mut state)
unsafe { wcsrtombs(s, &mut pwcs, n, &mut state) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/wctomb.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn wctomb(s: *mut c_char, wc: wchar_t) -> c_int {
let mut state: mbstate_t = mbstate_t {};
let result: usize = wcrtomb(s, wc, &mut state);
let result: usize = unsafe { wcrtomb(s, wc, &mut state) };
if result == -1isize as usize {
return -1;
+13 -10
View File
@@ -1,6 +1,9 @@
//! Helper functions for random() and friends, see https://pubs.opengroup.org/onlinepubs/7908799/xsh/initstate.html
// Ported from musl's implementation (src/prng/random.c)
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use crate::{
platform::types::*,
sync::{Mutex, MutexGuard},
@@ -34,23 +37,23 @@ impl State {
/// To be called in any function that may read from X_PTR
pub unsafe fn ensure_x_ptr_init(&mut self) {
if self.x_ptr.is_null() {
let x_u32_ptr: *mut u32 = DEFAULT_X.get().cast::<u32>().add(1);
let x_u32_ptr: *mut u32 = unsafe { DEFAULT_X.get().cast::<u32>().add(1) };
self.x_ptr = x_u32_ptr.cast::<[u8; 4]>();
}
}
pub unsafe fn save(&mut self) -> *mut [u8; 4] {
self.ensure_x_ptr_init();
unsafe { self.ensure_x_ptr_init() };
let stash_value: u32 =
(u32::from(self.n) << 16) | (u32::from(self.i) << 8) | u32::from(self.j);
*self.x_ptr.offset(-1) = stash_value.to_ne_bytes();
self.x_ptr.offset(-1)
unsafe { *self.x_ptr.offset(-1) = stash_value.to_ne_bytes() };
unsafe { self.x_ptr.offset(-1) }
}
pub unsafe fn load(&mut self, state_ptr: *mut [u8; 4]) {
let stash_value = u32::from_ne_bytes(*state_ptr);
self.x_ptr = state_ptr.offset(1);
let stash_value = u32::from_ne_bytes(unsafe { *state_ptr });
self.x_ptr = unsafe { state_ptr.offset(1) };
/* This calculation of n does not have a bit mask in the musl
* original, in principle resulting in a u16, but obtaining a value
@@ -63,12 +66,12 @@ impl State {
}
pub unsafe fn seed(&mut self, seed: c_uint) {
self.ensure_x_ptr_init();
unsafe { self.ensure_x_ptr_init() };
let mut s = seed as u64;
if self.n == 0 {
*self.x_ptr = (s as u32).to_ne_bytes();
unsafe { *self.x_ptr = (s as u32).to_ne_bytes() };
} else {
self.i = if self.n == 31 || self.n == 7 { 3 } else { 1 };
@@ -79,11 +82,11 @@ impl State {
// Conversion will always succeed (value is a 32-bit right-
// shift of a 64-bit integer).
*self.x_ptr.add(k) = u32::try_from(s >> 32).unwrap().to_ne_bytes();
unsafe { *self.x_ptr.add(k) = u32::try_from(s >> 32).unwrap().to_ne_bytes() };
}
// ensure X contains at least one odd number
*self.x_ptr = (u32::from_ne_bytes(*self.x_ptr) | 1).to_ne_bytes();
unsafe { *self.x_ptr = (u32::from_ne_bytes(*self.x_ptr) | 1).to_ne_bytes() };
}
}
}
+21 -18
View File
@@ -1,3 +1,6 @@
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use crate::platform::types::*;
pub unsafe fn introsort(
@@ -10,7 +13,7 @@ pub unsafe fn introsort(
let maxdepth = 2 * log2(nel);
introsort_helper(base, nel, width, maxdepth, comp);
*/
insertion_sort(base, nel, width, comp);
unsafe { insertion_sort(base, nel, width, comp) };
}
// NOTE: if num is 0, the result should be considered undefined
@@ -41,23 +44,23 @@ unsafe fn introsort_helper(
// to introsort_helper()
loop {
if nel < THRESHOLD {
insertion_sort(base, nel, width, comp);
unsafe { insertion_sort(base, nel, width, comp) };
break;
} else if nel > 1 {
if maxdepth == 0 {
heapsort(base, nel, width, comp);
unsafe { heapsort(base, nel, width, comp) };
break;
} else {
let (left, right) = partition(base, nel, width, comp);
let (left, right) = unsafe { partition(base, nel, width, comp) };
let right_base = unsafe { base.add((right + 1) * width) };
let right_nel = nel - (right + 1);
maxdepth -= 1;
if left < nel - right {
introsort_helper(base, left, width, maxdepth, comp);
unsafe { introsort_helper(base, left, width, maxdepth, comp) };
base = right_base;
nel = right_nel;
} else {
introsort_helper(right_base, right_nel, width, maxdepth, comp);
unsafe { introsort_helper(right_base, right_nel, width, maxdepth, comp) };
nel = left;
}
}
@@ -76,7 +79,7 @@ unsafe fn insertion_sort(
let current = unsafe { base.add(j * width) };
let prev = unsafe { base.add((j + 1) * width) };
if comp(current as *const c_void, prev as *const c_void) > 0 {
swap(current, prev, width);
unsafe { swap(current, prev, width) };
} else {
break;
}
@@ -90,14 +93,14 @@ unsafe fn heapsort(
width: size_t,
comp: extern "C" fn(*const c_void, *const c_void) -> c_int,
) {
heapify(base, nel, width, comp);
unsafe { heapify(base, nel, width, comp) };
let mut end = nel - 1;
while end > 0 {
let end_ptr = unsafe { base.add(end * width) };
swap(end_ptr, base, width);
unsafe { swap(end_ptr, base, width) };
end -= 1;
heap_sift_down(base, 0, end, width, comp);
unsafe { heap_sift_down(base, 0, end, width, comp) };
}
}
@@ -111,7 +114,7 @@ unsafe fn heapify(
let last_parent = (nel - 2) / 2;
for start in (0..=last_parent).rev() {
heap_sift_down(base, start, nel - 1, width, comp);
unsafe { heap_sift_down(base, start, nel - 1, width, comp) };
}
}
@@ -148,7 +151,7 @@ unsafe fn heap_sift_down(
if swap_idx == root {
break;
} else {
swap(root_ptr, swap_ptr, width);
unsafe { swap(root_ptr, swap_ptr, width) };
root = swap_idx;
}
}
@@ -163,7 +166,7 @@ unsafe fn partition(
) -> (size_t, size_t) {
// calculate the median of the first, middle, and last elements and use it as the pivot
// to do fewer comparisons, also swap the elements into their correct positions
let mut pivot = median_of_three(base, nel, width, comp);
let mut pivot = unsafe { median_of_three(base, nel, width, comp) };
let mut i = 1;
let mut j = 1;
@@ -178,14 +181,14 @@ unsafe fn partition(
let comparison = comp(j_ptr as *const c_void, pivot_ptr as *const c_void);
if comparison < 0 {
swap(i_ptr, j_ptr, width);
unsafe { swap(i_ptr, j_ptr, width) };
if i == pivot {
pivot = j;
}
i += 1;
j += 1;
} else if comparison > 0 {
swap(j_ptr, n_ptr, width);
unsafe { swap(j_ptr, n_ptr, width) };
if n == pivot {
pivot = j;
}
@@ -209,12 +212,12 @@ unsafe fn median_of_three(
let mid = unsafe { base.add(pivot * width) };
let last = unsafe { base.add((nel - 1) * width) };
if comp(mid as *const c_void, base as *const c_void) < 0 {
swap(mid, base, width);
unsafe { swap(mid, base, width) };
}
if comp(last as *const c_void, mid as *const c_void) < 0 {
swap(mid, last, width);
unsafe { swap(mid, last, width) };
if comp(mid as *const c_void, base as *const c_void) < 0 {
swap(mid, base, width);
unsafe { swap(mid, base, width) };
}
}
+6 -3
View File
@@ -1,5 +1,8 @@
//! sys/epoll.h implementation for Redox, following http://man7.org/linux/man-pages/man7/epoll.7.html
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use core::ptr;
use crate::{
@@ -80,7 +83,7 @@ pub unsafe extern "C" fn epoll_ctl(
event: *mut epoll_event,
) -> c_int {
trace_expr!(
Sys::epoll_ctl(epfd, op, fd, event)
unsafe { Sys::epoll_ctl(epfd, op, fd, event) }
.map(|()| 0)
.or_minus_one_errno(),
"epoll_ctl({}, {}, {}, {:p})",
@@ -98,7 +101,7 @@ pub unsafe extern "C" fn epoll_wait(
maxevents: c_int,
timeout: c_int,
) -> c_int {
epoll_pwait(epfd, events, maxevents, timeout, ptr::null())
unsafe { epoll_pwait(epfd, events, maxevents, timeout, ptr::null()) }
}
#[unsafe(no_mangle)]
@@ -110,7 +113,7 @@ pub unsafe extern "C" fn epoll_pwait(
sigmask: *const sigset_t,
) -> c_int {
trace_expr!(
Sys::epoll_pwait(epfd, events, maxevents, timeout, sigmask)
unsafe { Sys::epoll_pwait(epfd, events, maxevents, timeout, sigmask) }
.map(|e| e as c_int)
.or_minus_one_errno(),
"epoll_pwait({}, {:p}, {}, {}, {:p})",
+4 -1
View File
@@ -1,3 +1,6 @@
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use crate::{
error::ResultExt,
platform::{Sys, types::*},
@@ -6,7 +9,7 @@ use crate::{
#[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??
Sys::ioctl(fd, request, out).or_minus_one_errno()
unsafe { Sys::ioctl(fd, request, out).or_minus_one_errno() }
}
pub const TCGETS: c_ulong = 0x5401;
+30 -17
View File
@@ -2,6 +2,9 @@
//!
//! See <https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/sys_mman.h.html>.
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use crate::{
c_str::{CStr, CString},
error::{Errno, ResultExt},
@@ -54,7 +57,7 @@ pub const POSIX_MADV_WONTNEED: c_int = 4;
/// Non-POSIX, see <https://www.man7.org/linux/man-pages/man2/madvise.2.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn madvise(addr: *mut c_void, len: size_t, flags: c_int) -> c_int {
Sys::madvise(addr, len, flags)
unsafe { Sys::madvise(addr, len, flags) }
.map(|()| 0)
.or_minus_one_errno()
}
@@ -62,13 +65,17 @@ pub unsafe extern "C" fn madvise(addr: *mut c_void, len: size_t, flags: c_int) -
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/mlock.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn mlock(addr: *const c_void, len: usize) -> c_int {
Sys::mlock(addr, len).map(|()| 0).or_minus_one_errno()
unsafe { Sys::mlock(addr, len) }
.map(|()| 0)
.or_minus_one_errno()
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/mlockall.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn mlockall(flags: c_int) -> c_int {
Sys::mlockall(flags).map(|()| 0).or_minus_one_errno()
unsafe { Sys::mlockall(flags) }
.map(|()| 0)
.or_minus_one_errno()
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/mmap.html>.
@@ -81,7 +88,7 @@ pub unsafe extern "C" fn mmap(
fildes: c_int,
off: off_t,
) -> *mut c_void {
match Sys::mmap(addr, len, prot, flags, fildes, off) {
match unsafe { Sys::mmap(addr, len, prot, flags, fildes, off) } {
Ok(ptr) => ptr,
Err(Errno(errno)) => {
ERRNO.set(errno);
@@ -93,7 +100,7 @@ pub unsafe extern "C" fn mmap(
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/mprotect.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn mprotect(addr: *mut c_void, len: size_t, prot: c_int) -> c_int {
Sys::mprotect(addr, len, prot)
unsafe { Sys::mprotect(addr, len, prot) }
.map(|()| 0)
.or_minus_one_errno()
}
@@ -107,8 +114,8 @@ pub unsafe extern "C" fn mremap(
flags: c_int,
mut __valist: ...
) -> *mut c_void {
let new_address = __valist.arg::<*mut c_void>();
match Sys::mremap(old_address, old_size, new_size, flags, new_address) {
let new_address = unsafe { __valist.arg::<*mut c_void>() };
match unsafe { Sys::mremap(old_address, old_size, new_size, flags, new_address) } {
Ok(ptr) => ptr,
Err(Errno(errno)) => {
ERRNO.set(errno);
@@ -120,7 +127,7 @@ pub unsafe extern "C" fn mremap(
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/msync.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn msync(addr: *mut c_void, len: size_t, flags: c_int) -> c_int {
Sys::msync(addr, len, flags)
unsafe { Sys::msync(addr, len, flags) }
.map(|()| 0)
.or_minus_one_errno()
}
@@ -128,19 +135,25 @@ pub unsafe extern "C" fn msync(addr: *mut c_void, len: size_t, flags: c_int) ->
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/mlock.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn munlock(addr: *const c_void, len: usize) -> c_int {
Sys::munlock(addr, len).map(|()| 0).or_minus_one_errno()
unsafe { Sys::munlock(addr, len) }
.map(|()| 0)
.or_minus_one_errno()
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/mlockall.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn munlockall() -> c_int {
Sys::munlockall().map(|()| 0).or_minus_one_errno()
unsafe { Sys::munlockall() }
.map(|()| 0)
.or_minus_one_errno()
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/munmap.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn munmap(addr: *mut c_void, len: size_t) -> c_int {
Sys::munmap(addr, len).map(|()| 0).or_minus_one_errno()
unsafe { Sys::munmap(addr, len) }
.map(|()| 0)
.or_minus_one_errno()
}
#[cfg(target_os = "linux")]
@@ -150,7 +163,7 @@ static SHM_PATH: &'static [u8] = b"/dev/shm/";
static SHM_PATH: &'static [u8] = b"/scheme/shm/";
unsafe fn shm_path(name: *const c_char) -> CString {
let name_c = CStr::from_ptr(name);
let name_c = unsafe { CStr::from_ptr(name) };
let mut path = SHM_PATH.to_vec();
@@ -166,19 +179,19 @@ unsafe fn shm_path(name: *const c_char) -> CString {
path.push(b);
}
CString::from_vec_unchecked(path)
unsafe { CString::from_vec_unchecked(path) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/shm_open.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn shm_open(name: *const c_char, oflag: c_int, mode: mode_t) -> c_int {
let path = shm_path(name);
fcntl::open(path.as_ptr(), oflag, mode)
let path = unsafe { shm_path(name) };
unsafe { fcntl::open(path.as_ptr(), oflag, mode) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/shm_unlink.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn shm_unlink(name: *const c_char) -> c_int {
let path = shm_path(name);
unistd::unlink(path.as_ptr())
let path = unsafe { shm_path(name) };
unsafe { unistd::unlink(path.as_ptr()) }
}
+5 -1
View File
@@ -1,5 +1,8 @@
//! ptrace compatibility layer for Redox OS
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use crate::{
error::ResultExt,
platform::{PalPtrace, Sys, types::*},
@@ -28,5 +31,6 @@ pub const PTRACE_SYSEMU_SINGLESTEP: c_int = 32;
#[unsafe(no_mangle)]
pub unsafe extern "C" fn ptrace(request: c_int, mut __valist: ...) -> c_int {
// Musl also just grabs the arguments from the varargs...
Sys::ptrace(request, __valist.arg(), __valist.arg(), __valist.arg()).or_minus_one_errno()
unsafe { Sys::ptrace(request, __valist.arg(), __valist.arg(), __valist.arg()) }
.or_minus_one_errno()
}
+4 -1
View File
@@ -2,6 +2,9 @@
//!
//! Non-POSIX, see <https://www.man7.org/linux/man-pages/man2/getrandom.2.html>.
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use core::slice;
use crate::{
@@ -21,7 +24,7 @@ pub const GRND_RANDOM: c_uint = 2;
#[unsafe(no_mangle)]
pub unsafe extern "C" fn getrandom(buf: *mut c_void, buflen: size_t, flags: c_uint) -> ssize_t {
Sys::getrandom(
slice::from_raw_parts_mut(buf as *mut u8, buflen as usize),
unsafe { slice::from_raw_parts_mut(buf as *mut u8, buflen as usize) },
flags,
)
.map(|read| read as ssize_t)
+6 -3
View File
@@ -2,6 +2,9 @@
//!
//! See <https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/sys_resource.h.html>.
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use crate::{
error::ResultExt,
header::sys_time::timeval,
@@ -92,7 +95,7 @@ pub unsafe extern "C" fn setpriority(which: c_int, who: id_t, nice: c_int) -> c_
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/getrlimit.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn getrlimit(resource: c_int, rlp: *mut rlimit) -> c_int {
let rlp = Out::nonnull(rlp);
let rlp = unsafe { Out::nonnull(rlp) };
Sys::getrlimit(resource, rlp)
.map(|()| 0)
@@ -102,7 +105,7 @@ pub unsafe extern "C" fn getrlimit(resource: c_int, rlp: *mut rlimit) -> c_int {
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/setrlimit.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn setrlimit(resource: c_int, rlp: *const rlimit) -> c_int {
Sys::setrlimit(resource, rlp)
unsafe { Sys::setrlimit(resource, rlp) }
.map(|()| 0)
.or_minus_one_errno()
}
@@ -110,7 +113,7 @@ pub unsafe extern "C" fn setrlimit(resource: c_int, rlp: *const rlimit) -> c_int
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/getrusage.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn getrusage(who: c_int, r_usage: *mut rusage) -> c_int {
Sys::getrusage(who, Out::nonnull(r_usage))
Sys::getrusage(who, unsafe { Out::nonnull(r_usage) })
.map(|()| 0)
.or_minus_one_errno()
}
+7 -4
View File
@@ -2,6 +2,9 @@
//!
//! See <https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/sys_select.h.html>.
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use core::mem;
use cbitset::BitSet;
@@ -180,22 +183,22 @@ pub unsafe extern "C" fn select(
if readfds.is_null() {
None
} else {
Some(&mut *readfds)
Some(unsafe { &mut *readfds })
},
if writefds.is_null() {
None
} else {
Some(&mut *writefds)
Some(unsafe { &mut *writefds })
},
if exceptfds.is_null() {
None
} else {
Some(&mut *exceptfds)
Some(unsafe { &mut *exceptfds })
},
if timeout.is_null() {
None
} else {
Some(&mut *timeout)
Some(unsafe { &mut *timeout })
}
),
"select({}, {:p}, {:p}, {:p}, {:p})",
+35 -27
View File
@@ -2,6 +2,9 @@
//!
//! See <https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/sys_socket.h.html>.
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use core::{mem, ptr};
use crate::{
@@ -119,7 +122,7 @@ pub unsafe extern "C" fn CMSG_DATA(cmsg: *const cmsghdr) -> *mut c_uchar {
#[unsafe(no_mangle)]
pub unsafe extern "C" fn CMSG_NXTHDR(mhdr: *const msghdr, cmsg: *const cmsghdr) -> *mut cmsghdr {
if cmsg.is_null() {
return CMSG_FIRSTHDR(mhdr);
return unsafe { CMSG_FIRSTHDR(mhdr) };
};
unsafe {
@@ -155,13 +158,14 @@ pub unsafe extern "C" fn CMSG_ALIGN(len: size_t) -> size_t {
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/sys_socket.h.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn CMSG_SPACE(len: c_uint) -> c_uint {
(CMSG_ALIGN(len as size_t) + CMSG_ALIGN(mem::size_of::<cmsghdr>())) as c_uint
(unsafe { CMSG_ALIGN(len as size_t) } + unsafe { CMSG_ALIGN(mem::size_of::<cmsghdr>()) })
as c_uint
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/sys_socket.h.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn CMSG_LEN(length: c_uint) -> c_uint {
(CMSG_ALIGN(mem::size_of::<cmsghdr>()) + length as usize) as c_uint
(unsafe { CMSG_ALIGN(mem::size_of::<cmsghdr>()) } + length as usize) as c_uint
}
// } These must match C macros in include/bits/sys/socket.h
@@ -173,7 +177,7 @@ pub unsafe extern "C" fn accept(
address_len: *mut socklen_t,
) -> c_int {
trace_expr!(
Sys::accept(socket, address, address_len).or_minus_one_errno(),
unsafe { Sys::accept(socket, address, address_len) }.or_minus_one_errno(),
"accept({}, {:p}, {:p})",
socket,
address,
@@ -189,7 +193,7 @@ pub unsafe extern "C" fn bind(
address_len: socklen_t,
) -> c_int {
trace_expr!(
Sys::bind(socket, address, address_len)
unsafe { Sys::bind(socket, address, address_len) }
.map(|()| 0)
.or_minus_one_errno(),
"bind({}, {:p}, {})",
@@ -207,7 +211,7 @@ pub unsafe extern "C" fn connect(
address_len: socklen_t,
) -> c_int {
trace_expr!(
Sys::connect(socket, address, address_len).or_minus_one_errno(),
unsafe { Sys::connect(socket, address, address_len) }.or_minus_one_errno(),
"connect({}, {:p}, {})",
socket,
address,
@@ -223,7 +227,7 @@ pub unsafe extern "C" fn getpeername(
address_len: *mut socklen_t,
) -> c_int {
trace_expr!(
Sys::getpeername(socket, address, address_len)
unsafe { Sys::getpeername(socket, address, address_len) }
.map(|()| 0)
.or_minus_one_errno(),
"getpeername({}, {:p}, {:p})",
@@ -241,7 +245,7 @@ pub unsafe extern "C" fn getsockname(
address_len: *mut socklen_t,
) -> c_int {
trace_expr!(
Sys::getsockname(socket, address, address_len)
unsafe { Sys::getsockname(socket, address, address_len) }
.map(|()| 0)
.or_minus_one_errno(),
"getsockname({}, {:p}, {:p})",
@@ -261,7 +265,7 @@ pub unsafe extern "C" fn getsockopt(
option_len: *mut socklen_t,
) -> c_int {
trace_expr!(
Sys::getsockopt(socket, level, option_name, option_value, option_len)
unsafe { Sys::getsockopt(socket, level, option_name, option_value, option_len) }
.map(|()| 0)
.or_minus_one_errno(),
"getsockopt({}, {}, {}, {:p}, {:p})",
@@ -289,14 +293,16 @@ pub unsafe extern "C" fn recv(
length: size_t,
flags: c_int,
) -> ssize_t {
recvfrom(
socket,
buffer,
length,
flags,
ptr::null_mut(),
ptr::null_mut(),
)
unsafe {
recvfrom(
socket,
buffer,
length,
flags,
ptr::null_mut(),
ptr::null_mut(),
)
}
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/recvfrom.html>.
@@ -310,7 +316,7 @@ pub unsafe extern "C" fn recvfrom(
address_len: *mut socklen_t,
) -> ssize_t {
trace_expr!(
Sys::recvfrom(socket, buffer, length, flags, address, address_len)
unsafe { Sys::recvfrom(socket, buffer, length, flags, address, address_len) }
.map(|r| r as ssize_t)
.or_minus_one_errno(),
"recvfrom({}, {:p}, {}, {:#x}, {:p}, {:p})",
@@ -326,7 +332,7 @@ pub unsafe extern "C" fn recvfrom(
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/recvmsg.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn recvmsg(socket: c_int, msg: *mut msghdr, flags: c_int) -> ssize_t {
Sys::recvmsg(socket, msg, flags)
unsafe { Sys::recvmsg(socket, msg, flags) }
.map(|r| r as ssize_t)
.or_minus_one_errno()
}
@@ -339,13 +345,13 @@ pub unsafe extern "C" fn send(
length: size_t,
flags: c_int,
) -> ssize_t {
sendto(socket, message, length, flags, ptr::null(), 0)
unsafe { sendto(socket, message, length, flags, ptr::null(), 0) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/sendmsg.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn sendmsg(socket: c_int, msg: *const msghdr, flags: c_int) -> ssize_t {
Sys::sendmsg(socket, msg, flags)
unsafe { Sys::sendmsg(socket, msg, flags) }
.map(|w| w as ssize_t)
.or_minus_one_errno()
}
@@ -361,7 +367,7 @@ pub unsafe extern "C" fn sendto(
dest_len: socklen_t,
) -> ssize_t {
trace_expr!(
Sys::sendto(socket, message, length, flags, dest_addr, dest_len)
unsafe { Sys::sendto(socket, message, length, flags, dest_addr, dest_len) }
.map(|w| w as ssize_t)
.or_minus_one_errno(),
"sendto({}, {:p}, {}, {:#x}, {:p}, {})",
@@ -384,7 +390,7 @@ pub unsafe extern "C" fn setsockopt(
option_len: socklen_t,
) -> c_int {
trace_expr!(
Sys::setsockopt(socket, level, option_name, option_value, option_len)
unsafe { Sys::setsockopt(socket, level, option_name, option_value, option_len) }
.map(|()| 0)
.or_minus_one_errno(),
"setsockopt({}, {}, {}, {:p}, {})",
@@ -406,7 +412,7 @@ pub unsafe extern "C" fn shutdown(socket: c_int, how: c_int) -> c_int {
#[unsafe(no_mangle)]
pub unsafe extern "C" fn socket(domain: c_int, kind: c_int, protocol: c_int) -> c_int {
trace_expr!(
Sys::socket(domain, kind, protocol).or_minus_one_errno(),
unsafe { Sys::socket(domain, kind, protocol) }.or_minus_one_errno(),
"socket({}, {}, {})",
domain,
kind,
@@ -423,9 +429,11 @@ pub unsafe extern "C" fn socketpair(
sv: *mut c_int,
) -> c_int {
trace_expr!(
Sys::socketpair(domain, kind, protocol, &mut *(sv as *mut [c_int; 2]))
.map(|()| 0)
.or_minus_one_errno(),
Sys::socketpair(domain, kind, protocol, unsafe {
&mut *(sv as *mut [c_int; 2])
})
.map(|()| 0)
.or_minus_one_errno(),
"socketpair({}, {}, {}, {:p})",
domain,
kind,
+19 -17
View File
@@ -83,7 +83,7 @@ pub struct stat {
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/chmod.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn chmod(path: *const c_char, mode: mode_t) -> c_int {
let path = CStr::from_ptr(path);
let path = unsafe { CStr::from_ptr(path) };
Sys::chmod(path, mode).map(|()| 0).or_minus_one_errno()
}
@@ -101,7 +101,7 @@ pub unsafe extern "C" fn fchmodat(
mode: mode_t,
flags: c_int,
) -> c_int {
let path = CStr::from_nullable_ptr(path);
let path = unsafe { CStr::from_nullable_ptr(path) };
Sys::fchmodat(dirfd, path, mode, flags)
.map(|()| 0)
.or_minus_one_errno()
@@ -110,7 +110,7 @@ pub unsafe extern "C" fn fchmodat(
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/fstat.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn fstat(fildes: c_int, buf: *mut stat) -> c_int {
let buf = Out::nonnull(buf);
let buf = unsafe { Out::nonnull(buf) };
Sys::fstat(fildes, buf).map(|()| 0).or_minus_one_errno()
}
@@ -122,8 +122,8 @@ pub unsafe extern "C" fn fstatat(
buf: *mut stat,
flags: c_int,
) -> c_int {
let path = CStr::from_nullable_ptr(path);
let buf = Out::nonnull(buf);
let path = unsafe { CStr::from_nullable_ptr(path) };
let buf = unsafe { Out::nonnull(buf) };
Sys::fstatat(fildes, path, buf, flags)
.map(|()| 0)
.or_minus_one_errno()
@@ -131,20 +131,22 @@ pub unsafe extern "C" fn fstatat(
#[unsafe(no_mangle)]
pub unsafe extern "C" fn __fxstat(_ver: c_int, fildes: c_int, buf: *mut stat) -> c_int {
fstat(fildes, buf)
unsafe { fstat(fildes, buf) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/futimens.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn futimens(fd: c_int, times: *const timespec) -> c_int {
Sys::futimens(fd, times).map(|()| 0).or_minus_one_errno()
unsafe { Sys::futimens(fd, times) }
.map(|()| 0)
.or_minus_one_errno()
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/lstat.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn lstat(path: *const c_char, buf: *mut stat) -> c_int {
let path = CStr::from_ptr(path);
let buf = Out::nonnull(buf);
let path = unsafe { CStr::from_ptr(path) };
let buf = unsafe { Out::nonnull(buf) };
// TODO: Rustify
let fd = Sys::open(path, O_PATH | O_NOFOLLOW, 0).or_minus_one_errno();
@@ -163,7 +165,7 @@ pub unsafe extern "C" fn lstat(path: *const c_char, buf: *mut stat) -> c_int {
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/mkdirat.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn mkdirat(dirfd: c_int, path: *const c_char, mode: mode_t) -> c_int {
let path = CStr::from_ptr(path);
let path = unsafe { CStr::from_ptr(path) };
Sys::mkdirat(dirfd, path, mode)
.map(|()| 0)
.or_minus_one_errno()
@@ -172,14 +174,14 @@ pub unsafe extern "C" fn mkdirat(dirfd: c_int, path: *const c_char, mode: mode_t
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/mkdir.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn mkdir(path: *const c_char, mode: mode_t) -> c_int {
let path = CStr::from_ptr(path);
let path = unsafe { CStr::from_ptr(path) };
Sys::mkdir(path, mode).map(|()| 0).or_minus_one_errno()
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/mkfifoat.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn mkfifoat(dirfd: c_int, path: *const c_char, mode: mode_t) -> c_int {
let path = CStr::from_ptr(path);
let path = unsafe { CStr::from_ptr(path) };
Sys::mkfifoat(dirfd, path, mode)
.map(|()| 0)
.or_minus_one_errno()
@@ -188,14 +190,14 @@ pub unsafe extern "C" fn mkfifoat(dirfd: c_int, path: *const c_char, mode: mode_
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/mkfifo.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn mkfifo(path: *const c_char, mode: mode_t) -> c_int {
let path = CStr::from_ptr(path);
let path = unsafe { CStr::from_ptr(path) };
Sys::mkfifo(path, mode).map(|()| 0).or_minus_one_errno()
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/mknod.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn mknod(path: *const c_char, mode: mode_t, dev: dev_t) -> c_int {
let path = CStr::from_ptr(path);
let path = unsafe { CStr::from_ptr(path) };
Sys::mknod(path, mode, dev).map(|()| 0).or_minus_one_errno()
}
@@ -207,7 +209,7 @@ pub unsafe extern "C" fn mknodat(
mode: mode_t,
dev: dev_t,
) -> c_int {
let path = CStr::from_ptr(path);
let path = unsafe { CStr::from_ptr(path) };
Sys::mknodat(dirfd, path, mode, dev)
.map(|()| 0)
.or_minus_one_errno()
@@ -216,8 +218,8 @@ pub unsafe extern "C" fn mknodat(
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/stat.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn stat(file: *const c_char, buf: *mut stat) -> c_int {
let file = CStr::from_ptr(file);
let buf = Out::nonnull(buf);
let file = unsafe { CStr::from_ptr(file) };
let buf = unsafe { Out::nonnull(buf) };
// TODO: Rustify
let fd = Sys::open(file, O_PATH, 0).or_minus_one_errno();
+6 -3
View File
@@ -2,6 +2,9 @@
//!
//! See <https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/sys_statvfs.h.html>.
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use crate::{
c_str::CStr,
error::ResultExt,
@@ -35,15 +38,15 @@ pub struct statvfs {
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/fstatvfs.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn fstatvfs(fildes: c_int, buf: *mut statvfs) -> c_int {
let buf = Out::nonnull(buf);
let buf = unsafe { Out::nonnull(buf) };
Sys::fstatvfs(fildes, buf).map(|()| 0).or_minus_one_errno()
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/fstatvfs.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn statvfs(file: *const c_char, buf: *mut statvfs) -> c_int {
let file = CStr::from_ptr(file);
let buf = Out::nonnull(buf);
let file = unsafe { CStr::from_ptr(file) };
let buf = unsafe { Out::nonnull(buf) };
// TODO: Rustify
let fd = Sys::open(file, O_PATH, 0).or_minus_one_errno();
if fd < 0 {
+5 -2
View File
@@ -4,6 +4,9 @@
// Exported as both syslog.h and sys/syslog.h.
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
#[cfg(target_os = "redox")]
#[path = "redox.rs"]
pub mod sys;
@@ -120,7 +123,7 @@ pub unsafe extern "C" fn openlog(ident: *const c_char, opt: c_int, facility: c_i
/// Non-POSIX, 4.3BSD-Reno.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn vsyslog(priority: c_int, message: *const c_char, mut ap: VaList) {
let Some(message) = CStr::from_nullable_ptr(message) else {
let Some(message) = (unsafe { CStr::from_nullable_ptr(message) }) else {
return;
};
let Some(priority) = Priority::from_bits(priority) else {
@@ -136,7 +139,7 @@ pub unsafe extern "C" fn vsyslog(priority: c_int, message: *const c_char, mut ap
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/closelog.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn syslog(priority: c_int, message: *const c_char, mut __valist: ...) {
vsyslog(priority, message, __valist.as_va_list());
unsafe { vsyslog(priority, message, __valist.as_va_list()) };
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/closelog.html>.
+12 -9
View File
@@ -2,6 +2,9 @@
//!
//! See <https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/sys_time.h.html>.
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use crate::{
c_str::CStr,
error::ResultExt,
@@ -85,7 +88,7 @@ pub struct timezone {
#[deprecated]
#[unsafe(no_mangle)]
pub unsafe extern "C" fn getitimer(which: c_int, value: *mut itimerval) -> c_int {
Sys::getitimer(which, &mut *value)
Sys::getitimer(which, unsafe { &mut *value })
.map(|()| 0)
.or_minus_one_errno()
}
@@ -101,7 +104,7 @@ pub unsafe extern "C" fn getitimer(which: c_int, value: *mut itimerval) -> c_int
#[deprecated]
#[unsafe(no_mangle)]
pub unsafe extern "C" fn gettimeofday(tp: *mut timeval, tzp: *mut timezone) -> c_int {
Sys::gettimeofday(Out::nonnull(tp), Out::nullable(tzp))
Sys::gettimeofday(unsafe { Out::nonnull(tp) }, unsafe { Out::nullable(tzp) })
.map(|()| 0)
.or_minus_one_errno()
}
@@ -121,7 +124,7 @@ pub unsafe extern "C" fn setitimer(
ovalue: *mut itimerval,
) -> c_int {
// TODO setitimer is unimplemented on Redox
Sys::setitimer(which, &*value, ovalue.as_mut())
Sys::setitimer(which, unsafe { &*value }, unsafe { ovalue.as_mut() })
.map(|()| 0)
.or_minus_one_errno()
}
@@ -133,7 +136,7 @@ pub unsafe extern "C" fn setitimer(
/// Specifications Issue 6, and then unmarked in Issue 7.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn utimes(path: *const c_char, times: *const timeval) -> c_int {
let path = CStr::from_ptr(path);
let path = unsafe { CStr::from_ptr(path) };
// Nullptr is valid here, it means "use current time"
let times_spec = if times.is_null() {
null()
@@ -141,18 +144,18 @@ pub unsafe extern "C" fn utimes(path: *const c_char, times: *const timeval) -> c
{
[
timespec {
tv_sec: (*times.offset(0)).tv_sec,
tv_nsec: ((*times.offset(0)).tv_usec as c_long) * 1000,
tv_sec: unsafe { (*times.offset(0)).tv_sec },
tv_nsec: (unsafe { (*times.offset(0)).tv_usec } as c_long) * 1000,
},
timespec {
tv_sec: (*times.offset(1)).tv_sec,
tv_nsec: ((*times.offset(1)).tv_usec as c_long) * 1000,
tv_sec: unsafe { (*times.offset(1)).tv_sec },
tv_nsec: (unsafe { (*times.offset(1)).tv_usec } as c_long) * 1000,
},
]
}
.as_ptr()
};
Sys::utimens(path, times_spec)
unsafe { Sys::utimens(path, times_spec) }
.map(|()| 0)
.or_minus_one_errno()
}
+20 -17
View File
@@ -2,6 +2,9 @@
//!
//! See <https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/sys_uio.h.html>.
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use alloc::vec::Vec;
use core::slice;
@@ -25,14 +28,14 @@ pub struct iovec {
impl iovec {
unsafe fn to_slice(&self) -> &mut [u8] {
slice::from_raw_parts_mut(self.iov_base as *mut u8, self.iov_len as usize)
unsafe { slice::from_raw_parts_mut(self.iov_base as *mut u8, self.iov_len as usize) }
}
}
unsafe fn gather(iovs: &[iovec]) -> Vec<u8> {
let mut vec = Vec::new();
for iov in iovs.iter() {
vec.extend_from_slice(iov.to_slice());
vec.extend_from_slice(unsafe { iov.to_slice() });
}
vec
}
@@ -40,7 +43,7 @@ unsafe fn gather(iovs: &[iovec]) -> Vec<u8> {
unsafe fn scatter(iovs: &[iovec], vec: Vec<u8>) {
let mut i = 0;
for iov in iovs.iter() {
let slice = iov.to_slice();
let slice = unsafe { iov.to_slice() };
slice.copy_from_slice(&vec[i..][..slice.len()]);
i += slice.len();
}
@@ -59,12 +62,12 @@ pub unsafe extern "C" fn preadv(
return -1;
}
let iovs = slice::from_raw_parts(iov, iovcnt as usize);
let mut vec = gather(iovs);
let iovs = unsafe { slice::from_raw_parts(iov, iovcnt as usize) };
let mut vec = unsafe { gather(iovs) };
let ret = unistd::pread(fd, vec.as_mut_ptr() as *mut c_void, vec.len(), offset);
let ret = unsafe { unistd::pread(fd, vec.as_mut_ptr() as *mut c_void, vec.len(), offset) };
scatter(iovs, vec);
unsafe { scatter(iovs, vec) };
ret
}
@@ -82,10 +85,10 @@ pub unsafe extern "C" fn pwritev(
return -1;
}
let iovs = slice::from_raw_parts(iov, iovcnt as usize);
let vec = gather(iovs);
let iovs = unsafe { slice::from_raw_parts(iov, iovcnt as usize) };
let vec = unsafe { gather(iovs) };
unistd::pwrite(fd, vec.as_ptr() as *const c_void, vec.len(), offset)
unsafe { unistd::pwrite(fd, vec.as_ptr() as *const c_void, vec.len(), offset) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/readv.html>.
@@ -96,12 +99,12 @@ pub unsafe extern "C" fn readv(fd: c_int, iov: *const iovec, iovcnt: c_int) -> s
return -1;
}
let iovs = slice::from_raw_parts(iov, iovcnt as usize);
let mut vec = gather(iovs);
let iovs = unsafe { slice::from_raw_parts(iov, iovcnt as usize) };
let mut vec = unsafe { gather(iovs) };
let ret = unistd::read(fd, vec.as_mut_ptr() as *mut c_void, vec.len());
let ret = unsafe { unistd::read(fd, vec.as_mut_ptr() as *mut c_void, vec.len()) };
scatter(iovs, vec);
unsafe { scatter(iovs, vec) };
ret
}
@@ -114,8 +117,8 @@ pub unsafe extern "C" fn writev(fd: c_int, iov: *const iovec, iovcnt: c_int) ->
return -1;
}
let iovs = slice::from_raw_parts(iov, iovcnt as usize);
let vec = gather(iovs);
let iovs = unsafe { slice::from_raw_parts(iov, iovcnt as usize) };
let vec = unsafe { gather(iovs) };
unistd::write(fd, vec.as_ptr() as *const c_void, vec.len())
unsafe { unistd::write(fd, vec.as_ptr() as *const c_void, vec.len()) }
}
+4 -1
View File
@@ -2,6 +2,9 @@
//!
//! See <https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/sys_utsname.h.html>.
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use crate::{
error::ResultExt,
out::Out,
@@ -28,7 +31,7 @@ pub struct utsname {
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/uname.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn uname(uts: *mut utsname) -> c_int {
Sys::uname(Out::nonnull(uts))
Sys::uname(unsafe { Out::nonnull(uts) })
.map(|()| 0)
.or_minus_one_errno()
}
+5 -2
View File
@@ -2,6 +2,9 @@
//!
//! See <https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/sys_wait.h.html>.
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use crate::{
error::ResultExt,
out::Out,
@@ -27,7 +30,7 @@ pub const __WCLONE: c_int = 0x8000_0000;
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/wait.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn wait(stat_loc: *mut c_int) -> pid_t {
waitpid(!0, stat_loc, 0)
unsafe { waitpid(!0, stat_loc, 0) }
}
/*
@@ -47,5 +50,5 @@ pub unsafe extern "C" fn wait(stat_loc: *mut c_int) -> pid_t {
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/waitpid.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn waitpid(pid: pid_t, stat_loc: *mut c_int, options: c_int) -> pid_t {
Sys::waitpid(pid, Out::nullable(stat_loc), options).or_minus_one_errno()
Sys::waitpid(pid, unsafe { Out::nullable(stat_loc) }, options).or_minus_one_errno()
}
+28 -23
View File
@@ -2,6 +2,9 @@
//!
//! See <https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/termios.h.html>.
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use crate::{
header::{
errno,
@@ -71,7 +74,7 @@ pub struct termios {
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/tcgetattr.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn tcgetattr(fd: c_int, out: *mut termios) -> c_int {
sys_ioctl::ioctl(fd, sys_ioctl::TCGETS, out as *mut c_void)
unsafe { sys_ioctl::ioctl(fd, sys_ioctl::TCGETS, out as *mut c_void) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/tcsetattr.html>.
@@ -82,14 +85,14 @@ pub unsafe extern "C" fn tcsetattr(fd: c_int, act: c_int, value: *const termios)
return -1;
}
// This is safe because ioctl shouldn't modify the value
sys_ioctl::ioctl(fd, sys_ioctl::TCSETS + act as c_ulong, value as *mut c_void)
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>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn tcgetsid(fd: c_int) -> pid_t {
let mut sid = 0;
if sys_ioctl::ioctl(fd, sys_ioctl::TIOCGSID, (&raw mut sid) as *mut c_void) < 0 {
if unsafe { sys_ioctl::ioctl(fd, sys_ioctl::TIOCGSID, (&raw mut sid) as *mut c_void) } < 0 {
return -1;
}
sid
@@ -99,7 +102,7 @@ pub unsafe extern "C" fn tcgetsid(fd: c_int) -> pid_t {
#[cfg(target_os = "linux")]
#[unsafe(no_mangle)]
pub unsafe extern "C" fn cfgetispeed(termios_p: *const termios) -> speed_t {
(*termios_p).__c_ispeed
unsafe { (*termios_p).__c_ispeed }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/cfgetispeed.html>.
@@ -114,7 +117,7 @@ pub unsafe extern "C" fn cfgetispeed(termios_p: *const termios) -> speed_t {
#[cfg(target_os = "linux")]
#[unsafe(no_mangle)]
pub unsafe extern "C" fn cfgetospeed(termios_p: *const termios) -> speed_t {
(*termios_p).__c_ospeed
unsafe { (*termios_p).__c_ospeed }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/cfgetospeed.html>.
@@ -131,7 +134,7 @@ pub unsafe extern "C" fn cfgetospeed(termios_p: *const termios) -> speed_t {
pub unsafe extern "C" fn cfsetispeed(termios_p: *mut termios, speed: speed_t) -> c_int {
match speed as usize {
B0..=B38400 | B57600..=B4000000 => {
(*termios_p).__c_ispeed = speed;
unsafe { (*termios_p).__c_ispeed = speed };
0
}
_ => {
@@ -156,7 +159,7 @@ pub unsafe extern "C" fn cfsetispeed(termios_p: *mut termios, speed: speed_t) ->
pub unsafe extern "C" fn cfsetospeed(termios_p: *mut termios, speed: speed_t) -> c_int {
match speed as usize {
B0..=B38400 | B57600..=B4000000 => {
(*termios_p).__c_ospeed = speed;
unsafe { (*termios_p).__c_ospeed = speed };
0
}
_ => {
@@ -180,23 +183,23 @@ pub unsafe extern "C" fn cfsetospeed(termios_p: *mut termios, speed: speed_t) ->
/// See <https://www.man7.org/linux/man-pages/man3/cfsetispeed.3.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn cfsetspeed(termios_p: *mut termios, speed: speed_t) -> c_int {
let r = cfsetispeed(termios_p, speed);
let r = unsafe { cfsetispeed(termios_p, speed) };
if r < 0 {
return r;
}
cfsetospeed(termios_p, speed)
unsafe { cfsetospeed(termios_p, speed) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/tcflush.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn tcflush(fd: c_int, queue: c_int) -> c_int {
sys_ioctl::ioctl(fd, sys_ioctl::TCFLSH, queue as *mut c_void)
unsafe { sys_ioctl::ioctl(fd, sys_ioctl::TCFLSH, queue as *mut c_void) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/tcdrain.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn tcdrain(fd: c_int) -> c_int {
sys_ioctl::ioctl(fd, sys_ioctl::TCSBRK, 1 as *mut _)
unsafe { sys_ioctl::ioctl(fd, sys_ioctl::TCSBRK, 1 as *mut _) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/tcsendbreak.html>.
@@ -204,19 +207,19 @@ pub unsafe extern "C" fn tcdrain(fd: c_int) -> c_int {
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.
sys_ioctl::ioctl(fd, sys_ioctl::TCSBRK, 0 as *mut _)
unsafe { sys_ioctl::ioctl(fd, sys_ioctl::TCSBRK, 0 as *mut _) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/tcgetwinsize.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn tcgetwinsize(fd: c_int, sws: *mut winsize) -> c_int {
sys_ioctl::ioctl(fd, sys_ioctl::TIOCGWINSZ, sws.cast())
unsafe { sys_ioctl::ioctl(fd, sys_ioctl::TIOCGWINSZ, sws.cast()) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/tcsetwinsize.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn tcsetwinsize(fd: c_int, sws: *const winsize) -> c_int {
sys_ioctl::ioctl(fd, sys_ioctl::TIOCSWINSZ, (sws as *mut winsize).cast())
unsafe { sys_ioctl::ioctl(fd, sys_ioctl::TIOCSWINSZ, (sws as *mut winsize).cast()) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/tcflow.html>.
@@ -224,7 +227,7 @@ pub unsafe extern "C" fn tcsetwinsize(fd: c_int, sws: *const winsize) -> c_int {
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.
sys_ioctl::ioctl(fd, sys_ioctl::TCXONC, action as *mut _)
unsafe { sys_ioctl::ioctl(fd, sys_ioctl::TCXONC, action as *mut _) }
}
/// Non-POSIX, BSD extension
@@ -232,12 +235,14 @@ pub unsafe extern "C" fn tcflow(fd: c_int, action: c_int) -> c_int {
/// See <https://www.man7.org/linux/man-pages/man3/cfmakeraw.3.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn cfmakeraw(termios_p: *mut termios) {
(*termios_p).c_iflag &=
!(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON) as u32;
(*termios_p).c_oflag &= !OPOST as u32;
(*termios_p).c_lflag &= !(ECHO | ECHONL | ICANON | ISIG | IEXTEN) as u32;
(*termios_p).c_cflag &= !(CSIZE | PARENB) as u32;
(*termios_p).c_cflag |= CS8 as u32;
(*termios_p).c_cc[VMIN] = 1;
(*termios_p).c_cc[VTIME] = 0;
unsafe {
(*termios_p).c_iflag &=
!(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON) as u32;
(*termios_p).c_oflag &= !OPOST as u32;
(*termios_p).c_lflag &= !(ECHO | ECHONL | ICANON | ISIG | IEXTEN) as u32;
(*termios_p).c_cflag &= !(CSIZE | PARENB) as u32;
(*termios_p).c_cflag |= CS8 as u32;
(*termios_p).c_cc[VMIN] = 1;
(*termios_p).c_cc[VTIME] = 0;
}
}
+65 -54
View File
@@ -2,6 +2,9 @@
//!
//! See <https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/time.h.html>.
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use crate::{
c_str::{CStr, CString},
error::{Errno, ResultExt},
@@ -210,7 +213,7 @@ pub struct itimerspec {
#[deprecated]
#[unsafe(no_mangle)]
pub unsafe extern "C" fn asctime(timeptr: *const tm) -> *mut c_char {
asctime_r(timeptr, &raw mut ASCTIME as *mut _)
unsafe { asctime_r(timeptr, &raw mut ASCTIME as *mut _) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9699919799/functions/asctime.html>.
@@ -221,13 +224,13 @@ pub unsafe extern "C" fn asctime(timeptr: *const tm) -> *mut c_char {
#[deprecated]
#[unsafe(no_mangle)]
pub unsafe extern "C" fn asctime_r(tm: *const tm, buf: *mut c_char) -> *mut c_char {
let tm_sec = (*tm).tm_sec;
let tm_min = (*tm).tm_min;
let tm_hour = (*tm).tm_hour;
let tm_mday = (*tm).tm_mday;
let tm_mon = (*tm).tm_mon;
let tm_year = (*tm).tm_year;
let tm_wday = (*tm).tm_wday;
let tm_sec = unsafe { (*tm).tm_sec };
let tm_min = unsafe { (*tm).tm_min };
let tm_hour = unsafe { (*tm).tm_hour };
let tm_mday = unsafe { (*tm).tm_mday };
let tm_mon = unsafe { (*tm).tm_mon };
let tm_year = unsafe { (*tm).tm_year };
let tm_wday = unsafe { (*tm).tm_wday };
/* Panic when we run into undefined behavior.
*
@@ -323,7 +326,7 @@ pub extern "C" fn clock_getcpuclockid(pid: pid_t, clock_id: *mut clockid_t) -> c
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/clock_getres.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn clock_getres(clock_id: clockid_t, res: *mut timespec) -> c_int {
Sys::clock_getres(clock_id, Out::nullable(res))
Sys::clock_getres(clock_id, unsafe { Out::nullable(res) })
.map(|()| 0)
.or_minus_one_errno()
}
@@ -331,7 +334,7 @@ pub unsafe extern "C" fn clock_getres(clock_id: clockid_t, res: *mut timespec) -
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/clock_getres.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn clock_gettime(clock_id: clockid_t, tp: *mut timespec) -> c_int {
Sys::clock_gettime(clock_id, Out::nonnull(tp))
Sys::clock_gettime(clock_id, unsafe { Out::nonnull(tp) })
.map(|()| 0)
.or_minus_one_errno()
}
@@ -350,7 +353,7 @@ pub extern "C" fn clock_nanosleep(
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/clock_getres.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn clock_settime(clock_id: clockid_t, tp: *const timespec) -> c_int {
Sys::clock_settime(clock_id, tp)
unsafe { Sys::clock_settime(clock_id, tp) }
.map(|()| 0)
.or_minus_one_errno()
}
@@ -363,7 +366,7 @@ pub unsafe extern "C" fn clock_settime(clock_id: clockid_t, tp: *const timespec)
#[deprecated]
#[unsafe(no_mangle)]
pub unsafe extern "C" fn ctime(clock: *const time_t) -> *mut c_char {
asctime(localtime(clock))
unsafe { asctime(localtime(clock)) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9699919799/functions/ctime.html>.
@@ -376,8 +379,8 @@ pub unsafe extern "C" fn ctime(clock: *const time_t) -> *mut c_char {
pub unsafe extern "C" fn ctime_r(clock: *const time_t, buf: *mut c_char) -> *mut c_char {
// Using MaybeUninit<tm> seems to cause a panic during the build process
let mut tm1 = blank_tm();
localtime_r(clock, &mut tm1);
asctime_r(&tm1, buf)
unsafe { localtime_r(clock, &mut tm1) };
unsafe { asctime_r(&tm1, buf) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/difftime.html>.
@@ -395,20 +398,20 @@ pub unsafe extern "C" fn getdate(string: *const c_char) -> *const tm {
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/gmtime.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn gmtime(timer: *const time_t) -> *mut tm {
gmtime_r(timer, &raw mut TM)
unsafe { gmtime_r(timer, &raw mut TM) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/gmtime.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn gmtime_r(clock: *const time_t, result: *mut tm) -> *mut tm {
let _ = get_localtime(*clock, result);
let _ = get_localtime(unsafe { *clock }, result);
result
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/localtime.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn localtime(clock: *const time_t) -> *mut tm {
localtime_r(clock, &raw mut TM)
unsafe { localtime_r(clock, &raw mut TM) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/localtime.html>.
@@ -416,8 +419,8 @@ pub unsafe extern "C" fn localtime(clock: *const time_t) -> *mut tm {
pub unsafe extern "C" fn localtime_r(clock: *const time_t, t: *mut tm) -> *mut tm {
let mut lock = TIMEZONE_LOCK.lock();
clear_timezone(&mut lock);
if let (Some(std_time), dst_time) = get_localtime(*clock, t) {
set_timezone(&mut lock, &std_time, dst_time);
if let (Some(std_time), dst_time) = get_localtime(unsafe { *clock }, t) {
unsafe { set_timezone(&mut lock, &std_time, dst_time) };
}
t
}
@@ -428,12 +431,12 @@ pub unsafe extern "C" fn mktime(timeptr: *mut tm) -> time_t {
let mut lock = TIMEZONE_LOCK.lock();
clear_timezone(&mut lock);
let year = (*timeptr).tm_year + 1900;
let month = ((*timeptr).tm_mon + 1) as _;
let day = (*timeptr).tm_mday as _;
let hour = (*timeptr).tm_hour as _;
let minute = (*timeptr).tm_min as _;
let second = (*timeptr).tm_sec as _;
let year = unsafe { (*timeptr).tm_year } + 1900;
let month = (unsafe { (*timeptr).tm_mon } + 1) as _;
let day = unsafe { (*timeptr).tm_mday } as _;
let hour = unsafe { (*timeptr).tm_hour } as _;
let minute = unsafe { (*timeptr).tm_min } as _;
let second = unsafe { (*timeptr).tm_sec } as _;
let naive_local = match NaiveDate::from_ymd_opt(year, month, day)
.and_then(|date| date.and_hms_opt(hour, minute, second))
@@ -445,7 +448,7 @@ pub unsafe extern "C" fn mktime(timeptr: *mut tm) -> time_t {
}
};
let offset = get_offset((*timeptr).tm_gmtoff).unwrap();
let offset = get_offset(unsafe { (*timeptr).tm_gmtoff }).unwrap();
let tz = time_zone();
// Create DateTime<FixedOffset>
let datetime = match offset.from_local_datetime(&naive_local) {
@@ -460,7 +463,7 @@ pub unsafe extern "C" fn mktime(timeptr: *mut tm) -> time_t {
let tz_datetime = datetime.with_timezone(&tz);
let timestamp = tz_datetime.timestamp();
ptr::write(timeptr, datetime_to_tm(&tz_datetime));
unsafe { ptr::write(timeptr, datetime_to_tm(&tz_datetime)) };
// Convert UTC time to local time
if let (std_time, dst_time) = match tz.timestamp_opt(timestamp, 0) {
@@ -469,7 +472,7 @@ pub unsafe extern "C" fn mktime(timeptr: *mut tm) -> time_t {
MappedLocalTime::Ambiguous(t1, t2) => (t2, Some(t1)),
MappedLocalTime::None => return timestamp,
} {
set_timezone(&mut lock, &std_time, dst_time);
unsafe { set_timezone(&mut lock, &std_time, dst_time) };
}
timestamp
@@ -478,7 +481,9 @@ pub unsafe extern "C" fn mktime(timeptr: *mut tm) -> time_t {
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/nanosleep.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn nanosleep(rqtp: *const timespec, rmtp: *mut timespec) -> c_int {
Sys::nanosleep(rqtp, rmtp).map(|()| 0).or_minus_one_errno()
unsafe { Sys::nanosleep(rqtp, rmtp) }
.map(|()| 0)
.or_minus_one_errno()
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/strftime.html>.
@@ -489,11 +494,13 @@ pub unsafe extern "C" fn strftime(
format: *const c_char,
timeptr: *const tm,
) -> size_t {
let ret = strftime::strftime(
&mut platform::StringWriter(s as *mut u8, maxsize),
format,
timeptr,
);
let ret = unsafe {
strftime::strftime(
&mut platform::StringWriter(s as *mut u8, maxsize),
format,
timeptr,
)
};
if ret < maxsize { ret } else { 0 }
}
@@ -510,7 +517,7 @@ pub unsafe extern "C" fn time(tloc: *mut time_t) -> time_t {
let mut ts = timespec::default();
Sys::clock_gettime(CLOCK_REALTIME, Out::from_mut(&mut ts));
if !tloc.is_null() {
*tloc = ts.tv_sec
unsafe { *tloc = ts.tv_sec }
};
ts.tv_sec
}
@@ -518,17 +525,19 @@ pub unsafe extern "C" fn time(tloc: *mut time_t) -> time_t {
/// Non-POSIX, see <https://www.man7.org/linux/man-pages/man3/timegm.3.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn timegm(tm: *mut tm) -> time_t {
let tm_val = &mut *tm;
let tm_val = unsafe { &mut *tm };
let dt = match convert_tm_generic(&Utc, tm_val) {
Some(dt) => dt,
None => return -1,
};
(*tm).tm_wday = dt.weekday().num_days_from_sunday() as _;
(*tm).tm_yday = dt.ordinal0() as _; // day of year starting at 0
(*tm).tm_isdst = 0; // UTC does not use DST
(*tm).tm_gmtoff = 0; // UTC offset is zero
(*tm).tm_zone = UTC_STR.as_ptr() as *const c_char;
unsafe {
(*tm).tm_wday = dt.weekday().num_days_from_sunday() as _;
(*tm).tm_yday = dt.ordinal0() as _; // day of year starting at 0
(*tm).tm_isdst = 0; // UTC does not use DST
(*tm).tm_gmtoff = 0; // UTC offset is zero
(*tm).tm_zone = UTC_STR.as_ptr() as *const c_char;
}
dt.timestamp()
}
@@ -537,7 +546,7 @@ pub unsafe extern "C" fn timegm(tm: *mut tm) -> time_t {
#[deprecated]
#[unsafe(no_mangle)]
pub unsafe extern "C" fn timelocal(tm: *mut tm) -> time_t {
let tm_val = &mut *tm;
let tm_val = unsafe { &mut *tm };
let tz = time_zone();
let dt = match convert_tm_generic(&tz, tm_val) {
Some(dt) => dt,
@@ -545,11 +554,13 @@ pub unsafe extern "C" fn timelocal(tm: *mut tm) -> time_t {
};
let tz_name = CString::new(tz.name()).unwrap();
(*tm).tm_wday = dt.weekday().num_days_from_sunday() as _;
(*tm).tm_yday = dt.ordinal0() as _; // day of year starting at 0
(*tm).tm_isdst = dt.offset().dst_offset().num_hours() as _;
(*tm).tm_gmtoff = dt.offset().fix().local_minus_utc() as _;
(*tm).tm_zone = tz_name.into_raw().cast();
unsafe {
(*tm).tm_wday = dt.weekday().num_days_from_sunday() as _;
(*tm).tm_yday = dt.ordinal0() as _; // day of year starting at 0
(*tm).tm_isdst = dt.offset().dst_offset().num_hours() as _;
(*tm).tm_gmtoff = dt.offset().fix().local_minus_utc() as _;
(*tm).tm_zone = tz_name.into_raw().cast();
}
dt.timestamp()
}
@@ -653,7 +664,7 @@ pub unsafe extern "C" fn tzset() {
MappedLocalTime::None => return,
};
set_timezone(&mut lock, &std_time, dst_time)
unsafe { set_timezone(&mut lock, &std_time, dst_time) }
}
fn convert_tm_generic<Tz: TimeZone>(tz: &Tz, tm_val: &tm) -> Option<DateTime<Tz>> {
@@ -805,23 +816,23 @@ unsafe fn set_timezone(
let ut_offset = std.offset();
guard.0 = Some(CString::new(ut_offset.abbreviation().expect("Wrong timezone")).unwrap());
tzname.0[0] = guard.0.as_ref().unwrap().as_ptr().cast_mut();
(unsafe { tzname.0 })[0] = guard.0.as_ref().unwrap().as_ptr().cast_mut();
match dst {
Some(dst) => {
guard.1 =
Some(CString::new(dst.offset().abbreviation().expect("Wrong timezone")).unwrap());
tzname.0[1] = guard.1.as_ref().unwrap().as_ptr().cast_mut();
daylight = 1;
(unsafe { tzname.0 })[1] = guard.1.as_ref().unwrap().as_ptr().cast_mut();
unsafe { daylight = 1 };
}
None => {
guard.1 = None;
tzname.0[1] = guard.0.as_ref().unwrap().as_ptr().cast_mut();
daylight = 0;
(unsafe { tzname.0 })[1] = guard.0.as_ref().unwrap().as_ptr().cast_mut();
unsafe { daylight = 0 };
}
}
timezone = -c_long::from(ut_offset.fix().local_minus_utc());
unsafe { timezone = -c_long::from(ut_offset.fix().local_minus_utc()) };
}
#[inline(always)]
+56 -44
View File
@@ -2,6 +2,9 @@
//
// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/strftime.html>.
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use alloc::string::String;
use super::{get_offset, tm};
@@ -31,11 +34,11 @@ use crate::header::langinfo::{
unsafe fn langinfo_to_str(item: nl_item) -> &'static str {
use core::ffi::CStr;
let ptr = nl_langinfo(item);
let ptr = unsafe { nl_langinfo(item) };
if ptr.is_null() {
return "";
}
match CStr::from_ptr(ptr).to_str() {
match unsafe { CStr::from_ptr(ptr) }.to_str() {
Ok(s) => s,
Err(_) => "",
}
@@ -71,7 +74,7 @@ pub unsafe fn strftime<W: WriteByte>(w: &mut W, format: *const c_char, t: *const
tmp.push_str($fmt);
tmp.push('\0');
if !inner_strftime(w, tmp.as_ptr() as *mut c_char, t) {
if unsafe { !inner_strftime(w, tmp.as_ptr() as *mut c_char, t) } {
return false;
}
}};
@@ -88,24 +91,24 @@ pub unsafe fn strftime<W: WriteByte>(w: &mut W, format: *const c_char, t: *const
}};
}
while *format != 0 {
while unsafe { *format } != 0 {
// If the character isn't '%', just copy it out.
if *format as u8 != b'%' {
w!(byte * format as u8);
format = format.offset(1);
if unsafe { *format } as u8 != b'%' {
w!(byte unsafe { *format } as u8);
format = unsafe { format.offset(1) };
continue;
}
// Skip '%'
format = format.offset(1);
format = unsafe { format.offset(1) };
// POSIX says '%E' and '%O' can modify numeric formats for locales,
// but we ignore them in this minimal "C" locale approach.
if *format as u8 == b'E' || *format as u8 == b'O' {
format = format.offset(1);
if unsafe { *format } as u8 == b'E' || unsafe { *format } as u8 == b'O' {
format = unsafe { format.offset(1) };
}
match *format as u8 {
match unsafe { *format } as u8 {
// Literal '%'
b'%' => w!(byte b'%'),
@@ -116,83 +119,83 @@ pub unsafe fn strftime<W: WriteByte>(w: &mut W, format: *const c_char, t: *const
// Abbreviated weekday name: %a
b'a' => {
// `ABDAY_1 + tm_wday` is the correct langinfo ID for abbreviated weekdays
let s = langinfo_to_str(ABDAY_1 + (*t).tm_wday as i32);
let s = unsafe { langinfo_to_str(ABDAY_1 + (*t).tm_wday as i32) };
w!(s);
}
// Full weekday name: %A
b'A' => {
// `DAY_1 + tm_wday` is the correct langinfo ID for full weekdays
let s = langinfo_to_str(DAY_1 + (*t).tm_wday as i32);
let s = unsafe { langinfo_to_str(DAY_1 + (*t).tm_wday as i32) };
w!(s);
}
// Abbreviated month name: %b or %h
b'b' | b'h' => {
let s = langinfo_to_str(ABMON_1 + (*t).tm_mon as i32);
let s = unsafe { langinfo_to_str(ABMON_1 + (*t).tm_mon as i32) };
w!(s);
}
// Full month name: %B
b'B' => {
let s = langinfo_to_str(MON_1 + (*t).tm_mon as i32);
let s = unsafe { langinfo_to_str(MON_1 + (*t).tm_mon as i32) };
w!(s);
}
// Century: %C
b'C' => {
let mut year = (*t).tm_year / 100;
if (*t).tm_year % 100 != 0 {
let mut year = unsafe { (*t).tm_year } / 100;
if unsafe { (*t).tm_year } % 100 != 0 {
year += 1;
}
w!("{:02}", year + 19);
}
// Day of month: %d
b'd' => w!("{:02}", (*t).tm_mday),
b'd' => w!("{:02}", unsafe { (*t).tm_mday }),
// %D => same as %m/%d/%y
b'D' => w!(recurse "%m/%d/%y"),
// Day of month, space-padded: %e
b'e' => w!("{:2}", (*t).tm_mday),
b'e' => w!("{:2}", unsafe { (*t).tm_mday }),
// ISO 8601 date: %F => %Y-%m-%d
b'F' => w!(recurse "%Y-%m-%d"),
// Hour (00-23): %H
b'H' => w!("{:02}", (*t).tm_hour),
b'H' => w!("{:02}", unsafe { (*t).tm_hour }),
// Hour (01-12): %I
b'I' => w!("{:02}", ((*t).tm_hour + 12 - 1) % 12 + 1),
b'I' => w!("{:02}", (unsafe { (*t).tm_hour } + 12 - 1) % 12 + 1),
// Day of year: %j
b'j' => w!("{:03}", (*t).tm_yday + 1),
b'j' => w!("{:03}", unsafe { (*t).tm_yday } + 1),
// etc.
b'k' => w!("{:2}", (*t).tm_hour),
b'l' => w!("{:2}", ((*t).tm_hour + 12 - 1) % 12 + 1),
b'm' => w!("{:02}", (*t).tm_mon + 1),
b'M' => w!("{:02}", (*t).tm_min),
b'k' => w!("{:2}", unsafe { (*t).tm_hour }),
b'l' => w!("{:2}", (unsafe { (*t).tm_hour } + 12 - 1) % 12 + 1),
b'm' => w!("{:02}", unsafe { (*t).tm_mon } + 1),
b'M' => w!("{:02}", unsafe { (*t).tm_min }),
// AM/PM (uppercase): %p
b'p' => {
// Get "AM" / "PM" from langinfo
if (*t).tm_hour < 12 {
w!(langinfo_to_str(AM_STR));
if unsafe { (*t).tm_hour } < 12 {
w!(unsafe { langinfo_to_str(AM_STR) });
} else {
w!(langinfo_to_str(PM_STR));
w!(unsafe { langinfo_to_str(PM_STR) });
}
}
// am/pm (lowercase): %P
b'P' => {
// Convert the AM_STR / PM_STR to lowercase
if (*t).tm_hour < 12 {
let am = langinfo_to_str(AM_STR).to_ascii_lowercase();
if unsafe { (*t).tm_hour } < 12 {
let am = unsafe { langinfo_to_str(AM_STR) }.to_ascii_lowercase();
w!(&am);
} else {
let pm = langinfo_to_str(PM_STR).to_ascii_lowercase();
let pm = unsafe { langinfo_to_str(PM_STR) }.to_ascii_lowercase();
w!(&pm);
}
}
@@ -204,38 +207,44 @@ pub unsafe fn strftime<W: WriteByte>(w: &mut W, format: *const c_char, t: *const
b'R' => w!(recurse "%H:%M"),
// Seconds since the Epoch: %s => calls mktime() to convert tm to time_t
b's' => w!("{}", super::mktime(t as *mut tm)),
b's' => w!("{}", unsafe { super::mktime(t as *mut tm) }),
// Seconds (00-60): %S (unchanged)
b'S' => w!("{:02}", (*t).tm_sec),
b'S' => w!("{:02}", unsafe { (*t).tm_sec }),
// 24-hour clock with seconds: %T => %H:%M:%S
b'T' => w!(recurse "%H:%M:%S"),
// Weekday (1-7, Monday=1): %u
b'u' => w!("{}", ((*t).tm_wday + 7 - 1) % 7 + 1),
b'u' => w!("{}", (unsafe { (*t).tm_wday } + 7 - 1) % 7 + 1),
// Sunday-based week of year: %U
b'U' => w!("{}", ((*t).tm_yday + 7 - (*t).tm_wday) / 7),
b'U' => w!(
"{}",
(unsafe { (*t).tm_yday } + 7 - unsafe { (*t).tm_wday }) / 7
),
// ISO-8601 week of year
b'V' => w!("{}", week_of_year(unsafe { &*t })),
// Weekday (0-6, Sunday=0): %w
b'w' => w!("{}", (*t).tm_wday),
b'w' => w!("{}", unsafe { (*t).tm_wday }),
// Monday-based week of year: %W
b'W' => w!("{}", ((*t).tm_yday + 7 - ((*t).tm_wday + 6) % 7) / 7),
b'W' => w!(
"{}",
(unsafe { (*t).tm_yday } + 7 - (unsafe { (*t).tm_wday } + 6) % 7) / 7
),
// Last two digits of year: %y
b'y' => w!("{:02}", (*t).tm_year % 100),
b'y' => w!("{:02}", unsafe { (*t).tm_year } % 100),
// Full year: %Y
b'Y' => w!("{}", (*t).tm_year + 1900),
b'Y' => w!("{}", unsafe { (*t).tm_year } + 1900),
// Timezone offset: %z
b'z' => {
let offset = (*t).tm_gmtoff;
let offset = unsafe { (*t).tm_gmtoff };
let (sign, offset) = if offset < 0 {
('-', -offset)
} else {
@@ -248,7 +257,10 @@ pub unsafe fn strftime<W: WriteByte>(w: &mut W, format: *const c_char, t: *const
}
// Timezone name: %Z
b'Z' => w!("{}", CStr::from_ptr((*t).tm_zone).to_str().unwrap()),
b'Z' => w!(
"{}",
unsafe { CStr::from_ptr((*t).tm_zone) }.to_str().unwrap()
),
// Date+time+TZ: %+
b'+' => w!(recurse "%a %b %d %T %Z %Y"),
@@ -258,14 +270,14 @@ pub unsafe fn strftime<W: WriteByte>(w: &mut W, format: *const c_char, t: *const
}
// Move past the format specifier
format = format.offset(1);
format = unsafe { format.offset(1) };
}
true
}
// Wrap the writer in a CountingWriter to return how many bytes were written.
let mut cw = platform::CountingWriter::new(w);
if !inner_strftime(&mut cw, format, t) {
if unsafe { !inner_strftime(&mut cw, format, t) } {
return 0;
}
cw.written
+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()
+10 -5
View File
@@ -2,6 +2,9 @@
//!
//! Non-POSIX, see <https://www.man7.org/linux/man-pages/man3/openpty.3.html>.
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use crate::{
header::{sys_ioctl, unistd},
platform::types::{c_int, c_void},
@@ -15,11 +18,13 @@ pub unsafe extern "C" fn login_tty(fd: c_int) -> c_int {
// Set controlling terminal
let mut arg: c_int = 0;
if sys_ioctl::ioctl(
fd,
sys_ioctl::TIOCSCTTY,
&mut arg as *mut c_int as *mut c_void,
) != 0
if unsafe {
sys_ioctl::ioctl(
fd,
sys_ioctl::TIOCSCTTY,
&mut arg as *mut c_int as *mut c_void,
)
} != 0
{
return -1;
}
+165 -146
View File
@@ -2,6 +2,9 @@
//!
//! See <https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/wchar.h.html>.
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use core::{char, ffi::VaList as va_list, mem, ptr, slice, usize};
use crate::{
@@ -49,7 +52,7 @@ pub unsafe extern "C" fn btowc(c: c_int) -> wint_t {
let mut ps: mbstate_t = mbstate_t;
let mut wc: wchar_t = 0;
let saved_errno = platform::ERRNO.get();
let status = mbrtowc(&mut wc, &c as *const c_char, 1, &mut ps);
let status = unsafe { mbrtowc(&mut wc, &c as *const c_char, 1, &mut ps) };
if status == usize::max_value() || status == usize::max_value() - 1 {
platform::ERRNO.set(saved_errno);
return WEOF;
@@ -67,12 +70,14 @@ pub unsafe extern "C" fn fgetwc(stream: *mut FILE) -> wint_t {
let mut wc: wchar_t = 0;
loop {
let nread = fread(
buf[bytes_read..bytes_read + 1].as_mut_ptr() as *mut c_void,
1,
1,
stream,
);
let nread = unsafe {
fread(
buf[bytes_read..bytes_read + 1].as_mut_ptr() as *mut c_void,
1,
1,
stream,
)
};
if nread != 1 {
ERRNO.set(EILSEQ);
@@ -95,12 +100,14 @@ pub unsafe extern "C" fn fgetwc(stream: *mut FILE) -> wint_t {
}
}
mbrtowc(
&mut wc,
buf.as_ptr() as *const c_char,
encoded_length,
ptr::null_mut(),
);
unsafe {
mbrtowc(
&mut wc,
buf.as_ptr() as *const c_char,
encoded_length,
ptr::null_mut(),
)
};
wc as wint_t
}
@@ -111,15 +118,15 @@ pub unsafe extern "C" fn fgetws(ws: *mut wchar_t, n: c_int, stream: *mut FILE) -
//TODO: lock
let mut i = 0;
while ((i + 1) as c_int) < n {
let wc = fgetwc(stream);
let wc = unsafe { fgetwc(stream) };
if wc == WEOF {
return ptr::null_mut();
}
*ws.add(i) = wc as wchar_t;
unsafe { *ws.add(i) = wc as wchar_t };
i += 1;
}
while (i as c_int) < n {
*ws.add(i) = 0;
unsafe { *ws.add(i) = 0 };
i += 1;
}
ws
@@ -132,10 +139,10 @@ pub unsafe extern "C" fn fputwc(wc: wchar_t, stream: *mut FILE) -> wint_t {
static mut INTERNAL: mbstate_t = mbstate_t;
let mut bytes: [c_char; MB_CUR_MAX as usize] = [0; MB_CUR_MAX as usize];
let amount = wcrtomb(bytes.as_mut_ptr(), wc, &raw mut INTERNAL);
let amount = unsafe { wcrtomb(bytes.as_mut_ptr(), wc, &raw mut INTERNAL) };
for i in 0..amount {
fputc(bytes[i] as c_int, &mut *stream);
unsafe { fputc(bytes[i] as c_int, &mut *stream) };
}
wc as wint_t
@@ -146,11 +153,11 @@ pub unsafe extern "C" fn fputwc(wc: wchar_t, stream: *mut FILE) -> wint_t {
pub unsafe extern "C" fn fputws(ws: *const wchar_t, stream: *mut FILE) -> c_int {
let mut i = 0;
loop {
let wc = *ws.add(i);
let wc = unsafe { *ws.add(i) };
if wc == 0 {
return 0;
}
if fputwc(wc, stream) == WEOF {
if unsafe { fputwc(wc, stream) } == WEOF {
return -1;
}
i += 1;
@@ -160,7 +167,7 @@ pub unsafe extern "C" fn fputws(ws: *const wchar_t, stream: *mut FILE) -> c_int
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/fwide.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn fwide(stream: *mut FILE, mode: c_int) -> c_int {
(*stream).try_set_orientation(mode)
unsafe { (*stream).try_set_orientation(mode) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/fwscanf.html>.
@@ -170,19 +177,19 @@ pub unsafe extern "C" fn fwscanf(
format: *const wchar_t,
mut __valist: ...
) -> c_int {
vfwscanf(stream, format, __valist.as_va_list())
unsafe { vfwscanf(stream, format, __valist.as_va_list()) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/getwc.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn getwc(stream: *mut FILE) -> wint_t {
fgetwc(stream)
unsafe { fgetwc(stream) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/getwchar.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn getwchar() -> wint_t {
fgetwc(stdin)
unsafe { fgetwc(stdin) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/mbsinit.html>.
@@ -196,7 +203,7 @@ pub unsafe extern "C" fn mbsinit(ps: *const mbstate_t) -> c_int {
#[unsafe(no_mangle)]
pub unsafe extern "C" fn mbrlen(s: *const c_char, n: size_t, ps: *mut mbstate_t) -> size_t {
static mut INTERNAL: mbstate_t = mbstate_t;
mbrtowc(ptr::null_mut(), s, n, &raw mut INTERNAL)
unsafe { mbrtowc(ptr::null_mut(), s, n, &raw mut INTERNAL) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/mbrtowc.html>.
@@ -216,9 +223,9 @@ pub unsafe extern "C" fn mbrtowc(
}
if s.is_null() {
let xs: [c_char; 1] = [0];
utf8::mbrtowc(pwc, &xs[0] as *const c_char, 1, ps)
unsafe { utf8::mbrtowc(pwc, &xs[0] as *const c_char, 1, ps) }
} else {
utf8::mbrtowc(pwc, s, n, ps)
unsafe { utf8::mbrtowc(pwc, s, n, ps) }
}
}
@@ -239,31 +246,31 @@ pub unsafe extern "C" fn mbsnrtowcs(
let ps = &raw mut INTERNAL;
}
let mut src = *src_ptr;
let mut src = unsafe { *src_ptr };
let mut dst_offset: usize = 0;
let mut src_offset: usize = 0;
while (dst_ptr.is_null() || dst_offset < dst_len) && src_offset < src_len {
let ps_copy = *ps;
let ps_copy = unsafe { *ps };
let mut wc: wchar_t = 0;
let amount = mbrtowc(&mut wc, src.add(src_offset), src_len - src_offset, ps);
let amount = unsafe { mbrtowc(&mut wc, src.add(src_offset), src_len - src_offset, ps) };
// Stop in the event a decoding error occured.
if amount == -1isize as usize {
*src_ptr = src.add(src_offset);
unsafe { *src_ptr = src.add(src_offset) };
return 1isize as usize;
}
// Stop decoding early in the event we encountered a partial character.
if amount == -2isize as usize {
*ps = ps_copy;
unsafe { *ps = ps_copy };
break;
}
// Store the decoded wide character in the destination buffer.
if !dst_ptr.is_null() {
*dst_ptr.add(dst_offset) = wc;
unsafe { *dst_ptr.add(dst_offset) = wc };
}
// Stop decoding after decoding a null character and return a NULL
@@ -279,7 +286,7 @@ pub unsafe extern "C" fn mbsnrtowcs(
src_offset += amount;
}
*src_ptr = src.add(src_offset);
unsafe { *src_ptr = src.add(src_offset) };
dst_offset
}
@@ -293,19 +300,19 @@ pub unsafe extern "C" fn mbsrtowcs(
len: size_t,
ps: *mut mbstate_t,
) -> size_t {
mbsnrtowcs(dst, src, size_t::max_value(), len, ps)
unsafe { mbsnrtowcs(dst, src, size_t::max_value(), len, ps) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/putwc.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn putwc(wc: wchar_t, stream: *mut FILE) -> wint_t {
fputwc(wc, &mut *stream)
unsafe { fputwc(wc, &mut *stream) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/putwchar.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn putwchar(wc: wchar_t) -> wint_t {
fputwc(wc, &mut *stdout)
unsafe { fputwc(wc, &mut *stdout) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/vswscanf.html>.
@@ -316,7 +323,7 @@ pub unsafe extern "C" fn vswscanf(
__valist: va_list,
) -> c_int {
let reader = (s as *const wint_t).into();
wscanf::scanf(reader, format, __valist)
unsafe { wscanf::scanf(reader, format, __valist) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/fwscanf.html>.
@@ -326,7 +333,7 @@ pub unsafe extern "C" fn swscanf(
format: *const wchar_t,
mut __valist: ...
) -> c_int {
vswscanf(s, format, __valist.as_va_list())
unsafe { vswscanf(s, format, __valist.as_va_list()) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/ungetwc.html>.
@@ -340,7 +347,7 @@ pub unsafe extern "C" fn ungetwc(wc: wint_t, stream: &mut FILE) -> wint_t {
static mut INTERNAL: mbstate_t = mbstate_t;
let mut bytes: [c_char; MB_CUR_MAX as usize] = [0; MB_CUR_MAX as usize];
let amount = wcrtomb(bytes.as_mut_ptr(), wc as wchar_t, &raw mut INTERNAL);
let amount = unsafe { wcrtomb(bytes.as_mut_ptr(), wc as wchar_t, &raw mut INTERNAL) };
if amount == usize::MAX {
return WEOF;
}
@@ -352,7 +359,7 @@ pub unsafe extern "C" fn ungetwc(wc: wint_t, stream: &mut FILE) -> wint_t {
If we called ungetc in the non-reversed order, we would get [167, 195]
*/
for i in 0..amount {
ungetc(bytes[amount - 1 - i] as c_int, &mut *stream);
unsafe { ungetc(bytes[amount - 1 - i] as c_int, &mut *stream) };
}
wc
@@ -365,12 +372,12 @@ pub unsafe extern "C" fn vfwprintf(
format: *const wchar_t,
arg: va_list,
) -> c_int {
let mut stream = (*stream).lock();
let mut stream = unsafe { (*stream).lock() };
if let Err(_) = (*stream).try_set_wide_orientation_unlocked() {
return -1;
}
wprintf::wprintf(&mut *stream, WStr::from_ptr(format), arg)
unsafe { wprintf::wprintf(&mut *stream, WStr::from_ptr(format), arg) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/fwprintf.html>.
@@ -380,19 +387,19 @@ pub unsafe extern "C" fn fwprintf(
format: *const wchar_t,
mut __valist: ...
) -> c_int {
vfwprintf(stream, format, __valist.as_va_list())
unsafe { vfwprintf(stream, format, __valist.as_va_list()) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/vfwprintf.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn vwprintf(format: *const wchar_t, arg: va_list) -> c_int {
vfwprintf(&mut *stdout, format, arg)
unsafe { vfwprintf(&mut *stdout, format, arg) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/fwprintf.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn wprintf(format: *const wchar_t, mut __valist: ...) -> c_int {
vfwprintf(&mut *stdout, format, __valist.as_va_list())
unsafe { vfwprintf(&mut *stdout, format, __valist.as_va_list()) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/vfwprintf.html>.
@@ -417,19 +424,19 @@ pub unsafe extern "C" fn swprintf(
format: *const wchar_t,
mut __valist: ...
) -> c_int {
vswprintf(s, n, format, __valist.as_va_list())
unsafe { vswprintf(s, n, format, __valist.as_va_list()) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/wcpcpy.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn wcpcpy(d: *mut wchar_t, s: *const wchar_t) -> *mut wchar_t {
return (wcscpy(d, s)).offset(wcslen(s) as isize);
return unsafe { (wcscpy(d, s)).offset(wcslen(s) as isize) };
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/wcpncpy.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn wcpncpy(d: *mut wchar_t, s: *const wchar_t, n: size_t) -> *mut wchar_t {
return (wcsncpy(d, s, n)).offset(wcsnlen(s, n) as isize);
return unsafe { (wcsncpy(d, s, n)).offset(wcsnlen(s, n) as isize) };
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/wcrtomb.html>.
@@ -444,22 +451,22 @@ pub unsafe extern "C" fn wcrtomb(s: *mut c_char, wc: wchar_t, ps: *mut mbstate_t
(s, wc)
};
utf8::wcrtomb(s_cpy, wc_cpy, ps)
unsafe { utf8::wcrtomb(s_cpy, wc_cpy, ps) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/wcsdup.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn wcsdup(s: *const wchar_t) -> *mut wchar_t {
let l = wcslen(s);
let l = unsafe { wcslen(s) };
let d = malloc((l + 1) * mem::size_of::<wchar_t>()) as *mut wchar_t;
let d = unsafe { malloc((l + 1) * mem::size_of::<wchar_t>()) } as *mut wchar_t;
if d.is_null() {
ERRNO.set(ENOMEM);
return ptr::null_mut();
}
wmemcpy(d, s, l + 1)
unsafe { wmemcpy(d, s, l + 1) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/wcsrtombs.html>.
@@ -474,13 +481,13 @@ pub unsafe extern "C" fn wcsrtombs(
if st.is_null() {
st = &mut mbs;
}
wcsnrtombs(s, ws, size_t::MAX, n, st)
unsafe { wcsnrtombs(s, ws, size_t::MAX, n, st) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/wcscat.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn wcscat(ws1: *mut wchar_t, ws2: *const wchar_t) -> *mut wchar_t {
wcsncat(ws1, ws2, usize::MAX)
unsafe { wcsncat(ws1, ws2, usize::MAX) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/wcschr.html>.
@@ -506,14 +513,14 @@ pub unsafe extern "C" fn wcschr(ws: *const wchar_t, wc: wchar_t) -> *mut wchar_t
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/wcscmp.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn wcscmp(ws1: *const wchar_t, ws2: *const wchar_t) -> c_int {
wcsncmp(ws1, ws2, usize::MAX)
unsafe { wcsncmp(ws1, ws2, usize::MAX) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/wcscoll.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn wcscoll(ws1: *const wchar_t, ws2: *const wchar_t) -> c_int {
//TODO: locale comparison
wcscmp(ws1, ws2)
unsafe { wcscmp(ws1, ws2) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/wcscpy.html>.
@@ -521,8 +528,8 @@ pub unsafe extern "C" fn wcscoll(ws1: *const wchar_t, ws2: *const wchar_t) -> c_
pub unsafe extern "C" fn wcscpy(ws1: *mut wchar_t, ws2: *const wchar_t) -> *mut wchar_t {
let mut i = 0;
loop {
let wc = *ws2.add(i);
*ws1.add(i) = wc;
let wc = unsafe { *ws2.add(i) };
unsafe { *ws1.add(i) = wc };
i += 1;
if wc == 0 {
return ws1;
@@ -532,8 +539,8 @@ pub unsafe extern "C" fn wcscpy(ws1: *mut wchar_t, ws2: *const wchar_t) -> *mut
unsafe fn inner_wcsspn(mut wcs: *const wchar_t, set: *const wchar_t, reject: bool) -> size_t {
let mut count = 0;
while (*wcs) != 0 && wcschr(set, *wcs).is_null() == reject {
wcs = wcs.add(1);
while unsafe { *wcs } != 0 && unsafe { wcschr(set, *wcs).is_null() } == reject {
wcs = unsafe { wcs.add(1) };
count += 1;
}
count
@@ -542,7 +549,7 @@ unsafe fn inner_wcsspn(mut wcs: *const wchar_t, set: *const wchar_t, reject: boo
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/wcscspn.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn wcscspn(wcs: *const wchar_t, set: *const wchar_t) -> size_t {
inner_wcsspn(wcs, set, true)
unsafe { inner_wcsspn(wcs, set, true) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/wcsftime.html>.
@@ -569,18 +576,18 @@ pub unsafe extern "C" fn wcsncat(
ws2: *const wchar_t,
n: size_t,
) -> *mut wchar_t {
let len = wcslen(ws1);
let dest = ws1.add(len);
let len = unsafe { wcslen(ws1) };
let dest = unsafe { ws1.add(len) };
let mut i = 0;
while i < n {
let wc = *ws2.add(i);
let wc = unsafe { *ws2.add(i) };
if wc == 0 {
break;
}
*dest.add(i) = wc;
unsafe { *dest.add(i) = wc };
i += 1;
}
*dest.add(i) = 0;
unsafe { *dest.add(i) = 0 };
ws1
}
@@ -588,8 +595,8 @@ pub unsafe extern "C" fn wcsncat(
#[unsafe(no_mangle)]
pub unsafe extern "C" fn wcsncmp(ws1: *const wchar_t, ws2: *const wchar_t, n: size_t) -> c_int {
for i in 0..n {
let wc1 = *ws1.add(i);
let wc2 = *ws2.add(i);
let wc1 = unsafe { *ws1.add(i) };
let wc2 = unsafe { *ws2.add(i) };
if wc1 != wc2 {
return wc1 - wc2;
} else if wc1 == 0 {
@@ -608,15 +615,15 @@ pub unsafe extern "C" fn wcsncpy(
) -> *mut wchar_t {
let mut i = 0;
while i < n {
let wc = *ws2.add(i);
*ws1.add(i) = wc;
let wc = unsafe { *ws2.add(i) };
unsafe { *ws1.add(i) = wc };
i += 1;
if wc == 0 {
break;
}
}
while i < n {
*ws1.add(i) = 0;
unsafe { *ws1.add(i) = 0 };
i += 1;
}
ws1
@@ -628,12 +635,12 @@ pub unsafe extern "C" fn wcsnlen(mut s: *const wchar_t, maxlen: size_t) -> size_
let mut len = 0;
while len < maxlen {
if *s == 0 {
if unsafe { *s } == 0 {
break;
}
len = len + 1;
s = s.offset(1);
s = unsafe { s.offset(1) };
}
return len;
@@ -660,7 +667,7 @@ pub unsafe extern "C" fn wcsnrtombs(
while read < nwc {
buf.fill(0);
let ret = wcrtomb(buf.as_mut_ptr(), **src, ps);
let ret = unsafe { wcrtomb(buf.as_mut_ptr(), **src, ps) };
if ret == size_t::MAX {
ERRNO.set(EILSEQ);
@@ -672,16 +679,16 @@ pub unsafe extern "C" fn wcsnrtombs(
}
if !dest.is_null() {
ptr::copy_nonoverlapping(buf.as_ptr(), dest, ret);
dest = dest.add(ret);
unsafe { ptr::copy_nonoverlapping(buf.as_ptr(), dest, ret) };
dest = unsafe { dest.add(ret) };
}
if **src == '\0' as wchar_t {
*src = ptr::null();
if unsafe { **src } == '\0' as wchar_t {
unsafe { *src = ptr::null() };
return written;
}
*src = (*src).add(1);
unsafe { *src = (*src).add(1) };
read += 1;
written += ret;
}
@@ -691,8 +698,8 @@ pub unsafe extern "C" fn wcsnrtombs(
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/wcspbrk.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn wcspbrk(mut wcs: *const wchar_t, set: *const wchar_t) -> *mut wchar_t {
wcs = wcs.add(wcscspn(wcs, set));
if *wcs == 0 {
wcs = unsafe { wcs.add(wcscspn(wcs, set)) };
if unsafe { *wcs } == 0 {
ptr::null_mut()
} else {
// Once again, C wants us to transmute a const pointer to a
@@ -707,9 +714,9 @@ pub unsafe extern "C" fn wcsrchr(ws1: *const wchar_t, wc: wchar_t) -> *mut wchar
let mut last_matching_wc = 0 as *const wchar_t;
let mut i = 0;
while *ws1.add(i) != 0 {
if *ws1.add(i) == wc {
last_matching_wc = ws1.add(i);
while unsafe { *ws1.add(i) } != 0 {
if unsafe { *ws1.add(i) } == wc {
last_matching_wc = unsafe { ws1.add(i) };
}
i += 1;
}
@@ -720,24 +727,24 @@ pub unsafe extern "C" fn wcsrchr(ws1: *const wchar_t, wc: wchar_t) -> *mut wchar
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/wcsspn.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn wcsspn(wcs: *const wchar_t, set: *const wchar_t) -> size_t {
inner_wcsspn(wcs, set, false)
unsafe { inner_wcsspn(wcs, set, false) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/wcsstr.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn wcsstr(ws1: *const wchar_t, ws2: *const wchar_t) -> *mut wchar_t {
// Get length of ws2, not including null terminator
let ws2_len = wcslen(ws2);
let ws2_len = unsafe { wcslen(ws2) };
// The standard says that we must return ws1 if ws2 has length 0
if ws2_len == 0 {
ws1 as *mut wchar_t
} else {
let ws1_len = wcslen(ws1);
let ws1_len = unsafe { wcslen(ws1) };
// Construct slices without null terminator
let ws1_slice = slice::from_raw_parts(ws1, ws1_len);
let ws2_slice = slice::from_raw_parts(ws2, ws2_len);
let ws1_slice = unsafe { slice::from_raw_parts(ws1, ws1_len) };
let ws2_slice = unsafe { slice::from_raw_parts(ws2, ws2_len) };
/* Sliding ws2-sized window iterator on ws1. The iterator
* returns None if ws2 is longer than ws1. */
@@ -746,7 +753,7 @@ pub unsafe extern "C" fn wcsstr(ws1: *const wchar_t, ws2: *const wchar_t) -> *mu
/* Find the first offset into ws1 where the window is equal to
* the ws2 contents. Return null pointer if no match is found. */
match ws1_windows.position(|ws1_window| ws1_window == ws2_slice) {
Some(pos) => ws1.add(pos) as *mut wchar_t,
Some(pos) => unsafe { ws1.add(pos) as *mut wchar_t },
None => ptr::null_mut(),
}
}
@@ -754,8 +761,8 @@ pub unsafe extern "C" fn wcsstr(ws1: *const wchar_t, ws2: *const wchar_t) -> *mu
macro_rules! skipws {
($ptr:expr) => {
while isspace(*$ptr) != 0 {
$ptr = $ptr.add(1);
while isspace(unsafe { *$ptr }) != 0 {
$ptr = unsafe { $ptr.add(1) };
}
};
}
@@ -766,37 +773,38 @@ pub unsafe extern "C" fn wcstod(mut ptr: *const wchar_t, end: *mut *mut wchar_t)
const RADIX: u32 = 10;
skipws!(ptr);
let negative = *ptr == '-' as wchar_t;
let negative = unsafe { *ptr } == '-' as wchar_t;
if negative {
ptr = ptr.add(1);
ptr = unsafe { ptr.add(1) };
}
let mut result: c_double = 0.0;
while let Some(digit) = char::from_u32(*ptr as _).and_then(|c| c.to_digit(RADIX)) {
while let Some(digit) = char::from_u32(unsafe { *ptr } as _).and_then(|c| c.to_digit(RADIX)) {
result *= 10.0;
if negative {
result -= digit as c_double;
} else {
result += digit as c_double;
}
ptr = ptr.add(1);
ptr = unsafe { ptr.add(1) };
}
if *ptr == '.' as wchar_t {
ptr = ptr.add(1);
if unsafe { *ptr } == '.' as wchar_t {
ptr = unsafe { ptr.add(1) };
let mut scale = 1.0;
while let Some(digit) = char::from_u32(*ptr as _).and_then(|c| c.to_digit(RADIX)) {
while let Some(digit) = char::from_u32(unsafe { *ptr } as _).and_then(|c| c.to_digit(RADIX))
{
scale /= 10.0;
if negative {
result -= digit as c_double * scale;
} else {
result += digit as c_double * scale;
}
ptr = ptr.add(1);
ptr = unsafe { ptr.add(1) };
}
}
if !end.is_null() {
*end = ptr as *mut _;
unsafe { *end = ptr as *mut _ };
}
result
}
@@ -810,29 +818,29 @@ pub unsafe extern "C" fn wcstok(
) -> *mut wchar_t {
// Choose starting position
if wcs.is_null() {
if (*state).is_null() {
if (unsafe { *state }).is_null() {
// There was no next token
return ptr::null_mut();
}
wcs = *state;
wcs = unsafe { *state };
}
// Advance past any delimiters
wcs = wcs.add(wcsspn(wcs, delim));
wcs = unsafe { wcs.add(wcsspn(wcs, delim)) };
// Check end
if *wcs == 0 {
*state = ptr::null_mut();
if unsafe { *wcs } == 0 {
unsafe { *state = ptr::null_mut() };
return ptr::null_mut();
}
// Advance *to* any delimiters
let end = wcspbrk(wcs, delim);
let end = unsafe { wcspbrk(wcs, delim) };
if end.is_null() {
*state = ptr::null_mut();
unsafe { *state = ptr::null_mut() };
} else {
*end = 0;
*state = end.add(1);
unsafe { *end = 0 };
unsafe { *state = end.add(1) };
}
wcs
}
@@ -845,19 +853,26 @@ macro_rules! strtou_impl {
let mut base = $base;
if (base == 16 || base == 0)
&& *$ptr == '0' as wchar_t
&& (*$ptr.add(1) == 'x' as wchar_t || *$ptr.add(1) == 'X' as wchar_t)
&& unsafe { *$ptr } == '0' as wchar_t
&& (unsafe { *$ptr.add(1) } == 'x' as wchar_t
|| unsafe { *$ptr.add(1) } == 'X' as wchar_t)
{
$ptr = $ptr.add(2);
$ptr = unsafe { $ptr.add(2) };
base = 16;
}
if base == 0 {
base = if *$ptr == '0' as wchar_t { 8 } else { 10 };
base = if unsafe { *$ptr } == '0' as wchar_t {
8
} else {
10
};
};
let mut result: $type = 0;
while let Some(digit) = char::from_u32(*$ptr as u32).and_then(|c| c.to_digit(base as u32)) {
while let Some(digit) =
char::from_u32(unsafe { *$ptr } as u32).and_then(|c| c.to_digit(base as u32))
{
let new = result.checked_mul(base as $type).and_then(|result| {
if $negative {
result.checked_sub(digit as $type)
@@ -873,16 +888,16 @@ macro_rules! strtou_impl {
}
};
$ptr = $ptr.add(1);
$ptr = unsafe { $ptr.add(1) };
}
result
}};
}
macro_rules! strto_impl {
($type:ident, $ptr:expr, $base:expr) => {{
let negative = *$ptr == '-' as wchar_t;
let negative = unsafe { *$ptr } == '-' as wchar_t;
if negative {
$ptr = $ptr.add(1);
$ptr = unsafe { $ptr.add(1) };
}
strtou_impl!($type, $ptr, $base, negative)
}};
@@ -898,7 +913,7 @@ pub unsafe extern "C" fn wcstol(
skipws!(ptr);
let result = strto_impl!(c_long, ptr, base);
if !end.is_null() {
*end = ptr as *mut _;
unsafe { *end = ptr as *mut _ };
}
result
}
@@ -913,7 +928,7 @@ pub unsafe extern "C" fn wcstoll(
skipws!(ptr);
let result = strto_impl!(c_longlong, ptr, base);
if !end.is_null() {
*end = ptr as *mut _;
unsafe { *end = ptr as *mut _ };
}
result
}
@@ -928,7 +943,7 @@ pub unsafe extern "C" fn wcstoimax(
skipws!(ptr);
let result = strto_impl!(intmax_t, ptr, base);
if !end.is_null() {
*end = ptr as *mut _;
unsafe { *end = ptr as *mut _ };
}
result
}
@@ -943,7 +958,7 @@ pub unsafe extern "C" fn wcstoul(
skipws!(ptr);
let result = strtou_impl!(c_ulong, ptr, base);
if !end.is_null() {
*end = ptr as *mut _;
unsafe { *end = ptr as *mut _ };
}
result
}
@@ -958,7 +973,7 @@ pub unsafe extern "C" fn wcstoull(
skipws!(ptr);
let result = strtou_impl!(c_ulonglong, ptr, base);
if !end.is_null() {
*end = ptr as *mut _;
unsafe { *end = ptr as *mut _ };
}
result
}
@@ -973,7 +988,7 @@ pub unsafe extern "C" fn wcstoumax(
skipws!(ptr);
let result = strtou_impl!(uintmax_t, ptr, base);
if !end.is_null() {
*end = ptr as *mut _;
unsafe { *end = ptr as *mut _ };
}
result
}
@@ -984,7 +999,7 @@ pub unsafe extern "C" fn wcstoumax(
/// Encouraged to use `wcsstr` instead, which this implementation simply forwards to.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn wcswcs(ws1: *const wchar_t, ws2: *const wchar_t) -> *mut wchar_t {
wcsstr(ws1, ws2)
unsafe { wcsstr(ws1, ws2) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/wcswidth.html>.
@@ -992,7 +1007,7 @@ pub unsafe extern "C" fn wcswcs(ws1: *const wchar_t, ws2: *const wchar_t) -> *mu
pub unsafe extern "C" fn wcswidth(pwcs: *const wchar_t, n: size_t) -> c_int {
let mut total_width = 0;
for i in 0..n {
let wc_width = wcwidth(*pwcs.add(i));
let wc_width = wcwidth(unsafe { *pwcs.add(i) });
if wc_width < 0 {
return -1;
}
@@ -1029,8 +1044,8 @@ pub extern "C" fn wcwidth(wc: wchar_t) -> c_int {
#[unsafe(no_mangle)]
pub unsafe extern "C" fn wmemchr(ws: *const wchar_t, wc: wchar_t, n: size_t) -> *mut wchar_t {
for i in 0..n {
if *ws.add(i) == wc {
return ws.add(i) as *mut wchar_t;
if unsafe { *ws.add(i) } == wc {
return unsafe { ws.add(i) } as *mut wchar_t;
}
}
ptr::null_mut()
@@ -1040,8 +1055,8 @@ pub unsafe extern "C" fn wmemchr(ws: *const wchar_t, wc: wchar_t, n: size_t) ->
#[unsafe(no_mangle)]
pub unsafe extern "C" fn wmemcmp(ws1: *const wchar_t, ws2: *const wchar_t, n: size_t) -> c_int {
for i in 0..n {
let wc1 = *ws1.add(i);
let wc2 = *ws2.add(i);
let wc1 = unsafe { *ws1.add(i) };
let wc2 = unsafe { *ws2.add(i) };
if wc1 != wc2 {
return wc1 - wc2;
}
@@ -1056,11 +1071,13 @@ pub unsafe extern "C" fn wmemcpy(
ws2: *const wchar_t,
n: size_t,
) -> *mut wchar_t {
string::memcpy(
ws1 as *mut c_void,
ws2 as *const c_void,
n * mem::size_of::<wchar_t>(),
) as *mut wchar_t
(unsafe {
string::memcpy(
ws1 as *mut c_void,
ws2 as *const c_void,
n * mem::size_of::<wchar_t>(),
)
}) as *mut wchar_t
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/wmemmove.html>.
@@ -1070,18 +1087,20 @@ pub unsafe extern "C" fn wmemmove(
ws2: *const wchar_t,
n: size_t,
) -> *mut wchar_t {
string::memmove(
ws1 as *mut c_void,
ws2 as *const c_void,
n * mem::size_of::<wchar_t>(),
) as *mut wchar_t
(unsafe {
string::memmove(
ws1 as *mut c_void,
ws2 as *const c_void,
n * mem::size_of::<wchar_t>(),
)
}) as *mut wchar_t
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/wmemset.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn wmemset(ws: *mut wchar_t, wc: wchar_t, n: size_t) -> *mut wchar_t {
for i in 0..n {
*ws.add(i) = wc;
unsafe { *ws.add(i) = wc };
}
ws
}
@@ -1093,26 +1112,26 @@ pub unsafe extern "C" fn vfwscanf(
format: *const wchar_t,
__valist: va_list,
) -> c_int {
let mut file = (*stream).lock();
let mut file = unsafe { (*stream).lock() };
if let Err(_) = file.try_set_byte_orientation_unlocked() {
return -1;
}
let f: &mut FILE = &mut *file;
let reader: LookAheadReader = f.into();
wscanf::scanf(reader, format, __valist)
unsafe { wscanf::scanf(reader, format, __valist) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/vwscanf.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn vwscanf(format: *const wchar_t, __valist: va_list) -> c_int {
vfwscanf(stdin, format, __valist)
unsafe { vfwscanf(stdin, format, __valist) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/wscanf.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn wscanf(format: *const wchar_t, mut __valist: ...) -> c_int {
vfwscanf(stdin, format, __valist.as_va_list())
unsafe { vfwscanf(stdin, format, __valist.as_va_list()) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/wcscasecmp.html>.
+8 -5
View File
@@ -1,6 +1,9 @@
//UTF implementation parts for wchar.h.
//Partially ported from the Sortix libc
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use core::{char, slice, str, usize};
use crate::{
@@ -42,17 +45,17 @@ fn utf8_char_width(b: u8) -> usize {
//It's guaranteed that we don't have any nullpointers here
pub unsafe fn mbrtowc(pwc: *mut wchar_t, s: *const c_char, n: usize, ps: *mut mbstate_t) -> usize {
let size = utf8_char_width(*s as u8);
let size = utf8_char_width(unsafe { *s } as u8);
if size > n {
platform::ERRNO.set(errno::EILSEQ);
return -2isize as usize;
}
if size == 0 {
platform::ERRNO.set(errno::EILSEQ);
return -1isize as usize;
return unsafe { -1isize as usize };
}
let slice = slice::from_raw_parts(s as *const u8, size);
let slice = unsafe { slice::from_raw_parts(s as *const u8, size) };
let decoded = str::from_utf8(slice);
if decoded.is_err() {
platform::ERRNO.set(errno::EILSEQ);
@@ -64,7 +67,7 @@ pub unsafe fn mbrtowc(pwc: *mut wchar_t, s: *const c_char, n: usize, ps: *mut mb
let result: wchar_t = wc.chars().next().unwrap() as wchar_t;
if !pwc.is_null() {
*pwc = result;
unsafe { *pwc = result };
}
if result != 0 { size } else { 0 }
@@ -81,7 +84,7 @@ pub unsafe fn wcrtomb(s: *mut c_char, wc: wchar_t, ps: *mut mbstate_t) -> usize
let c = dc.unwrap();
let size = c.len_utf8();
let slice = slice::from_raw_parts_mut(s as *mut u8, size);
let slice = unsafe { slice::from_raw_parts_mut(s as *mut u8, size) };
c.encode_utf8(slice);
+4 -1
View File
@@ -1,3 +1,6 @@
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
// TODO: reuse more code with the thin printf impl
use crate::{
c_str::{self, WStr},
@@ -9,5 +12,5 @@ use core::ffi::VaList;
use crate::platform::{self, types::*};
pub unsafe fn wprintf(w: impl Write, format: WStr, ap: VaList) -> c_int {
inner_printf::<c_str::Wide>(w, format, ap).unwrap_or(-1)
unsafe { inner_printf::<c_str::Wide>(w, format, ap).unwrap_or(-1) }
}
+46 -29
View File
@@ -1,3 +1,6 @@
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use super::lookaheadreader::LookAheadReader;
use crate::platform::types::*;
use alloc::{string::String, vec::Vec};
@@ -23,8 +26,8 @@ enum CharKind {
/// Helper function for progressing a C string
unsafe fn next_char(string: &mut *const wchar_t) -> Result<wint_t, c_int> {
let c = **string as wint_t;
*string = string.offset(1);
let c = unsafe { **string } as wint_t;
*string = unsafe { string.offset(1) };
if c == 0 { Err(-1) } else { Ok(c) }
}
@@ -79,8 +82,8 @@ unsafe fn inner_scanf(
}
}
while *format != 0 {
let mut c = next_char(&mut format)?;
while unsafe { *format } != 0 {
let mut c = unsafe { next_char(&mut format) }?;
if c as u8 == b' ' {
maybe_read!(noreset);
@@ -99,18 +102,18 @@ unsafe fn inner_scanf(
}
r.commit();
} else {
c = next_char(&mut format)?;
c = unsafe { next_char(&mut format) }?;
let mut ignore = false;
if c as u8 == b'*' {
ignore = true;
c = next_char(&mut format)?;
c = unsafe { next_char(&mut format) }?;
}
let mut width = String::new();
while c as u8 >= b'0' && c as u8 <= b'9' {
width.push(wc_as_char!(c));
c = next_char(&mut format)?;
c = unsafe { next_char(&mut format) }?;
}
let mut width = if width.is_empty() {
None
@@ -156,7 +159,7 @@ unsafe fn inner_scanf(
_ => break,
}
c = next_char(&mut format)?;
c = unsafe { next_char(&mut format) }?;
}
if c as u8 != b'n' {
@@ -254,7 +257,7 @@ unsafe fn inner_scanf(
n.parse::<$type>().map_err(|_| 0)?
};
if !ignore {
*ap.arg::<*mut $type>() = n;
unsafe { *ap.arg::<*mut $type>() = n };
matched += 1;
}
}};
@@ -274,7 +277,7 @@ unsafe fn inner_scanf(
$type::from_str_radix(&n, radix).map_err(|_| 0)?
};
if !ignore {
*ap.arg::<*mut $final>() = n as $final;
unsafe { *ap.arg::<*mut $final>() = n as $final };
matched += 1;
}
}};
@@ -358,15 +361,18 @@ unsafe fn inner_scanf(
}
}
let mut ptr: Option<*mut $type> =
if ignore { None } else { Some(ap.arg()) };
let mut ptr: Option<*mut $type> = if ignore {
None
} else {
Some(unsafe { ap.arg() })
};
while width.map(|w| w > 0).unwrap_or(true)
&& !(wc_as_char!(wchar)).is_whitespace()
{
if let Some(ref mut ptr) = ptr {
**ptr = wchar as $type;
*ptr = ptr.offset(1);
unsafe { **ptr = wchar as $type };
*ptr = unsafe { ptr.offset(1) };
}
width = width.map(|w| w - 1);
if width.map(|w| w > 0).unwrap_or(true) && !read!() {
@@ -384,21 +390,28 @@ unsafe fn inner_scanf(
}
if c_kind == CharKind::Ascii {
parse_string_type!(c_char);
unsafe {
parse_string_type!(c_char);
}
} else {
parse_string_type!(wchar_t);
unsafe {
parse_string_type!(wchar_t);
}
}
}
b'c' => {
macro_rules! parse_char_type {
($type:ident) => {
let ptr: Option<*mut $type> =
if ignore { None } else { Some(ap.arg()) };
let ptr: Option<*mut $type> = if ignore {
None
} else {
Some(unsafe { ap.arg() })
};
for i in 0..width.unwrap_or(1) {
if let Some(ptr) = ptr {
*ptr.add(i) = wchar as $type;
unsafe { *ptr.add(i) = wchar as $type };
}
width = width.map(|w| w - 1);
if width.map(|w| w > 0).unwrap_or(true) && !read!() {
@@ -422,11 +435,11 @@ unsafe fn inner_scanf(
}
b'[' => {
c = next_char(&mut format)?;
c = unsafe { next_char(&mut format) }?;
let mut matches = Vec::new();
let invert = if c as u8 == b'^' {
c = next_char(&mut format)?;
c = unsafe { next_char(&mut format) }?;
true
} else {
false
@@ -436,12 +449,12 @@ unsafe fn inner_scanf(
loop {
matches.push(c);
prev = c;
c = next_char(&mut format)?;
c = unsafe { next_char(&mut format) }?;
if c as u8 == b'-' {
if prev as u8 == b']' {
continue;
}
c = next_char(&mut format)?;
c = unsafe { next_char(&mut format) }?;
if c as u8 == b']' {
matches.push('-' as wint_t);
break;
@@ -456,7 +469,11 @@ unsafe fn inner_scanf(
}
}
let mut ptr: Option<*mut c_char> = if ignore { None } else { Some(ap.arg()) };
let mut ptr: Option<*mut c_char> = if ignore {
None
} else {
Some(unsafe { ap.arg() })
};
// While we haven't used up all the width, and it matches
let mut data_stored = false;
@@ -464,8 +481,8 @@ unsafe fn inner_scanf(
&& !invert == matches.contains(&wchar)
{
if let Some(ref mut ptr) = ptr {
**ptr = wchar as c_char;
*ptr = ptr.offset(1);
unsafe { **ptr = wchar as c_char };
*ptr = unsafe { ptr.offset(1) };
data_stored = true;
}
r.commit();
@@ -480,13 +497,13 @@ unsafe fn inner_scanf(
}
if data_stored {
*ptr.unwrap() = 0;
unsafe { *ptr.unwrap() = 0 };
matched += 1;
}
}
b'n' => {
if !ignore {
*ap.arg::<*mut c_int>() = count as c_int;
unsafe { *ap.arg::<*mut c_int>() = count as c_int };
}
}
_ => return Err(-1),
@@ -507,7 +524,7 @@ unsafe fn inner_scanf(
}
pub unsafe fn scanf(r: LookAheadReader, format: *const wchar_t, ap: va_list) -> c_int {
match inner_scanf(r, format, ap) {
match unsafe { inner_scanf(r, format, ap) } {
Ok(n) => n,
Err(n) => n,
}
+4 -1
View File
@@ -10,6 +10,9 @@
//! Buffering wrappers for I/O traits
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use core::{cmp, fmt};
use crate::io::{
@@ -172,7 +175,7 @@ impl<R: Read> Read for BufReader<R> {
// we can't skip unconditionally because of the large buffer case in read.
unsafe fn initializer(&self) -> Initializer {
self.inner.initializer()
unsafe { self.inner.initializer() }
}
}
+4 -1
View File
@@ -8,6 +8,9 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use core::cmp;
use crate::io::{self, Error, ErrorKind, Initializer, SeekFrom, prelude::*};
@@ -253,7 +256,7 @@ where
#[inline]
unsafe fn initializer(&self) -> Initializer {
Initializer::nop()
unsafe { Initializer::nop() }
}
}
+6 -3
View File
@@ -8,6 +8,9 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use alloc::string::String;
use core::{cmp, fmt, mem};
@@ -21,7 +24,7 @@ impl<'a, R: Read + ?Sized> Read for &'a mut R {
#[inline]
unsafe fn initializer(&self) -> Initializer {
(**self).initializer()
unsafe { (**self).initializer() }
}
#[cfg(feature = "alloc")]
@@ -100,7 +103,7 @@ impl<R: Read + ?Sized> Read for Box<R> {
#[inline]
unsafe fn initializer(&self) -> Initializer {
(**self).initializer()
unsafe { (**self).initializer() }
}
#[cfg(feature = "alloc")]
@@ -200,7 +203,7 @@ impl<'a> Read for &'a [u8] {
#[inline]
unsafe fn initializer(&self) -> Initializer {
Initializer::nop()
unsafe { Initializer::nop() }
}
#[inline]
+6 -3
View File
@@ -267,6 +267,9 @@
//! [`Result`]: ../result/enum.Result.html
//! [`.unwrap()`]: ../result/enum.Result.html#method.unwrap
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
pub mod buffered;
pub mod cursor;
pub mod error;
@@ -1393,11 +1396,11 @@ impl<T: Read, U: Read> Read for Chain<T, U> {
}
unsafe fn initializer(&self) -> Initializer {
let initializer = self.first.initializer();
let initializer = unsafe { self.first.initializer() };
if initializer.should_initialize() {
initializer
} else {
self.second.initializer()
unsafe { self.second.initializer() }
}
}
}
@@ -1586,7 +1589,7 @@ impl<T: Read> Read for Take<T> {
}
unsafe fn initializer(&self) -> Initializer {
self.inner.initializer()
unsafe { self.inner.initializer() }
}
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize> {
+39 -34
View File
@@ -1,3 +1,6 @@
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
/// Print to stdout
#[macro_export]
macro_rules! print {
@@ -139,7 +142,9 @@ macro_rules! strto_impl {
// const input but mut output, yet the man page says
// "stores the address of the first invalid character in *endptr"
// so obviously it doesn't want us to clone it.
*$endptr = $s.offset(idx) as *mut _;
unsafe {
*$endptr = $s.offset(idx) as *mut _;
}
}
};
@@ -157,12 +162,12 @@ macro_rules! strto_impl {
let mut idx = 0;
// skip any whitespace at the beginning of the string
while ctype::isspace(*$s.offset(idx) as c_int) != 0 {
while ctype::isspace(unsafe { *$s.offset(idx) } as c_int) != 0 {
idx += 1;
}
// check for +/-
let positive = match is_positive(*$s.offset(idx)) {
let positive = match is_positive(unsafe { *$s.offset(idx) }) {
Some((pos, i)) => {
idx += i;
pos
@@ -174,15 +179,15 @@ macro_rules! strto_impl {
};
// convert the string to a number
let num_str = $s.offset(idx);
let num_str = unsafe { $s.offset(idx) };
let res = match $base {
0 => detect_base(num_str).and_then(|($base, i)| {
0 => unsafe { detect_base(num_str) }.and_then(|($base, i)| {
idx += i;
convert_integer(num_str.offset(i), $base)
unsafe { convert_integer(num_str.offset(i), $base) }
}),
8 => convert_octal(num_str),
16 => convert_hex(num_str),
_ => convert_integer(num_str, $base),
8 => unsafe { convert_octal(num_str) },
16 => unsafe { convert_hex(num_str) },
_ => unsafe { convert_integer(num_str, $base) },
};
// check for error parsing octal/hex prefix
@@ -231,86 +236,86 @@ macro_rules! strto_float_impl {
let mut s = $s;
let endptr = $endptr;
while ctype::isspace(*s as c_int) != 0 {
s = s.offset(1);
while ctype::isspace(unsafe{*s} as c_int) != 0 {
s = unsafe{ s.offset(1)};
}
let mut result: $type = 0.0;
let mut exponent: Option<$type> = None;
let mut radix = 10;
let result_sign = match *s as u8 {
let result_sign = match unsafe{*s} as u8 {
b'-' => {
s = s.offset(1);
s = unsafe{s.offset(1)};
-1.0
}
b'+' => {
s = s.offset(1);
s = unsafe{s.offset(1)};
1.0
}
_ => 1.0,
};
let rust_s = CStr::from_ptr(s).to_string_lossy();
let rust_s = unsafe{CStr::from_ptr(s)}.to_string_lossy();
// detect NaN, Inf
if rust_s.to_lowercase().starts_with("inf") {
result = $type::INFINITY;
s = s.offset(3);
s = unsafe{s.offset(3)};
} else if rust_s.to_lowercase().starts_with("nan") {
// we cannot signal negative NaN in LLVM backed languages
// https://github.com/rust-lang/rust/issues/73328 , https://github.com/rust-lang/rust/issues/81261
result = $type::NAN;
s = s.offset(3);
s = unsafe{s.offset(3)};
} else {
if *s as u8 == b'0' && *s.offset(1) as u8 == b'x' {
s = s.offset(2);
if unsafe{*s} as u8 == b'0' && unsafe{*s.offset(1)} as u8 == b'x' {
s = unsafe{s.offset(2)};
radix = 16;
}
while let Some(digit) = (*s as u8 as char).to_digit(radix) {
while let Some(digit) = (unsafe{*s} as u8 as char).to_digit(radix) {
result *= radix as $type;
result += digit as $type;
s = s.offset(1);
s = unsafe{s.offset(1)};
}
if *s as u8 == b'.' {
s = s.offset(1);
if unsafe{*s} as u8 == b'.' {
s = unsafe{s.offset(1)};
let mut i = 1.0;
while let Some(digit) = (*s as u8 as char).to_digit(radix) {
while let Some(digit) = (unsafe{*s} as u8 as char).to_digit(radix) {
i *= radix as $type;
result += digit as $type / i;
s = s.offset(1);
s = unsafe{s.offset(1)};
}
}
let s_before_exponent = s;
exponent = match (*s as u8, radix) {
exponent = match (unsafe{*s} as u8, radix) {
(b'e' | b'E', 10) | (b'p' | b'P', 16) => {
s = s.offset(1);
s = unsafe{s.offset(1)};
let is_exponent_positive = match *s as u8 {
let is_exponent_positive = match unsafe{*s} as u8 {
b'-' => {
s = s.offset(1);
s = unsafe{s.offset(1)};
false
}
b'+' => {
s = s.offset(1);
s = unsafe{s.offset(1)};
true
}
_ => true,
};
// Exponent digits are always in base 10.
if (*s as u8 as char).is_digit(10) {
if (unsafe{*s} as u8 as char).is_digit(10) {
let mut exponent_value = 0;
while let Some(digit) = (*s as u8 as char).to_digit(10) {
while let Some(digit) = (unsafe{*s} as u8 as char).to_digit(10) {
exponent_value *= 10;
exponent_value += digit;
s = s.offset(1);
s = unsafe{s.offset(1)};
}
let exponent_base = match radix {
@@ -339,7 +344,7 @@ macro_rules! strto_float_impl {
// const input but mut output, yet the man page says
// "stores the address of the first invalid character in *endptr"
// so obviously it doesn't want us to clone it.
*endptr = s as *mut _;
unsafe{*endptr = s as *mut _};
}
if let Some(exponent) = exponent {
+6 -3
View File
@@ -9,6 +9,9 @@
//! requirement that `&mut` references are never aliased, which can typically not be assumed when
//! getting pointers from C.
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use core::{cell::UnsafeCell, fmt, marker::PhantomData, mem::MaybeUninit, ptr::NonNull};
/// Wrapper for write-only "out pointers" that are safe to write to
@@ -39,7 +42,7 @@ impl<'a, T: ?Sized> Out<'a, T> {
assert!(!ptr.is_null());
}
Self {
ptr: NonNull::new_unchecked(ptr),
ptr: unsafe { NonNull::new_unchecked(ptr) },
_marker: PhantomData,
}
}
@@ -94,7 +97,7 @@ impl<'a, T> Out<'a, [T]> {
} else {
ptr
};
Self::nonnull(core::slice::from_raw_parts_mut(ptr, len))
unsafe { Self::nonnull(core::slice::from_raw_parts_mut(ptr, len)) }
}
pub fn len(&self) -> usize {
self.ptr.as_ptr().len()
@@ -226,7 +229,7 @@ pub unsafe trait OutProject {}
impl<'a, T: ?Sized> Out<'a, T> {
pub unsafe fn with_lifetime_of<'b, U: ?Sized>(mut self, u: &'b U) -> Out<'b, T> {
Out::nonnull(self.as_mut_ptr())
unsafe { Out::nonnull(self.as_mut_ptr()) }
}
}
+20 -16
View File
@@ -1,3 +1,6 @@
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use core::{
alloc::{GlobalAlloc, Layout},
cell::SyncUnsafeCell,
@@ -33,22 +36,22 @@ unsafe impl GlobalAlloc for Allocator {
#[inline]
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
if layout.align() <= align_of::<max_align_t>() {
(*self.get()).lock().malloc(layout.size())
unsafe { (*self.get()).lock().malloc(layout.size()) }
} else {
(*self.get()).lock().memalign(layout.align(), layout.size())
unsafe { (*self.get()).lock().memalign(layout.align(), layout.size()) }
}
}
#[inline]
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
(*self.get()).lock().free(ptr)
unsafe { (*self.get()).lock().free(ptr) }
}
#[inline]
unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
let ptr = self.alloc(layout);
if !ptr.is_null() && (*self.get()).lock().calloc_must_clear(ptr) {
write_bytes(ptr, 0, layout.size());
let ptr = unsafe { self.alloc(layout) };
if !ptr.is_null() && unsafe { (*self.get()).lock().calloc_must_clear(ptr) } {
unsafe { write_bytes(ptr, 0, layout.size()) };
}
ptr
}
@@ -56,19 +59,20 @@ unsafe impl GlobalAlloc for Allocator {
#[inline]
unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
if layout.align() <= align_of::<max_align_t>() {
(*self.get()).lock().realloc(ptr, new_size)
unsafe { (*self.get()).lock().realloc(ptr, new_size) }
} else {
let new = self.alloc(Layout::from_size_align_unchecked(new_size, layout.align()));
let new =
unsafe { self.alloc(Layout::from_size_align_unchecked(new_size, layout.align())) };
let old_size = layout.size();
let old_align = layout.align();
if !new.is_null() {
let size = cmp::min(old_size, new_size);
copy_nonoverlapping(ptr, new, size);
unsafe { copy_nonoverlapping(ptr, new, size) };
}
drop((old_size, old_align));
(*self.get()).lock().free(ptr);
unsafe { (*self.get()).lock().free(ptr) };
new
}
@@ -76,18 +80,18 @@ unsafe impl GlobalAlloc for Allocator {
}
pub unsafe fn alloc(size: size_t) -> *mut c_void {
(*ALLOCATOR.get()).lock().malloc(size).cast()
unsafe { (*ALLOCATOR.get()).lock().malloc(size) }.cast()
}
pub unsafe fn alloc_align(size: size_t, alignment: size_t) -> *mut c_void {
(*ALLOCATOR.get()).lock().memalign(alignment, size).cast()
unsafe { (*ALLOCATOR.get()).lock().memalign(alignment, size) }.cast()
}
pub unsafe fn realloc(ptr: *mut c_void, size: size_t) -> *mut c_void {
if ptr.is_null() {
(*ALLOCATOR.get()).lock().malloc(size).cast()
unsafe { (*ALLOCATOR.get()).lock().malloc(size) }.cast()
} else {
(*ALLOCATOR.get()).lock().realloc(ptr.cast(), size).cast()
unsafe { (*ALLOCATOR.get()).lock().realloc(ptr.cast(), size) }.cast()
}
}
@@ -95,12 +99,12 @@ pub unsafe fn free(ptr: *mut c_void) {
if ptr.is_null() {
return;
}
(*ALLOCATOR.get()).lock().free(ptr.cast())
unsafe { (*ALLOCATOR.get()).lock().free(ptr.cast()) }
}
pub unsafe fn alloc_usable_size(ptr: *mut c_void) -> size_t {
if ptr.is_null() {
return 0;
}
(*ALLOCATOR.get()).lock().usable_size(ptr.cast())
unsafe { (*ALLOCATOR.get()).lock().usable_size(ptr.cast()) }
}
+12 -7
View File
@@ -1,3 +1,6 @@
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use crate::{
header::{
sys_mman::{self, MAP_FAILED, MREMAP_MAYMOVE},
@@ -115,13 +118,15 @@ pub unsafe fn enable_alloc_after_fork() {
// it will acquire the lock before any other thread,
// protecting it from deadlock,
// due to the child being created with only the calling thread.
if !FORK_PROTECTED {
pthread_atfork(
Some(_acquire_global_lock),
Some(_release_global_lock),
Some(_release_global_lock),
);
FORK_PROTECTED = true;
unsafe {
if !FORK_PROTECTED {
pthread_atfork(
Some(_acquire_global_lock),
Some(_release_global_lock),
Some(_release_global_lock),
);
FORK_PROTECTED = true;
}
}
release_global_lock();
}
+46 -41
View File
@@ -1,3 +1,6 @@
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use core::{arch::asm, num::NonZeroU64, ptr};
use super::{ERRNO, Pal, types::*};
@@ -343,7 +346,7 @@ impl Pal for Sys {
}
unsafe fn dent_reclen_offset(this_dent: &[u8], offset: usize) -> Option<(u16, u64)> {
let dent = this_dent.as_ptr().cast::<dirent>();
Some(((*dent).d_reclen, (*dent).d_off as u64))
Some((unsafe { (*dent).d_reclen }, unsafe { (*dent).d_off } as u64))
}
fn getegid() -> gid_t {
@@ -638,52 +641,54 @@ impl Pal for Sys {
) -> Result<crate::pthread::OsTid> {
let flags = CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_THREAD;
let pid;
asm!("
# Call clone syscall
syscall
unsafe {
asm!("
# Call clone syscall
syscall
# Check if child or parent
test rax, rax
jnz 2f
# Check if child or parent
test rax, rax
jnz 2f
# Load registers
pop rax
pop rdi
pop rsi
pop rdx
pop rcx
pop r8
pop r9
# Load registers
pop rax
pop rdi
pop rsi
pop rdx
pop rcx
pop r8
pop r9
# Call entry point
call rax
# Call entry point
call rax
# Exit
mov rax, 60
xor rdi, rdi
syscall
# Exit
mov rax, 60
xor rdi, rdi
syscall
# Invalid instruction on failure to exit
ud2
# Invalid instruction on failure to exit
ud2
# Return PID if parent
2:
",
inout("rax") SYS_CLONE => pid,
inout("rdi") flags => _,
inout("rsi") stack => _,
inout("rdx") 0 => _,
inout("r10") 0 => _,
inout("r8") 0 => _,
//TODO: out("rbx") _,
out("rcx") _,
out("r9") _,
out("r11") _,
out("r12") _,
out("r13") _,
out("r14") _,
out("r15") _,
);
# Return PID if parent
2:
",
inout("rax") SYS_CLONE => pid,
inout("rdi") flags => _,
inout("rsi") stack => _,
inout("rdx") 0 => _,
inout("r10") 0 => _,
inout("r8") 0 => _,
//TODO: out("rbx") _,
out("rcx") _,
out("r9") _,
out("r11") _,
out("r12") _,
out("r13") _,
out("r14") _,
out("r15") _,
);
}
let tid = e_raw(pid)?;
Ok(crate::pthread::OsTid { thread_id: tid })
+6 -2
View File
@@ -1,5 +1,8 @@
//! Platform abstractions and environment.
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use crate::{
error::{Errno, ResultExt},
io::{self, Read, Write},
@@ -305,7 +308,7 @@ unsafe fn auxv_iter<'a>(ptr: *const usize) -> impl Iterator<Item = [usize; 2]> +
#[cold]
pub unsafe fn get_auxvs(ptr: *const usize) -> Box<[[usize; 2]]> {
//traverse the stack and collect argument environment variables
let mut auxvs = auxv_iter(ptr).collect::<Vec<_>>();
let mut auxvs = unsafe { auxv_iter(ptr) }.collect::<Vec<_>>();
auxvs.sort_unstable_by_key(|[kind, _]| *kind);
auxvs.into_boxed_slice()
@@ -313,7 +316,8 @@ pub unsafe fn get_auxvs(ptr: *const usize) -> Box<[[usize; 2]]> {
// TODO: Find an auxv replacement for Redox's execv protocol
#[cold]
pub unsafe fn get_auxv_raw(ptr: *const usize, requested_kind: usize) -> Option<usize> {
auxv_iter(ptr).find_map(|[kind, value]| Some(value).filter(|_| kind == requested_kind))
unsafe { auxv_iter(ptr) }
.find_map(|[kind, value]| Some(value).filter(|_| kind == requested_kind))
}
pub fn get_auxv(auxvs: &[[usize; 2]], key: usize) -> Option<usize> {
auxvs
+43 -36
View File
@@ -1,5 +1,8 @@
//! Relibc Threads, or RLCT.
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use core::{
cell::UnsafeCell,
mem::MaybeUninit,
@@ -43,7 +46,7 @@ pub unsafe fn init() {
thread.stack_size = STACK_SIZE;
}
Tcb::current()
unsafe { Tcb::current() }
.expect_notls("no TCB present for main thread")
.pthread = thread;
}
@@ -53,7 +56,7 @@ pub unsafe fn init() {
pub unsafe fn terminate_from_main_thread() {
for (_, tcb) in OS_TID_TO_PTHREAD.lock().iter() {
let _ = cancel(&(*tcb.0).pthread);
let _ = unsafe { cancel(&(*tcb.0).pthread) };
}
}
@@ -117,7 +120,7 @@ pub(crate) unsafe fn create(
}
// Create a locked mutex, unlocked by the thread after it has started.
let synchronization_mutex = Mutex::locked(current_sigmask);
let synchronization_mutex = unsafe { Mutex::locked(current_sigmask) };
let synchronization_mutex = &synchronization_mutex;
let stack_size = attrs.stacksize.next_multiple_of(Sys::getpagesize());
@@ -125,14 +128,16 @@ pub(crate) unsafe fn create(
let stack_base = if attrs.stack != 0 {
attrs.stack as *mut c_void
} else {
let ret = sys_mman::mmap(
core::ptr::null_mut(),
stack_size,
sys_mman::PROT_READ | sys_mman::PROT_WRITE,
sys_mman::MAP_PRIVATE | sys_mman::MAP_ANONYMOUS,
-1,
0,
);
let ret = unsafe {
sys_mman::mmap(
core::ptr::null_mut(),
stack_size,
sys_mman::PROT_READ | sys_mman::PROT_WRITE,
sys_mman::MAP_PRIVATE | sys_mman::MAP_ANONYMOUS,
-1,
0,
)
};
if ret as isize == -1 {
// "Insufficient resources"
return Err(Errno(EAGAIN));
@@ -153,8 +158,8 @@ pub(crate) unsafe fn create(
mmap_size: stack_size,
};
let current_tcb = Tcb::current().expect("no TCB!");
let new_tcb = Tcb::new(current_tcb.tls_len).map_err(|_| Errno(ENOMEM))?;
let current_tcb = unsafe { Tcb::current() }.expect("no TCB!");
let new_tcb = unsafe { Tcb::new(current_tcb.tls_len) }.map_err(|_| Errno(ENOMEM))?;
new_tcb.pthread.flags = flags.bits().into();
new_tcb.pthread.stack_base = stack_base;
new_tcb.pthread.stack_size = stack_size;
@@ -164,12 +169,12 @@ pub(crate) unsafe fn create(
new_tcb.linker_ptr = current_tcb.linker_ptr;
new_tcb.mspace = current_tcb.mspace;
let stack_end = stack_base.add(stack_size);
let stack_end = unsafe { stack_base.add(stack_size) };
let mut stack = stack_end as *mut usize;
{
let mut push = |value: usize| {
stack = stack.sub(1);
stack.write(value);
stack = unsafe { stack.sub(1) };
unsafe { stack.write(value) };
};
if cfg!(target_arch = "aarch64") {
@@ -190,7 +195,7 @@ pub(crate) unsafe fn create(
push(new_thread_shim as usize);
}
let Ok(os_tid) = Sys::rlct_clone(stack, &mut new_tcb.os_specific) else {
let Ok(os_tid) = (unsafe { Sys::rlct_clone(stack, &mut new_tcb.os_specific) }) else {
return Err(Errno(EAGAIN));
};
core::mem::forget(stack_raii);
@@ -211,11 +216,11 @@ unsafe extern "C" fn new_thread_shim(
tcb: *mut Tcb,
synchronization_mutex: *const Mutex<u64>,
) -> ! {
let tcb = tcb.as_mut().expect_notls("non-null TLS is required");
let tcb = unsafe { tcb.as_mut() }.expect_notls("non-null TLS is required");
#[cfg(not(target_os = "redox"))]
{
tcb.activate();
unsafe { tcb.activate() };
}
#[cfg(target_os = "redox")]
{
@@ -225,13 +230,13 @@ unsafe extern "C" fn new_thread_shim(
redox_rt::signal::setup_sighandler(&tcb.os_specific, false);
}
let procmask = (&*synchronization_mutex).as_ptr().read();
let procmask = unsafe { (&*synchronization_mutex).as_ptr().read() };
tcb.copy_masters().unwrap();
unsafe { tcb.copy_masters() }.unwrap();
(*tcb).pthread.os_tid.get().write(Sys::current_os_tid());
unsafe { (*tcb).pthread.os_tid.get().write(Sys::current_os_tid()) };
(&*synchronization_mutex).manual_unlock();
unsafe { (&*synchronization_mutex).manual_unlock() };
#[cfg(target_os = "redox")]
{
@@ -239,9 +244,9 @@ unsafe extern "C" fn new_thread_shim(
.expect("failed to set procmask in child thread");
}
let retval = entry_point(arg);
let retval = unsafe { entry_point(arg) };
exit_current_thread(Retval(retval))
unsafe { exit_current_thread(Retval(retval)) }
}
pub unsafe fn join(thread: &Pthread) -> Result<Retval, Errno> {
// We don't have to return EDEADLK, but unlike e.g. pthread_t lifetime checking, it's a
@@ -260,7 +265,7 @@ pub unsafe fn join(thread: &Pthread) -> Result<Retval, Errno> {
// pthread_t of this thread, will no longer be valid. In practice, we can thus deallocate the
// thread state.
dealloc_thread(thread);
unsafe { dealloc_thread(thread) };
Ok(retval)
}
@@ -282,15 +287,15 @@ pub unsafe fn testcancel() {
if this_thread.has_queued_cancelation.load(Ordering::Acquire)
&& this_thread.has_enabled_cancelation.load(Ordering::Acquire)
{
cancel_current_thread();
unsafe { cancel_current_thread() };
}
}
pub unsafe fn exit_current_thread(retval: Retval) -> ! {
// Run pthread_cleanup_push/pthread_cleanup_pop destructors.
header::run_destructor_stack();
unsafe { header::run_destructor_stack() };
header::tls::run_all_destructors();
unsafe { header::tls::run_all_destructors() };
let this = current_thread().expect("failed to obtain current thread when exiting");
let stack_base = this.stack_base;
@@ -299,28 +304,30 @@ pub unsafe fn exit_current_thread(retval: Retval) -> ! {
if this.flags.load(Ordering::Acquire) & PthreadFlags::DETACHED.bits() != 0 {
// When detached, the thread state no longer makes any sense, and can immediately be
// deallocated.
dealloc_thread(this);
unsafe { dealloc_thread(this) };
} else {
// When joinable, the return value should be made available to other threads.
this.waitval.post(retval);
unsafe { this.waitval.post(retval) };
}
Sys::exit_thread(stack_base.cast(), stack_size)
unsafe { Sys::exit_thread(stack_base.cast(), stack_size) }
}
unsafe fn dealloc_thread(thread: &Pthread) {
// TODO: How should this be handled on Linux?
OS_TID_TO_PTHREAD.lock().remove(&thread.os_tid.get().read());
unsafe {
OS_TID_TO_PTHREAD.lock().remove(&thread.os_tid.get().read());
}
}
pub const SIGRT_RLCT_CANCEL: usize = 33;
pub const SIGRT_RLCT_TIMER: usize = 34;
unsafe extern "C" fn cancel_sighandler(_: c_int) {
cancel_current_thread();
unsafe { cancel_current_thread() };
}
unsafe fn cancel_current_thread() {
// Terminate the thread
exit_current_thread(Retval(header::PTHREAD_CANCELED));
unsafe { exit_current_thread(Retval(header::PTHREAD_CANCELED)) };
}
pub unsafe fn cancel(thread: &Pthread) -> Result<(), Errno> {
@@ -328,7 +335,7 @@ pub unsafe fn cancel(thread: &Pthread) -> Result<(), Errno> {
thread.has_queued_cancelation.store(true, Ordering::Release);
if thread.has_enabled_cancelation.load(Ordering::Acquire) {
Sys::rlct_kill(thread.os_tid.get().read(), SIGRT_RLCT_CANCEL)?;
(unsafe { Sys::rlct_kill(thread.os_tid.get().read(), SIGRT_RLCT_CANCEL) })?;
}
Ok(())
+6 -3
View File
@@ -1,3 +1,6 @@
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use core::cell::UnsafeCell;
/// Wrapper over `UnsafeCell` that can directly be used in statics, where all modifications require
@@ -27,15 +30,15 @@ impl<T> RawCell<T> {
}
#[inline]
pub unsafe fn unsafe_ref(&self) -> &T {
&*self.inner.get()
unsafe { &*self.inner.get() }
}
#[inline]
pub unsafe fn unsafe_set(&self, t: T) {
*self.inner.get() = t;
unsafe { *self.inner.get() = t };
}
#[inline]
pub unsafe fn unsafe_mut(&self) -> &mut T {
&mut *self.inner.get()
unsafe { &mut *self.inner.get() }
}
}
+37 -32
View File
@@ -1,5 +1,8 @@
//! Startup code.
// TODO: set this for entire crate when possible
#![deny(unsafe_op_in_unsafe_fn)]
use alloc::{boxed::Box, vec::Vec};
use core::{intrinsics, ptr};
use generic_rt::ExpectTlsFree;
@@ -42,15 +45,15 @@ impl Stack {
unsafe fn copy_string_array(array: *const *const c_char, len: usize) -> Vec<*mut c_char> {
let mut vec = Vec::with_capacity(len + 1);
for i in 0..len {
let item = *array.add(i);
let item = unsafe { *array.add(i) };
let mut len = 0;
while *item.add(len) != 0 {
while unsafe { *item.add(len) } != 0 {
len += 1;
}
let buf = platform::alloc(len + 1) as *mut c_char;
let buf = unsafe { platform::alloc(len + 1) } as *mut c_char;
for i in 0..=len {
*buf.add(i) = *item.add(i);
unsafe { *buf.add(i) = *item.add(i) };
}
vec.push(buf);
}
@@ -147,7 +150,7 @@ pub unsafe extern "C" fn relibc_start_v1(
}
// Ensure correct host system before executing more system calls
relibc_verify_host();
unsafe { relibc_verify_host() };
#[cfg(target_os = "redox")]
let thr_fd = redox_rt::proc::FdGuard::new(
@@ -158,17 +161,19 @@ pub unsafe extern "C" fn relibc_start_v1(
.expect_notls("failed to move thread fd to upper table");
// Initialize TLS, if necessary
ld_so::init(
sp,
#[cfg(target_os = "redox")]
thr_fd,
);
unsafe {
ld_so::init(
sp,
#[cfg(target_os = "redox")]
thr_fd,
)
};
// Set up the right allocator...
// if any memory rust based memory allocation happen before this step .. we are doomed.
alloc_init();
if let Some(tcb) = ld_so::tcb::Tcb::current() {
if let Some(tcb) = unsafe { ld_so::tcb::Tcb::current() } {
// Update TCB mspace
tcb.mspace = ALLOCATOR.get();
@@ -186,60 +191,60 @@ pub unsafe extern "C" fn relibc_start_v1(
// Set up argc and argv
let argc = sp.argc;
let argv = sp.argv();
platform::inner_argv.unsafe_set(copy_string_array(argv, argc as usize));
platform::argv = platform::inner_argv.unsafe_mut().as_mut_ptr();
unsafe { platform::inner_argv.unsafe_set(copy_string_array(argv, argc as usize)) };
unsafe { platform::argv = platform::inner_argv.unsafe_mut().as_mut_ptr() };
// Special code for program_invocation_name and program_invocation_short_name
if let Some(arg) = platform::inner_argv.unsafe_ref().get(0) {
platform::program_invocation_name = *arg;
platform::program_invocation_short_name = libgen::basename(*arg);
if let Some(arg) = unsafe { platform::inner_argv.unsafe_ref() }.get(0) {
unsafe { platform::program_invocation_name = *arg };
unsafe { platform::program_invocation_short_name = libgen::basename(*arg) };
}
// We check for NULL here since ld.so might already have initialized it for us, and we don't
// want to overwrite it if constructors in .init_array of dependency libraries have called
// setenv.
if platform::environ.is_null() {
if unsafe { platform::environ }.is_null() {
// Set up envp
let envp = sp.envp();
let mut len = 0;
while !(*envp.add(len)).is_null() {
while !(unsafe { *envp.add(len) }).is_null() {
len += 1;
}
platform::OUR_ENVIRON.unsafe_set(copy_string_array(envp, len));
platform::environ = platform::OUR_ENVIRON.unsafe_mut().as_mut_ptr();
unsafe { platform::OUR_ENVIRON.unsafe_set(copy_string_array(envp, len)) };
unsafe { platform::environ = platform::OUR_ENVIRON.unsafe_mut().as_mut_ptr() };
}
let auxvs = get_auxvs(sp.auxv().cast());
crate::platform::init(auxvs);
let auxvs = unsafe { get_auxvs(sp.auxv().cast()) };
unsafe { crate::platform::init(auxvs) };
init_array();
// Run preinit array
{
let mut f = &__preinit_array_start as *const _;
let mut f = unsafe { &__preinit_array_start } as *const _;
#[allow(clippy::op_ref)]
while f < &__preinit_array_end {
(*f)();
f = f.offset(1);
while f < unsafe { &__preinit_array_end } {
(unsafe { *f })();
f = unsafe { f.offset(1) };
}
}
// Call init section
#[cfg(not(target_arch = "riscv64"))] // risc-v uses arrays exclusively
{
_init();
unsafe { _init() };
}
// Run init array
{
let mut f = &__init_array_start as *const _;
let mut f = unsafe { &__init_array_start } as *const _;
#[allow(clippy::op_ref)]
while f < &__init_array_end {
(*f)();
f = f.offset(1);
while f < unsafe { &__init_array_end } {
(unsafe { *f })();
f = unsafe { f.offset(1) };
}
}
// not argv or envp, because programs like bash try to modify this *const* pointer :|
stdlib::exit(main(argc, platform::argv, platform::environ));
unsafe { stdlib::exit(main(argc, platform::argv, platform::environ)) };
unreachable!();
}