From e57ef36d3ced1b7a6001ff9361466f71ce0f0736 Mon Sep 17 00:00:00 2001 From: sourceturner <126549-sourceturner@users.noreply.gitlab.redox-os.org> Date: Sun, 18 Jan 2026 21:01:15 +0100 Subject: [PATCH 01/33] Use unsafe blocks in netdb.h implementation --- src/header/netdb/host.rs | 91 +++++---- src/header/netdb/mod.rs | 418 +++++++++++++++++++++------------------ 2 files changed, 277 insertions(+), 232 deletions(-) diff --git a/src/header/netdb/host.rs b/src/header/netdb/host.rs index 949001f0fa..a9c30a6254 100644 --- a/src/header/netdb/host.rs +++ b/src/header/netdb/host.rs @@ -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 = 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 = 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> = 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 } diff --git a/src/header/netdb/mod.rs b/src/header/netdb/mod.rs index d41865d12d..072cd64b11 100644 --- a/src/header/netdb/mod.rs +++ b/src/header/netdb/mod.rs @@ -2,6 +2,9 @@ //! //! See . +// 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 { /// See . #[unsafe(no_mangle)] pub unsafe extern "C" fn endnetent() { - Sys::close(NETDB); - NETDB = 0; + Sys::close(unsafe { NETDB }); + unsafe { NETDB = 0 }; } /// See . #[unsafe(no_mangle)] pub unsafe extern "C" fn endprotoent() { - Sys::close(PROTODB); - PROTODB = 0; + Sys::close(unsafe { PROTODB }); + unsafe { PROTODB = 0 }; } /// See . #[unsafe(no_mangle)] pub unsafe extern "C" fn endservent() { - Sys::close(SERVDB); - SERVDB = 0; + Sys::close(unsafe { SERVDB }); + unsafe { SERVDB = 0 }; } /// See . @@ -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 = 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::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 = 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 = 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> = 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 . #[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 . #[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 = 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> = 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 . #[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 . #[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 . #[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 = 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::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 . #[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 . #[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 . #[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::() { + match unsafe { str::from_utf8_unchecked(service.to_bytes()) }.parse::() { 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::() 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::() 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); } From ac449a4338e8ec1c01f6650d126b84e4eb997c5a Mon Sep 17 00:00:00 2001 From: sourceturner <126549-sourceturner@users.noreply.gitlab.redox-os.org> Date: Sun, 18 Jan 2026 21:09:17 +0100 Subject: [PATCH 02/33] Use unsafe blocks in pthread.h implementation --- src/header/pthread/attr.rs | 49 ++++++++++++++++--------------- src/header/pthread/barrier.rs | 21 ++++++------- src/header/pthread/cond.rs | 45 ++++++++++++++++------------ src/header/pthread/mod.rs | 55 ++++++++++++++++++++--------------- src/header/pthread/mutex.rs | 55 ++++++++++++++++++----------------- src/header/pthread/once.rs | 5 +++- src/header/pthread/rwlock.rs | 45 +++++++++++++++------------- src/header/pthread/spin.rs | 19 +++++++----- src/header/pthread/tls.rs | 5 +++- 9 files changed, 168 insertions(+), 131 deletions(-) diff --git a/src/header/pthread/attr.rs b/src/header/pthread/attr.rs index e82eac089f..aa2329859e 100644 --- a/src/header/pthread/attr.rs +++ b/src/header/pthread/attr.rs @@ -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::()).detachstate as _); + unsafe { core::ptr::write(detachstate, (*attr.cast::()).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::()).guardsize); + unsafe { core::ptr::write(size, (*attr.cast::()).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::()).inheritsched as _); + unsafe { core::ptr::write(inheritsched, (*attr.cast::()).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::()).param); + unsafe { param.write((*attr.cast::()).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::()).schedpolicy as _); + unsafe { core::ptr::write(policy, (*attr.cast::()).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::()).scope as _); + unsafe { core::ptr::write(scope, (*attr.cast::()).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::()).stack as _); - core::ptr::write(stacksize, (*attr.cast::()).stacksize as _); + unsafe { core::ptr::write(stackaddr, (*attr.cast::()).stack as _) }; + unsafe { core::ptr::write(stacksize, (*attr.cast::()).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::()).stacksize as _); + unsafe { core::ptr::write(stacksize, (*attr.cast::()).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::default()); + unsafe { core::ptr::write(attr.cast::(), 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::()).detachstate = detachstate as _; + (unsafe { *attr.cast::() }).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::()).guardsize = guardsize as _; + (unsafe { *attr.cast::() }).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::()).inheritsched = inheritsched as _; + (unsafe { *attr.cast::() }).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::()).param = param.read(); + (unsafe { *attr.cast::() }).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::()).schedpolicy = policy as u8; + (unsafe { *attr.cast::() }).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::()).scope = scope as u8; + (unsafe { *attr.cast::() }).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::()).stack = stackaddr as usize; - (*attr.cast::()).stacksize = stacksize; + (unsafe { *attr.cast::() }).stack = stackaddr as usize; + (unsafe { *attr.cast::() }).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::()).stacksize = stacksize; + (unsafe { *attr.cast::() }).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::(); + let thread = unsafe { &*thread_ptr.cast::() }; let attr_ptr = attr_ptr.cast::(); - 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 _; } diff --git a/src/header/pthread/barrier.rs b/src/header/pthread/barrier.rs index 06b74e3059..f3618bf685 100644 --- a/src/header/pthread/barrier.rs +++ b/src/header/pthread/barrier.rs @@ -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::()); + unsafe { core::ptr::drop_in_place(barrier.cast::()) }; 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::() - .as_ref() + let attr = unsafe { attr.cast::().as_ref() } .copied() .unwrap_or_default(); @@ -49,7 +50,7 @@ pub unsafe extern "C" fn pthread_barrier_init( return EINVAL; }; - barrier.cast::().write(RlctBarrier::new(count)); + unsafe { barrier.cast::().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::(); + let barrier = unsafe { &*barrier.cast::() }; 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::default()); + unsafe { core::ptr::write(attr.cast::(), 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::()).pshared = pshared; + (unsafe { *attr.cast::() }).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::()).pshared); + unsafe { core::ptr::write(pshared, (*attr.cast::()).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 } diff --git a/src/header/pthread/cond.rs b/src/header/pthread/cond.rs index 91b9763775..7fda576d39 100644 --- a/src/header/pthread/cond.rs +++ b/src/header/pthread/cond.rs @@ -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::()).broadcast()) + e((unsafe { &*cond.cast::() }).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::()); + unsafe { core::ptr::drop_in_place(cond.cast::()) }; 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::() - .as_ref() + let attr = unsafe { attr.cast::().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::().write(RlctCond::new()); + unsafe { cond.cast::().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::()).signal()) + e((unsafe { &*cond.cast::() }).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::()).timedwait(&*mutex.cast::(), &*timeout)) + e((unsafe { &*cond.cast::() }) + .timedwait(unsafe { &*mutex.cast::() }, 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::()).clockwait(&*mutex.cast::(), &*timeout, clock_id)) + e((unsafe { &*cond.cast::() }).clockwait( + unsafe { &*mutex.cast::() }, + 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::()).wait(&*mutex.cast::())) + e((unsafe { &*cond.cast::() }).wait(unsafe { &*mutex.cast::() })) } #[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::()); + unsafe { core::ptr::drop_in_place(condattr.cast::()) }; // 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::()).clock); + unsafe { core::ptr::write(clock, (*condattr.cast::()).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::()).pshared); + unsafe { core::ptr::write(pshared, (*condattr.cast::()).pshared) }; 0 } #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_condattr_init(condattr: *mut pthread_condattr_t) -> c_int { - condattr - .cast::() - .write(RlctCondAttr::default()); - + unsafe { + condattr + .cast::() + .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::()).clock = clock; + (unsafe { *condattr.cast::() }).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::()).pshared = pshared; + (unsafe { *condattr.cast::() }).pshared = pshared; 0 } diff --git a/src/header/pthread/mod.rs b/src/header/pthread/mod.rs index f01cfa1f75..eba998a6b1 100644 --- a/src/header/pthread/mod.rs +++ b/src/header/pthread/mod.rs @@ -2,6 +2,9 @@ //! //! See . +// 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; 3] = [const { LinkedLis /// See . #[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::().as_ref(); + let attr = unsafe { attr.cast::().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 . #[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 . #[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 . #[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 . #[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 . @@ -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 . #[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 . #[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::(); + let new_entry = unsafe { &mut *new_entry.cast::() }; 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); diff --git a/src/header/pthread/mutex.rs b/src/header/pthread/mutex.rs index 0ea0233a17..c2d7becb7d 100644 --- a/src/header/pthread/mutex.rs +++ b/src/header/pthread/mutex.rs @@ -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::()).make_consistent()) + e((unsafe { &*mutex.cast::() }).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::()); + unsafe { core::ptr::drop_in_place(mutex.cast::()) }; 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::()).prioceiling() { + match (unsafe { &*mutex.cast::() }).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::() - .as_ref() + let attr = unsafe { attr.cast::().as_ref() } .copied() .unwrap_or_default(); match RlctMutex::new(&attr) { Ok(new) => { - mutex.cast::().write(new); + unsafe { mutex.cast::().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::()).lock()) + e((unsafe { &*mutex.cast::() }).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::()).replace_prioceiling(prioceiling) { + match (unsafe { &*mutex.cast::() }).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::()).lock_with_timeout(&relative)) + e((unsafe { &*mutex.cast::() }).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::()).try_lock()) + e((unsafe { &*mutex.cast::() }).try_lock()) } #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_mutex_unlock(mutex: *mut pthread_mutex_t) -> c_int { - e((&*mutex.cast::()).unlock()) + e((unsafe { &*mutex.cast::() }).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::()); + unsafe { core::ptr::drop_in_place(attr.cast::()) }; 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::()).prioceiling); + unsafe { prioceiling.write((*attr.cast::()).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::()).protocol); + unsafe { protocol.write((*attr.cast::()).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::()).pshared); + unsafe { pshared.write((*attr.cast::()).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::()).robust); + unsafe { robust.write((*attr.cast::()).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::()).ty); + unsafe { ty.write((*attr.cast::()).ty) }; 0 } #[unsafe(no_mangle)] pub unsafe extern "C" fn pthread_mutexattr_init(attr: *mut pthread_mutexattr_t) -> c_int { - attr.cast::().write(RlctMutexAttr::default()); + unsafe { attr.cast::().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::()).prioceiling = prioceiling; + (unsafe { *attr.cast::() }).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::()).protocol = protocol; + (unsafe { *attr.cast::() }).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::()).pshared = pshared; + (unsafe { *attr.cast::() }).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::()).robust = robust; + (unsafe { *attr.cast::() }).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::()).ty = ty; + (unsafe { *attr.cast::() }).ty = ty; 0 } diff --git a/src/header/pthread/once.rs b/src/header/pthread/once.rs index 15100ee976..f13da472c4 100644 --- a/src/header/pthread/once.rs +++ b/src/header/pthread/once.rs @@ -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::(); + let once = unsafe { &*once.cast::() }; // TODO: Cancellation points diff --git a/src/header/pthread/rwlock.rs b/src/header/pthread/rwlock.rs index d2259ca3a6..d29cd31515 100644 --- a/src/header/pthread/rwlock.rs +++ b/src/header/pthread/rwlock.rs @@ -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::() - .as_ref() + let attr = unsafe { attr.cast::().as_ref() } .copied() .unwrap_or_default(); - rwlock - .cast::() - .write(RlctRwlock::new(attr.pshared)); + unsafe { + rwlock + .cast::() + .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::() - .write(RlctRwlockAttr::default()); + unsafe { + attr.cast::() + .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::()).pshared.raw()); + unsafe { core::ptr::write(pshared_out, (*attr.cast::()).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::()).pshared = + (unsafe { *attr.cast::() }).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() } } diff --git a/src/header/pthread/spin.rs b/src/header/pthread/spin.rs index f2b4f55e82..cef8da6035 100644 --- a/src/header/pthread/spin.rs +++ b/src/header/pthread/spin.rs @@ -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::(); + let _spinlock = unsafe { &mut *spinlock.cast::() }; // 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::().write(RlctSpinlock { - inner: AtomicInt::new(UNLOCKED), - }); + unsafe { + spinlock.cast::().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::(); + let spinlock = unsafe { &*spinlock.cast::() }; 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::(); + let spinlock = unsafe { &*spinlock.cast::() }; 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::(); + let spinlock = unsafe { &*spinlock.cast::() }; spinlock.inner.store(UNLOCKED, Ordering::Release); diff --git a/src/header/pthread/tls.rs b/src/header/pthread/tls.rs index 82d214a00e..e0a0276c92 100644 --- a/src/header/pthread/tls.rs +++ b/src/header/pthread/tls.rs @@ -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 } From 891eb61239768682028e28b419922c8a17022411 Mon Sep 17 00:00:00 2001 From: sourceturner <126549-sourceturner@users.noreply.gitlab.redox-os.org> Date: Sun, 18 Jan 2026 21:10:03 +0100 Subject: [PATCH 03/33] Use unsafe blocks in pty.h implementation --- src/header/pty/linux.rs | 41 ++++++++++++++++---------- src/header/pty/mod.rs | 65 +++++++++++++++++++++++------------------ 2 files changed, 61 insertions(+), 45 deletions(-) diff --git a/src/header/pty/linux.rs b/src/header/pty/linux.rs index faad407d87..1ad910ba5b 100644 --- a/src/header/pty/linux.rs +++ b/src/header/pty/linux.rs @@ -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(()); diff --git a/src/header/pty/mod.rs b/src/header/pty/mod.rs index 126be6c957..376a8497dd 100644 --- a/src/header/pty/mod.rs +++ b/src/header/pty/mod.rs @@ -2,6 +2,9 @@ //! //! Non-POSIX, see . +// 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::(), - ) > 0 + if unsafe { + unistd::read( + p[0], + &mut ec as *mut c_int as *mut c_void, + mem::size_of::(), + ) + } > 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 } From 59fb13ee2c04515f7635a099a2e8b27c1b1c2cfb Mon Sep 17 00:00:00 2001 From: sourceturner <126549-sourceturner@users.noreply.gitlab.redox-os.org> Date: Sun, 18 Jan 2026 21:10:34 +0100 Subject: [PATCH 04/33] Use unsafe blocks in stdlib.h implementation --- src/header/stdlib/mod.rs | 361 +++++++++++++++++++----------------- src/header/stdlib/random.rs | 23 ++- src/header/stdlib/sort.rs | 39 ++-- 3 files changed, 228 insertions(+), 195 deletions(-) diff --git a/src/header/stdlib/mod.rs b/src/header/stdlib/mod.rs index cef9cdcdd1..c367e7060f 100644 --- a/src/header/stdlib/mod.rs +++ b/src/header/stdlib/mod.rs @@ -2,6 +2,9 @@ //! //! See . +// 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 . @@ -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 . #[unsafe(no_mangle)] pub unsafe extern "C" fn at_quick_exit(func: Option) -> 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) -> c_int { /// See . #[unsafe(no_mangle)] pub unsafe extern "C" fn atexit(func: Option) -> 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) -> c_int { /// See . #[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 . #[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 . @@ -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 . @@ -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 . #[unsafe(no_mangle)] pub unsafe extern "C" fn free(ptr: *mut c_void) { - platform::free(ptr); + unsafe { platform::free(ptr) }; } /// See . @@ -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 . #[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 . @@ -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 . @@ -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 . #[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 . #[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(name: *mut c_char, suffix_len: c_int, mut attempt: F) -> Option @@ -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 . #[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 . @@ -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 . #[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 . #[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 . @@ -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::() * 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 . #[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 . #[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::()]); + let seed_arr: [u8; 16] = unsafe { mem::transmute([*seed; 16 / mem::size_of::()]) }; 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 . #[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 . @@ -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 . #[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 . @@ -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 . #[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 . #[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; diff --git a/src/header/stdlib/random.rs b/src/header/stdlib/random.rs index 16733f0add..14ec843be1 100644 --- a/src/header/stdlib/random.rs +++ b/src/header/stdlib/random.rs @@ -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::().add(1); + let x_u32_ptr: *mut u32 = unsafe { DEFAULT_X.get().cast::().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() }; } } } diff --git a/src/header/stdlib/sort.rs b/src/header/stdlib/sort.rs index f79d361bcd..11d0d81119 100644 --- a/src/header/stdlib/sort.rs +++ b/src/header/stdlib/sort.rs @@ -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) }; } } From bb3ff6e068504d9e8cbee5e548be93f0bd89c471 Mon Sep 17 00:00:00 2001 From: sourceturner <126549-sourceturner@users.noreply.gitlab.redox-os.org> Date: Sun, 18 Jan 2026 21:11:13 +0100 Subject: [PATCH 05/33] Use unsafe blocks in sys/epoll.h implementation --- src/header/sys_epoll/mod.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/header/sys_epoll/mod.rs b/src/header/sys_epoll/mod.rs index 90bc1b96fd..16183b3852 100644 --- a/src/header/sys_epoll/mod.rs +++ b/src/header/sys_epoll/mod.rs @@ -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})", From 3879cb641da5cc2ce7fcfe1ce6df2b615a9ce617 Mon Sep 17 00:00:00 2001 From: sourceturner <126549-sourceturner@users.noreply.gitlab.redox-os.org> Date: Sun, 18 Jan 2026 21:13:34 +0100 Subject: [PATCH 06/33] Use unsafe blocks in ioctl implementation --- src/header/sys_ioctl/linux.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/header/sys_ioctl/linux.rs b/src/header/sys_ioctl/linux.rs index dd32215490..e67375449f 100644 --- a/src/header/sys_ioctl/linux.rs +++ b/src/header/sys_ioctl/linux.rs @@ -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; From 2720f410327ed93207ac7b9b7574c00dcc5b9084 Mon Sep 17 00:00:00 2001 From: sourceturner <126549-sourceturner@users.noreply.gitlab.redox-os.org> Date: Sun, 18 Jan 2026 21:14:10 +0100 Subject: [PATCH 07/33] Use unsafe blocks in sys/mman.h implementation --- src/header/sys_mman/mod.rs | 47 ++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/src/header/sys_mman/mod.rs b/src/header/sys_mman/mod.rs index b8e98db922..8789673674 100644 --- a/src/header/sys_mman/mod.rs +++ b/src/header/sys_mman/mod.rs @@ -2,6 +2,9 @@ //! //! See . +// 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 . #[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 . #[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 . #[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 . @@ -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 . #[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 . #[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 . #[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 . #[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 . #[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 . #[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 . #[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()) } } From 3bace40832a6145eac02e53b87e9ed7056ddb9d2 Mon Sep 17 00:00:00 2001 From: sourceturner <126549-sourceturner@users.noreply.gitlab.redox-os.org> Date: Sun, 18 Jan 2026 21:14:56 +0100 Subject: [PATCH 08/33] Use unsafe blocks in ptrace compatibility layer --- src/header/sys_ptrace/mod.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/header/sys_ptrace/mod.rs b/src/header/sys_ptrace/mod.rs index cee4fc47d6..4e7053d0fd 100644 --- a/src/header/sys_ptrace/mod.rs +++ b/src/header/sys_ptrace/mod.rs @@ -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() } From 6aed86d2829b1cefab221b5e2d87338deee1fee5 Mon Sep 17 00:00:00 2001 From: sourceturner <126549-sourceturner@users.noreply.gitlab.redox-os.org> Date: Sun, 18 Jan 2026 21:15:32 +0100 Subject: [PATCH 09/33] Use unsafe blocks in sys/random.h implementation --- src/header/sys_random/mod.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/header/sys_random/mod.rs b/src/header/sys_random/mod.rs index 332f3aa867..f12f4b80a9 100644 --- a/src/header/sys_random/mod.rs +++ b/src/header/sys_random/mod.rs @@ -2,6 +2,9 @@ //! //! Non-POSIX, see . +// 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) From e07602426812daf080450996ec143edf0b015756 Mon Sep 17 00:00:00 2001 From: sourceturner <126549-sourceturner@users.noreply.gitlab.redox-os.org> Date: Sun, 18 Jan 2026 21:16:02 +0100 Subject: [PATCH 10/33] Use unsafe blocks in sys/resource.h implementation --- src/header/sys_resource/mod.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/header/sys_resource/mod.rs b/src/header/sys_resource/mod.rs index 829bb2ba9b..87e943f68d 100644 --- a/src/header/sys_resource/mod.rs +++ b/src/header/sys_resource/mod.rs @@ -2,6 +2,9 @@ //! //! See . +// 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 . #[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 . #[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 . #[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() } From 3326fafa9049ac04419cabafc91851a228fc12a9 Mon Sep 17 00:00:00 2001 From: sourceturner <126549-sourceturner@users.noreply.gitlab.redox-os.org> Date: Sun, 18 Jan 2026 21:16:37 +0100 Subject: [PATCH 11/33] Use unsafe blocks in sys/select.h implementation --- src/header/sys_select/mod.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/header/sys_select/mod.rs b/src/header/sys_select/mod.rs index 8124f211a9..b97707586b 100644 --- a/src/header/sys_select/mod.rs +++ b/src/header/sys_select/mod.rs @@ -2,6 +2,9 @@ //! //! See . +// 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})", From ee765594a34768a730a6c466b81b90ed51be0855 Mon Sep 17 00:00:00 2001 From: sourceturner <126549-sourceturner@users.noreply.gitlab.redox-os.org> Date: Sun, 18 Jan 2026 21:16:57 +0100 Subject: [PATCH 12/33] Use unsafe blocks in sys/socket.h implementation --- src/header/sys_socket/mod.rs | 62 ++++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 27 deletions(-) diff --git a/src/header/sys_socket/mod.rs b/src/header/sys_socket/mod.rs index e555d23e3f..8a0222e686 100644 --- a/src/header/sys_socket/mod.rs +++ b/src/header/sys_socket/mod.rs @@ -2,6 +2,9 @@ //! //! See . +// 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 . #[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::())) as c_uint + (unsafe { CMSG_ALIGN(len as size_t) } + unsafe { CMSG_ALIGN(mem::size_of::()) }) + as c_uint } /// See . #[unsafe(no_mangle)] pub unsafe extern "C" fn CMSG_LEN(length: c_uint) -> c_uint { - (CMSG_ALIGN(mem::size_of::()) + length as usize) as c_uint + (unsafe { CMSG_ALIGN(mem::size_of::()) } + 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 . @@ -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 . #[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 . #[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, From 95c8e6ddb5455bfd08cf2d90c12e5925656320fe Mon Sep 17 00:00:00 2001 From: sourceturner <126549-sourceturner@users.noreply.gitlab.redox-os.org> Date: Sun, 18 Jan 2026 21:17:21 +0100 Subject: [PATCH 13/33] Use unsafe blocks in sys/stat.h implementation --- src/header/sys_stat/mod.rs | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/src/header/sys_stat/mod.rs b/src/header/sys_stat/mod.rs index b71a5f4d39..bbccc3613b 100644 --- a/src/header/sys_stat/mod.rs +++ b/src/header/sys_stat/mod.rs @@ -83,7 +83,7 @@ pub struct stat { /// See . #[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 . #[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 . #[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 . #[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 . #[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 . #[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 . #[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 . #[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 . #[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 . #[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(); From 263567f2cc18bfa86430d182983c711de9099636 Mon Sep 17 00:00:00 2001 From: sourceturner <126549-sourceturner@users.noreply.gitlab.redox-os.org> Date: Sun, 18 Jan 2026 21:18:06 +0100 Subject: [PATCH 14/33] Use unsafe blocks in sys/statvfs.h implementation --- src/header/sys_statvfs/mod.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/header/sys_statvfs/mod.rs b/src/header/sys_statvfs/mod.rs index aa2a1172c8..61052e0ac7 100644 --- a/src/header/sys_statvfs/mod.rs +++ b/src/header/sys_statvfs/mod.rs @@ -2,6 +2,9 @@ //! //! See . +// 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 . #[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 . #[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 { From 093b830148182418678c784ddae1339266557ede Mon Sep 17 00:00:00 2001 From: sourceturner <126549-sourceturner@users.noreply.gitlab.redox-os.org> Date: Sun, 18 Jan 2026 21:18:45 +0100 Subject: [PATCH 15/33] Use unsafe blocks in syslog.h implementation --- src/header/sys_syslog/mod.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/header/sys_syslog/mod.rs b/src/header/sys_syslog/mod.rs index 0a17dd6c6e..dd436d4bbc 100644 --- a/src/header/sys_syslog/mod.rs +++ b/src/header/sys_syslog/mod.rs @@ -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 . #[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 . From 3bfd14fcab30318adc93adc5e95cd0ec63f5359f Mon Sep 17 00:00:00 2001 From: sourceturner <126549-sourceturner@users.noreply.gitlab.redox-os.org> Date: Sun, 18 Jan 2026 21:19:08 +0100 Subject: [PATCH 16/33] Use unsafe blocks in sys/time.h implementation --- src/header/sys_time/mod.rs | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/header/sys_time/mod.rs b/src/header/sys_time/mod.rs index 9eecc9fdad..3d6193996d 100644 --- a/src/header/sys_time/mod.rs +++ b/src/header/sys_time/mod.rs @@ -2,6 +2,9 @@ //! //! See . +// 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() } From 3ccfc170adacfda4b299f1eae610e8d1e011fa0e Mon Sep 17 00:00:00 2001 From: sourceturner <126549-sourceturner@users.noreply.gitlab.redox-os.org> Date: Sun, 18 Jan 2026 21:19:40 +0100 Subject: [PATCH 17/33] Use unsafe blocks in sys/uio.h implementation --- src/header/sys_uio/mod.rs | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/src/header/sys_uio/mod.rs b/src/header/sys_uio/mod.rs index 8bfb8a289b..627f2a4ad1 100644 --- a/src/header/sys_uio/mod.rs +++ b/src/header/sys_uio/mod.rs @@ -2,6 +2,9 @@ //! //! See . +// 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 { 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 { unsafe fn scatter(iovs: &[iovec], vec: Vec) { 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 . @@ -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()) } } From 560360cb0847d12b9ab8f1845142646dbe35e7a9 Mon Sep 17 00:00:00 2001 From: sourceturner <126549-sourceturner@users.noreply.gitlab.redox-os.org> Date: Sun, 18 Jan 2026 21:20:14 +0100 Subject: [PATCH 18/33] Use unsafe blocks in sys/utsname.h implementation --- src/header/sys_utsname/mod.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/header/sys_utsname/mod.rs b/src/header/sys_utsname/mod.rs index 8751727430..bde1633f7e 100644 --- a/src/header/sys_utsname/mod.rs +++ b/src/header/sys_utsname/mod.rs @@ -2,6 +2,9 @@ //! //! See . +// 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 . #[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() } From 1a7136e6c497305f4a92b9fd78b97b8c8516577b Mon Sep 17 00:00:00 2001 From: sourceturner <126549-sourceturner@users.noreply.gitlab.redox-os.org> Date: Sun, 18 Jan 2026 21:20:33 +0100 Subject: [PATCH 19/33] Use unsafe blocks in sys/wait.h implementation --- src/header/sys_wait/mod.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/header/sys_wait/mod.rs b/src/header/sys_wait/mod.rs index b32ed9f792..adcb21d088 100644 --- a/src/header/sys_wait/mod.rs +++ b/src/header/sys_wait/mod.rs @@ -2,6 +2,9 @@ //! //! See . +// 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 . #[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 . #[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() } From 3873cf9a2814fe871e474f3e339197489bf70b4a Mon Sep 17 00:00:00 2001 From: sourceturner <126549-sourceturner@users.noreply.gitlab.redox-os.org> Date: Sun, 18 Jan 2026 21:21:03 +0100 Subject: [PATCH 20/33] Use unsafe blocks in termios.h implementation --- src/header/termios/mod.rs | 51 +++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/src/header/termios/mod.rs b/src/header/termios/mod.rs index 93afa8b985..358841c232 100644 --- a/src/header/termios/mod.rs +++ b/src/header/termios/mod.rs @@ -2,6 +2,9 @@ //! //! See . +// 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 . #[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 . @@ -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 . #[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 . @@ -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 . @@ -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 . #[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 . #[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 . #[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 . @@ -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 . #[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 . #[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 . @@ -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 . #[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; + } } From 2cf1a2d16a2341433ae759ef0620218326cbac87 Mon Sep 17 00:00:00 2001 From: sourceturner <126549-sourceturner@users.noreply.gitlab.redox-os.org> Date: Sun, 18 Jan 2026 21:22:57 +0100 Subject: [PATCH 21/33] Use unsafe blocks in time.h implementation --- src/header/time/mod.rs | 119 ++++++++++++++++++++---------------- src/header/time/strftime.rs | 100 +++++++++++++++++------------- 2 files changed, 121 insertions(+), 98 deletions(-) diff --git a/src/header/time/mod.rs b/src/header/time/mod.rs index cb3b2c668d..1bb0668b1b 100644 --- a/src/header/time/mod.rs +++ b/src/header/time/mod.rs @@ -2,6 +2,9 @@ //! //! See . +// 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 . @@ -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 . #[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 . #[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 . #[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 . @@ -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 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 . @@ -395,20 +398,20 @@ pub unsafe extern "C" fn getdate(string: *const c_char) -> *const tm { /// See . #[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 . #[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 . #[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 . @@ -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 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 . #[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 . @@ -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 . #[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: &Tz, tm_val: &tm) -> Option> { @@ -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)] diff --git a/src/header/time/strftime.rs b/src/header/time/strftime.rs index f84707516f..df647f0764 100644 --- a/src/header/time/strftime.rs +++ b/src/header/time/strftime.rs @@ -2,6 +2,9 @@ // // See . +// 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: &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: &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: &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: &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: &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: &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 From 61e098eb2c501e826cdbce55ed9f04f5c6ccd262 Mon Sep 17 00:00:00 2001 From: sourceturner <126549-sourceturner@users.noreply.gitlab.redox-os.org> Date: Sun, 18 Jan 2026 21:23:24 +0100 Subject: [PATCH 22/33] Use unsafe blocks in unistd.h implementation --- src/header/unistd/brk.rs | 19 +++-- src/header/unistd/getopt.rs | 5 +- src/header/unistd/mod.rs | 164 ++++++++++++++++++++---------------- 3 files changed, 107 insertions(+), 81 deletions(-) diff --git a/src/header/unistd/brk.rs b/src/header/unistd/brk.rs index 5ba63954fc..61ac540a70 100644 --- a/src/header/unistd/brk.rs +++ b/src/header/unistd/brk.rs @@ -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; } diff --git a/src/header/unistd/getopt.rs b/src/header/unistd/getopt.rs index 1729560ab7..f3963c46c0 100644 --- a/src/header/unistd/getopt.rs +++ b/src/header/unistd/getopt.rs @@ -2,6 +2,9 @@ //! //! See . +// 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()) } } diff --git a/src/header/unistd/mod.rs b/src/header/unistd/mod.rs index 19d57a280f..9b05bbd7d3 100644 --- a/src/header/unistd/mod.rs +++ b/src/header/unistd/mod.rs @@ -2,6 +2,9 @@ //! //! See . +// 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 . #[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 . @@ -137,7 +140,7 @@ pub extern "C" fn _exit(status: c_int) -> ! { /// See . #[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 . #[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 . #[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 . @@ -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 . @@ -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 . @@ -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 . #[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 . @@ -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 . #[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 . #[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 . #[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 . #[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 . #[unsafe(no_mangle)] pub unsafe extern "C" fn pipe(fildes: *mut c_int) -> c_int { - pipe2(fildes, 0) + unsafe { pipe2(fildes, 0) } } /// See . #[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::(), nbyte), + unsafe { slice::from_raw_parts_mut(buf.cast::(), 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::(), nbyte), + unsafe { slice::from_raw_parts(buf.cast::(), 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 . #[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 . @@ -1026,8 +1044,8 @@ pub unsafe extern "C" fn swab(src: *const c_void, dest: *mut c_void, nbytes: ssi /// See . #[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 . #[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::>(), argc) + unsafe { slice::from_raw_parts_mut(ptr.cast::>(), 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 . #[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() From 83815c74330b13fba6578bbea6f427bc14b973f3 Mon Sep 17 00:00:00 2001 From: sourceturner <126549-sourceturner@users.noreply.gitlab.redox-os.org> Date: Sun, 18 Jan 2026 21:23:50 +0100 Subject: [PATCH 23/33] Use unsafe blocks in utmp.h implementation --- src/header/utmp/mod.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/header/utmp/mod.rs b/src/header/utmp/mod.rs index 26c85f026a..6032fa6dc7 100644 --- a/src/header/utmp/mod.rs +++ b/src/header/utmp/mod.rs @@ -2,6 +2,9 @@ //! //! Non-POSIX, see . +// 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; } From 718dc53b87e47a54d486a2c273a21132a52aa599 Mon Sep 17 00:00:00 2001 From: sourceturner <126549-sourceturner@users.noreply.gitlab.redox-os.org> Date: Sun, 18 Jan 2026 21:25:10 +0100 Subject: [PATCH 24/33] Use unsafe blocks in wchar.h implementation --- src/header/wchar/mod.rs | 311 +++++++++++++++++++----------------- src/header/wchar/utf8.rs | 13 +- src/header/wchar/wprintf.rs | 5 +- src/header/wchar/wscanf.rs | 75 +++++---- 4 files changed, 223 insertions(+), 181 deletions(-) diff --git a/src/header/wchar/mod.rs b/src/header/wchar/mod.rs index 32909f8602..32236b5e6d 100644 --- a/src/header/wchar/mod.rs +++ b/src/header/wchar/mod.rs @@ -2,6 +2,9 @@ //! //! See . +// 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 . #[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 . @@ -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 . #[unsafe(no_mangle)] pub unsafe extern "C" fn getwc(stream: *mut FILE) -> wint_t { - fgetwc(stream) + unsafe { fgetwc(stream) } } /// See . #[unsafe(no_mangle)] pub unsafe extern "C" fn getwchar() -> wint_t { - fgetwc(stdin) + unsafe { fgetwc(stdin) } } /// See . @@ -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 . @@ -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 . #[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 . #[unsafe(no_mangle)] pub unsafe extern "C" fn putwchar(wc: wchar_t) -> wint_t { - fputwc(wc, &mut *stdout) + unsafe { fputwc(wc, &mut *stdout) } } /// See . @@ -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 . @@ -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 . @@ -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 . @@ -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 . #[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 . #[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 . @@ -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 . #[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 . #[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 . @@ -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 . #[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::()) as *mut wchar_t; + let d = unsafe { malloc((l + 1) * mem::size_of::()) } 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 . @@ -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 . #[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 . @@ -506,14 +513,14 @@ pub unsafe extern "C" fn wcschr(ws: *const wchar_t, wc: wchar_t) -> *mut wchar_t /// See . #[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 . #[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 . @@ -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 . #[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 . @@ -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 . #[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 . #[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 . #[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 . @@ -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::(), - ) as *mut wchar_t + (unsafe { + string::memcpy( + ws1 as *mut c_void, + ws2 as *const c_void, + n * mem::size_of::(), + ) + }) as *mut wchar_t } /// See . @@ -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::(), - ) as *mut wchar_t + (unsafe { + string::memmove( + ws1 as *mut c_void, + ws2 as *const c_void, + n * mem::size_of::(), + ) + }) as *mut wchar_t } /// See . #[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 . #[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 . #[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 . diff --git a/src/header/wchar/utf8.rs b/src/header/wchar/utf8.rs index c55aa930d7..31d1a8aba3 100644 --- a/src/header/wchar/utf8.rs +++ b/src/header/wchar/utf8.rs @@ -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); diff --git a/src/header/wchar/wprintf.rs b/src/header/wchar/wprintf.rs index 1925a0369b..539585dc2f 100644 --- a/src/header/wchar/wprintf.rs +++ b/src/header/wchar/wprintf.rs @@ -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::(w, format, ap).unwrap_or(-1) + unsafe { inner_printf::(w, format, ap).unwrap_or(-1) } } diff --git a/src/header/wchar/wscanf.rs b/src/header/wchar/wscanf.rs index e001322704..e284a6631a 100644 --- a/src/header/wchar/wscanf.rs +++ b/src/header/wchar/wscanf.rs @@ -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 { - 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, } From 0f23c03ba4f4bff995dbf761fc81a07269e27358 Mon Sep 17 00:00:00 2001 From: sourceturner <126549-sourceturner@users.noreply.gitlab.redox-os.org> Date: Sun, 18 Jan 2026 21:51:08 +0100 Subject: [PATCH 25/33] Use unsafe blocks in io module --- src/io/buffered.rs | 5 ++++- src/io/cursor.rs | 5 ++++- src/io/impls.rs | 9 ++++++--- src/io/mod.rs | 9 ++++++--- 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/io/buffered.rs b/src/io/buffered.rs index 001501dcaa..e0a5ab28da 100644 --- a/src/io/buffered.rs +++ b/src/io/buffered.rs @@ -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 Read for BufReader { // 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() } } } diff --git a/src/io/cursor.rs b/src/io/cursor.rs index b2179bc14f..ff229bd0ce 100644 --- a/src/io/cursor.rs +++ b/src/io/cursor.rs @@ -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() } } } diff --git a/src/io/impls.rs b/src/io/impls.rs index 80932844be..2168bc80ce 100644 --- a/src/io/impls.rs +++ b/src/io/impls.rs @@ -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 Read for Box { #[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] diff --git a/src/io/mod.rs b/src/io/mod.rs index 96c5813a17..ae4f50ab3a 100644 --- a/src/io/mod.rs +++ b/src/io/mod.rs @@ -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 Read for Chain { } 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 Read for Take { } unsafe fn initializer(&self) -> Initializer { - self.inner.initializer() + unsafe { self.inner.initializer() } } fn read_to_end(&mut self, buf: &mut Vec) -> Result { From 2d5ac472146842ee0b46b086097ceeb76cc7e787 Mon Sep 17 00:00:00 2001 From: sourceturner <126549-sourceturner@users.noreply.gitlab.redox-os.org> Date: Sun, 18 Jan 2026 21:51:33 +0100 Subject: [PATCH 26/33] Use unsafe blocks in platform module --- src/platform/allocator/mod.rs | 36 ++++++++------- src/platform/allocator/sys.rs | 19 +++++--- src/platform/linux/mod.rs | 87 ++++++++++++++++++----------------- src/platform/mod.rs | 8 +++- 4 files changed, 84 insertions(+), 66 deletions(-) diff --git a/src/platform/allocator/mod.rs b/src/platform/allocator/mod.rs index 7dddfb8adc..bee1c7628e 100644 --- a/src/platform/allocator/mod.rs +++ b/src/platform/allocator/mod.rs @@ -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::() { - (*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::() { - (*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()) } } diff --git a/src/platform/allocator/sys.rs b/src/platform/allocator/sys.rs index 55c813cec0..9b720e6395 100644 --- a/src/platform/allocator/sys.rs +++ b/src/platform/allocator/sys.rs @@ -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(); } diff --git a/src/platform/linux/mod.rs b/src/platform/linux/mod.rs index 712addf2e3..6ac8c20964 100644 --- a/src/platform/linux/mod.rs +++ b/src/platform/linux/mod.rs @@ -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::(); - 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 { 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 }) diff --git a/src/platform/mod.rs b/src/platform/mod.rs index 3b9d481de1..2427218381 100644 --- a/src/platform/mod.rs +++ b/src/platform/mod.rs @@ -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 + #[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::>(); + let mut auxvs = unsafe { auxv_iter(ptr) }.collect::>(); 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 { - 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 { auxvs From de27858da298ae400704b424078574868ffb4681 Mon Sep 17 00:00:00 2001 From: sourceturner <126549-sourceturner@users.noreply.gitlab.redox-os.org> Date: Sun, 18 Jan 2026 21:51:49 +0100 Subject: [PATCH 27/33] Use unsafe blocks in pthread module --- src/pthread/mod.rs | 79 +++++++++++++++++++++++++--------------------- 1 file changed, 43 insertions(+), 36 deletions(-) diff --git a/src/pthread/mod.rs b/src/pthread/mod.rs index 0f86adfd67..31e4263429 100644 --- a/src/pthread/mod.rs +++ b/src/pthread/mod.rs @@ -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, ) -> ! { - 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 { // 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 { // 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(()) From f6b0b3fde0aadeb7d309a002f936763b7ce3cb48 Mon Sep 17 00:00:00 2001 From: sourceturner <126549-sourceturner@users.noreply.gitlab.redox-os.org> Date: Sun, 18 Jan 2026 21:53:43 +0100 Subject: [PATCH 28/33] Use unsafe blocks in c_str.rs --- src/c_str.rs | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/c_str.rs b/src/c_str.rs index ee98f47dee..7bbf6ac6e0 100644 --- a/src/c_str.rs +++ b/src/c_str.rs @@ -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 { 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 { From 1af4be27c0a1c21fd90c585be97c03d04084ac56 Mon Sep 17 00:00:00 2001 From: sourceturner <126549-sourceturner@users.noreply.gitlab.redox-os.org> Date: Sun, 18 Jan 2026 21:54:40 +0100 Subject: [PATCH 29/33] Use unsafe blocks in c_vec.rs --- src/c_vec.rs | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/c_vec.rs b/src/c_vec.rs index 593fa0426b..423586e9b9 100644 --- a/src/c_vec.rs +++ b/src/c_vec.rs @@ -1,5 +1,8 @@ //! Equivalent of Rust's `Vec`, 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 CVec { 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) }; } } From b5291171d3dca8d6ac2802b36469bbdf6350432d Mon Sep 17 00:00:00 2001 From: sourceturner <126549-sourceturner@users.noreply.gitlab.redox-os.org> Date: Sun, 18 Jan 2026 21:55:50 +0100 Subject: [PATCH 30/33] Use unsafe blocks in macros.rs --- src/macros.rs | 73 +++++++++++++++++++++++++++------------------------ 1 file changed, 39 insertions(+), 34 deletions(-) diff --git a/src/macros.rs b/src/macros.rs index 2c988281ec..3cf348fe00 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -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 { From 0107a29e0007287839df49d8c9dfe60825f5b5a0 Mon Sep 17 00:00:00 2001 From: sourceturner <126549-sourceturner@users.noreply.gitlab.redox-os.org> Date: Sun, 18 Jan 2026 21:56:20 +0100 Subject: [PATCH 31/33] Use unsafe blocks in out.rs --- src/out.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/out.rs b/src/out.rs index 4da353ff18..47d5cc2deb 100644 --- a/src/out.rs +++ b/src/out.rs @@ -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()) } } } From 86ca639b14fe892b87c52a204d76f74dfa19fbf1 Mon Sep 17 00:00:00 2001 From: sourceturner <126549-sourceturner@users.noreply.gitlab.redox-os.org> Date: Sun, 18 Jan 2026 21:56:53 +0100 Subject: [PATCH 32/33] Use unsafe blocks in raw_cell.rs --- src/raw_cell.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/raw_cell.rs b/src/raw_cell.rs index 091bfe6662..3f311f9d6d 100644 --- a/src/raw_cell.rs +++ b/src/raw_cell.rs @@ -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 RawCell { } #[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() } } } From df5d7b2adbced00d738330fb6243ca3b8171e681 Mon Sep 17 00:00:00 2001 From: sourceturner <126549-sourceturner@users.noreply.gitlab.redox-os.org> Date: Sun, 18 Jan 2026 21:57:21 +0100 Subject: [PATCH 33/33] Use unsafe blocks in start.rs --- src/start.rs | 69 ++++++++++++++++++++++++++++------------------------ 1 file changed, 37 insertions(+), 32 deletions(-) diff --git a/src/start.rs b/src/start.rs index e576cfab3b..ae47e770ce 100644 --- a/src/start.rs +++ b/src/start.rs @@ -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!(); }