Merge branch 'use-cstr-literals-minimal' into 'master'

Use C string literals & deprecate `c_str!`

See merge request redox-os/relibc!625
This commit is contained in:
Jeremy Soller
2025-03-16 17:56:05 +00:00
19 changed files with 88 additions and 88 deletions
+10 -1
View File
@@ -51,7 +51,7 @@ impl<'a> CStr<'a> {
pub fn to_string_lossy(self) -> Cow<'a, str> {
String::from_utf8_lossy(self.to_bytes())
}
pub fn as_ptr(self) -> *const c_char {
pub const fn as_ptr(self) -> *const c_char {
self.ptr.as_ptr()
}
pub const unsafe fn from_bytes_with_nul_unchecked(bytes: &'a [u8]) -> Self {
@@ -82,6 +82,15 @@ impl<'a> CStr<'a> {
unsafe impl Send for CStr<'_> {}
unsafe impl Sync for CStr<'_> {}
impl From<&core::ffi::CStr> for CStr<'_> {
fn from(s: &core::ffi::CStr) -> Self {
// SAFETY:
// * We can assume that `s` is valid because the caller should have upheld its
// safety concerns when constructing it.
unsafe { Self::from_ptr(s.as_ptr()) }
}
}
#[derive(Debug)]
pub struct FromBytesWithNulError;
+1 -1
View File
@@ -27,7 +27,7 @@ pub const RTLD_LOCAL: c_int = 0x0000;
pub const RTLD_DEFAULT: *mut c_void = 0 as *mut c_void; // XXX: cbindgen doesn't like ptr::null_mut()
static ERROR_NOT_SUPPORTED: CStr = c_str!("dlfcn not supported");
static ERROR_NOT_SUPPORTED: &core::ffi::CStr = c"dlfcn not supported";
#[thread_local]
static ERROR: AtomicUsize = AtomicUsize::new(0);
+1 -1
View File
@@ -58,7 +58,7 @@ pub unsafe extern "C" fn getopt_long(
|| *current_arg.offset(1) == 0
} {
-1
} else if unsafe { string::strcmp(current_arg, c_str!("--").as_ptr()) == 0 } {
} else if unsafe { string::strcmp(current_arg, c"--".as_ptr()) == 0 } {
unsafe {
optind += 1;
}
+14 -14
View File
@@ -253,7 +253,7 @@ fn parse_grp(line: String, destbuf: Option<DestBuffer>) -> Result<OwnedGrp, Erro
// MT-Unsafe race:grgid locale
#[no_mangle]
pub unsafe extern "C" fn getgrgid(gid: gid_t) -> *mut group {
let Ok(db) = File::open(c_str!("/etc/group"), fcntl::O_RDONLY) else {
let Ok(db) = File::open(c"/etc/group".into(), fcntl::O_RDONLY) else {
return ptr::null_mut();
};
@@ -270,13 +270,13 @@ pub unsafe extern "C" fn getgrgid(gid: gid_t) -> *mut group {
}
}
return ptr::null_mut();
ptr::null_mut()
}
// MT-Unsafe race:grnam locale
#[no_mangle]
pub unsafe extern "C" fn getgrnam(name: *const c_char) -> *mut group {
let Ok(db) = File::open(c_str!("/etc/group"), fcntl::O_RDONLY) else {
let Ok(db) = File::open(c"/etc/group".into(), fcntl::O_RDONLY) else {
return ptr::null_mut();
};
@@ -301,7 +301,7 @@ pub unsafe extern "C" fn getgrnam(name: *const c_char) -> *mut group {
}
}
return ptr::null_mut();
ptr::null_mut()
}
// MT-Safe locale
@@ -318,7 +318,7 @@ pub unsafe extern "C" fn getgrgid_r(
*result = ptr::null_mut();
}
let Ok(db) = File::open(c_str!("/etc/group"), fcntl::O_RDONLY) else {
let Ok(db) = File::open(c"/etc/group".into(), fcntl::O_RDONLY) else {
return ENOENT;
};
@@ -360,7 +360,7 @@ pub unsafe extern "C" fn getgrgid_r(
}
// The requested entry was not found.
return 0;
0
}
// MT-Safe locale
@@ -372,7 +372,7 @@ pub unsafe extern "C" fn getgrnam_r(
buflen: usize,
result: *mut *mut group,
) -> c_int {
let Ok(db) = File::open(c_str!("/etc/group"), fcntl::O_RDONLY) else {
let Ok(db) = File::open(c"/etc/group".into(), fcntl::O_RDONLY) else {
return ENOENT;
};
@@ -404,7 +404,7 @@ pub unsafe extern "C" fn getgrnam_r(
}
}
return ENOENT;
ENOENT
}
// MT-Unsafe race:grent race:grentbuf locale
@@ -413,7 +413,7 @@ pub unsafe extern "C" fn getgrent() -> *mut group {
let mut line_reader = unsafe { &mut *LINE_READER.get() };
if line_reader.is_none() {
let Ok(db) = File::open(c_str!("/etc/group"), fcntl::O_RDONLY) else {
let Ok(db) = File::open(c"/etc/group".into(), fcntl::O_RDONLY) else {
return ptr::null_mut();
};
*line_reader = Some(BufReader::new(db).lines());
@@ -428,12 +428,12 @@ pub unsafe extern "C" fn getgrent() -> *mut group {
};
if let Ok(grp) = parse_grp(line, None) {
return grp.into_global();
grp.into_global()
} else {
return ptr::null_mut();
ptr::null_mut()
}
} else {
return ptr::null_mut();
ptr::null_mut()
}
}
@@ -449,7 +449,7 @@ pub unsafe extern "C" fn endgrent() {
#[no_mangle]
pub unsafe extern "C" fn setgrent() {
let mut line_reader = unsafe { &mut *LINE_READER.get() };
let Ok(db) = File::open(c_str!("/etc/group"), fcntl::O_RDONLY) else {
let Ok(db) = File::open(c"/etc/group".into(), fcntl::O_RDONLY) else {
return;
};
*line_reader = Some(BufReader::new(db).lines());
@@ -475,7 +475,7 @@ pub unsafe extern "C" fn getgrouplist(
return 0;
};
let Ok(db) = File::open(c_str!("/etc/group"), fcntl::O_RDONLY) else {
let Ok(db) = File::open(c"/etc/group".into(), fcntl::O_RDONLY) else {
return 0;
};
+2 -2
View File
@@ -46,7 +46,7 @@ pub unsafe extern "C" fn endhostent() {
pub unsafe extern "C" fn sethostent(stayopen: c_int) {
HOST_STAYOPEN = stayopen;
if HOSTDB < 0 {
HOSTDB = Sys::open(c_str!("/etc/hosts"), O_RDONLY, 0).or_minus_one_errno()
HOSTDB = Sys::open(c"/etc/hosts".into(), O_RDONLY, 0).or_minus_one_errno()
} else {
Sys::lseek(HOSTDB, 0, SEEK_SET);
}
@@ -56,7 +56,7 @@ pub unsafe extern "C" fn sethostent(stayopen: c_int) {
#[no_mangle]
pub unsafe extern "C" fn gethostent() -> *mut hostent {
if HOSTDB < 0 {
HOSTDB = Sys::open(c_str!("/etc/hosts"), O_RDONLY, 0).or_minus_one_errno();
HOSTDB = Sys::open(c"/etc/hosts".into(), O_RDONLY, 0).or_minus_one_errno();
}
let mut rlb = RawLineBuffer::new(HOSTDB);
rlb.seek(H_POS);
+1 -1
View File
@@ -7,7 +7,7 @@ use crate::{
use alloc::string::String;
pub fn get_dns_server() -> String {
let file = match File::open(c_str!("/etc/resolv.conf"), fcntl::O_RDONLY) {
let file = match File::open(c"/etc/resolv.conf".into(), fcntl::O_RDONLY) {
Ok(file) => file,
Err(_) => return String::new(), // TODO: better error handling
};
+27 -27
View File
@@ -439,7 +439,7 @@ pub unsafe extern "C" fn getnetent() -> *mut netent {
// TODO: Rustify implementation
if NETDB == 0 {
NETDB = Sys::open(c_str!("/etc/networks"), O_RDONLY, 0).or_minus_one_errno();
NETDB = Sys::open(c"/etc/networks".into(), O_RDONLY, 0).or_minus_one_errno();
}
let mut rlb = RawLineBuffer::new(NETDB);
@@ -548,7 +548,7 @@ pub unsafe extern "C" fn getprotobynumber(number: c_int) -> *mut protoent {
#[no_mangle]
pub unsafe extern "C" fn getprotoent() -> *mut protoent {
if PROTODB == 0 {
PROTODB = Sys::open(c_str!("/etc/protocols"), O_RDONLY, 0).or_minus_one_errno();
PROTODB = Sys::open(c"/etc/protocols".into(), O_RDONLY, 0).or_minus_one_errno();
}
let mut rlb = RawLineBuffer::new(PROTODB);
@@ -665,7 +665,7 @@ pub unsafe extern "C" fn getservbyport(port: c_int, proto: *const c_char) -> *mu
pub unsafe extern "C" fn getservent() -> *mut servent {
if SERVDB == 0 {
// TODO: Rustify
SERVDB = Sys::open(c_str!("/etc/services"), O_RDONLY, 0).or_minus_one_errno();
SERVDB = Sys::open(c"/etc/services".into(), O_RDONLY, 0).or_minus_one_errno();
}
let mut rlb = RawLineBuffer::new(SERVDB);
rlb.seek(S_POS);
@@ -749,7 +749,7 @@ pub unsafe extern "C" fn getservent() -> *mut servent {
pub unsafe extern "C" fn setnetent(stayopen: c_int) {
NET_STAYOPEN = stayopen;
if NETDB == 0 {
NETDB = Sys::open(c_str!("/etc/networks"), O_RDONLY, 0).or_minus_one_errno()
NETDB = Sys::open(c"/etc/networks".into(), O_RDONLY, 0).or_minus_one_errno()
} else {
Sys::lseek(NETDB, 0, SEEK_SET);
N_POS = 0;
@@ -760,7 +760,7 @@ pub unsafe extern "C" fn setnetent(stayopen: c_int) {
pub unsafe extern "C" fn setprotoent(stayopen: c_int) {
PROTO_STAYOPEN = stayopen;
if PROTODB == 0 {
PROTODB = Sys::open(c_str!("/etc/protocols"), O_RDONLY, 0).or_minus_one_errno()
PROTODB = Sys::open(c"/etc/protocols".into(), O_RDONLY, 0).or_minus_one_errno()
} else {
Sys::lseek(PROTODB, 0, SEEK_SET);
P_POS = 0;
@@ -771,7 +771,7 @@ pub unsafe extern "C" fn setprotoent(stayopen: c_int) {
pub unsafe extern "C" fn setservent(stayopen: c_int) {
SERV_STAYOPEN = stayopen;
if SERVDB == 0 {
SERVDB = Sys::open(c_str!("/etc/services"), O_RDONLY, 0).or_minus_one_errno()
SERVDB = Sys::open(c"/etc/services".into(), O_RDONLY, 0).or_minus_one_errno()
} else {
Sys::lseek(SERVDB, 0, SEEK_SET);
S_POS = 0;
@@ -925,21 +925,21 @@ pub unsafe extern "C" fn freeaddrinfo(res: *mut addrinfo) {
}
#[no_mangle]
pub extern "C" fn gai_strerror(errcode: c_int) -> *const c_char {
pub const extern "C" fn gai_strerror(errcode: c_int) -> *const c_char {
match errcode {
EAI_BADFLAGS => c_str!("Invalid flags"),
EAI_NONAME => c_str!("Name does not resolve"),
EAI_AGAIN => c_str!("Try again"),
EAI_FAIL => c_str!("Non-recoverable error"),
EAI_NODATA => c_str!("Unknown error"),
EAI_FAMILY => c_str!("Unrecognized address family or invalid length"),
EAI_SOCKTYPE => c_str!("Unrecognized socket type"),
EAI_SERVICE => c_str!("Unrecognized service"),
EAI_ADDRFAMILY => c_str!("Address family for name not supported"),
EAI_MEMORY => c_str!("Out of memory"),
EAI_SYSTEM => c_str!("System error"),
EAI_OVERFLOW => c_str!("Overflow"),
_ => c_str!("Unknown error"),
EAI_BADFLAGS => c"Invalid flags",
EAI_NONAME => c"Name does not resolve",
EAI_AGAIN => c"Try again",
EAI_FAIL => c"Non-recoverable error",
EAI_NODATA => c"Unknown error",
EAI_FAMILY => c"Unrecognized address family or invalid length",
EAI_SOCKTYPE => c"Unrecognized socket type",
EAI_SERVICE => c"Unrecognized service",
EAI_ADDRFAMILY => c"Address family for name not supported",
EAI_MEMORY => c"Out of memory",
EAI_SYSTEM => c"System error",
EAI_OVERFLOW => c"Overflow",
_ => c"Unknown error",
}
.as_ptr()
}
@@ -953,14 +953,14 @@ pub extern "C" fn __h_errno_location() -> *mut c_int {
#[no_mangle]
#[deprecated]
pub extern "C" fn hstrerror(errcode: c_int) -> *const c_char {
pub const extern "C" fn hstrerror(errcode: c_int) -> *const c_char {
match errcode {
H_UNSET => c_str!("Resolver error unset"),
HOST_NOT_FOUND => c_str!("Unknown hostname"),
NO_DATA => c_str!("No address for hostname"),
NO_RECOVERY => c_str!("Unknown server error"),
TRY_AGAIN => c_str!("Hostname lookup failure"),
_ => c_str!("Unknown error"),
H_UNSET => c"Resolver error unset",
HOST_NOT_FOUND => c"Unknown hostname",
NO_DATA => c"No address for hostname",
NO_RECOVERY => c"Unknown server error",
TRY_AGAIN => c"Hostname lookup failure",
_ => c"Unknown error",
}
.as_ptr()
}
+1 -1
View File
@@ -3,7 +3,7 @@ use alloc::string::String;
pub fn get_dns_server() -> String {
let mut string = String::new();
let mut file = File::open(c_str!("/etc/net/dns"), fcntl::O_RDONLY).unwrap(); // TODO: error handling
let mut file = File::open(c"/etc/net/dns".into(), fcntl::O_RDONLY).unwrap(); // TODO: error handling
file.read_to_string(&mut string).unwrap(); // TODO: error handling
string
}
+1 -1
View File
@@ -8,7 +8,7 @@ pub(super) unsafe fn openpty(name: &mut [u8]) -> Result<(c_int, c_int), ()> {
const O_NOCTTY: c_int = 0x100;
//TODO: wrap in auto-close struct
let master = fcntl::open(c_str!("/dev/ptmx").as_ptr(), fcntl::O_RDWR | O_NOCTTY, 0);
let master = fcntl::open(c"/dev/ptmx".as_ptr(), fcntl::O_RDWR | O_NOCTTY, 0);
if master < 0 {
return Err(());
}
+1 -1
View File
@@ -6,7 +6,7 @@ use crate::{
};
pub(super) unsafe fn openpty(name: &mut [u8]) -> Result<(c_int, c_int), ()> {
let master = fcntl::open(c_str!("/scheme/pty").as_ptr(), fcntl::O_RDWR, 0);
let master = fcntl::open(c"/scheme/pty".as_ptr(), fcntl::O_RDWR, 0);
if master < 0 {
return Err(());
}
+2 -2
View File
@@ -181,7 +181,7 @@ fn pwd_lookup<F>(mut matches: F, destination: Option<DestBuffer>) -> Result<Owne
where
F: FnMut(&passwd) -> bool,
{
let file = match File::open(c_str!("/etc/passwd"), fcntl::O_RDONLY) {
let file = match File::open(c"/etc/passwd".into(), fcntl::O_RDONLY) {
Ok(file) => file,
Err(_) => return Err(Cause::Other),
};
@@ -233,7 +233,7 @@ pub extern "C" fn getpwent() -> *mut passwd {
let reader = match unsafe { &mut READER } {
Some(reader) => reader,
None => {
let file = match File::open(c_str!("/etc/passwd"), fcntl::O_RDONLY) {
let file = match File::open(c"/etc/passwd".into(), fcntl::O_RDONLY) {
Ok(file) => file,
Err(_) => return ptr::null_mut(),
};
+4 -4
View File
@@ -938,12 +938,12 @@ pub unsafe extern "C" fn popen(command: *const c_char, mode: *const c_char) -> *
unreachable!();
} else if child_pid > 0 {
let (fd, fd_mode) = if write {
let (fd, fd_mode): (_, CStr) = if write {
unistd::close(pipes[0]);
(pipes[1], if cloexec { c_str!("we") } else { c_str!("w") })
(pipes[1], if cloexec { c"we".into() } else { c"w".into() })
} else {
unistd::close(pipes[1]);
(pipes[0], if cloexec { c_str!("re") } else { c_str!("r") })
(pipes[0], if cloexec { c"re".into() } else { c"r".into() })
};
if let Some(f) = helpers::_fdopen(fd, fd_mode.as_ptr()) {
@@ -1136,7 +1136,7 @@ pub unsafe extern "C" fn tmpfile() -> *mut FILE {
return ptr::null_mut();
}
let fp = fdopen(fd, c_str!("w+").as_ptr());
let fp = fdopen(fd, c"w+".as_ptr());
{
let file_name = CStr::from_ptr(file_name);
Sys::unlink(file_name);
+1 -1
View File
@@ -14,7 +14,7 @@ use crate::{
use crate::platform::types::*;
fn getpass_rs(prompt: CStr, passbuff: &mut [u8]) -> Result<*mut c_char, io::Error> {
let mut f = File::open(c_str!("/dev/tty"), O_RDWR | O_CLOEXEC)?;
let mut f = File::open(c"/dev/tty".into(), O_RDWR | O_CLOEXEC)?;
let mut term = termios::termios::default();
+3 -3
View File
@@ -169,13 +169,13 @@ pub unsafe extern "C" fn crypt(key: *const c_char, salt: *const c_char) -> *mut
#[no_mangle]
pub extern "C" fn daemon(nochdir: c_int, noclose: c_int) -> c_int {
if nochdir == 0 {
if Sys::chdir(c_str!("/")).map(|()| 0).or_minus_one_errno() < 0 {
if Sys::chdir(c"/".into()).map(|()| 0).or_minus_one_errno() < 0 {
return -1;
}
}
if noclose == 0 {
let fd = Sys::open(c_str!("/dev/null"), fcntl::O_RDWR, 0).or_minus_one_errno();
let fd = Sys::open(c"/dev/null".into(), fcntl::O_RDWR, 0).or_minus_one_errno();
if fd < 0 {
return -1;
}
@@ -303,7 +303,7 @@ pub unsafe extern "C" fn execvp(file: *const c_char, argv: *const *mut c_char) -
} else {
let mut error = errno::ENOENT;
let path_env = getenv(c_str!("PATH\0").as_ptr());
let path_env = getenv(c"PATH".as_ptr());
if !path_env.is_null() {
let path_env = CStr::from_ptr(path_env);
for path in path_env.to_bytes().split(|&b| b == PATH_SEPARATOR) {
+7 -7
View File
@@ -55,21 +55,21 @@ pub enum DlError {
impl DlError {
/// Returns a human-readable, null-terminated C string describing the error.
pub fn repr(&self) -> CStr<'static> {
pub const fn repr(&self) -> &'static core::ffi::CStr {
match self {
DlError::NotFound => c_str!(
"Failed to locate the requested DSO. Set `LD_DEBUG=all` for more information."
),
DlError::NotFound => {
c"Failed to locate the requested DSO. Set `LD_DEBUG=all` for more information."
}
DlError::Malformed => {
c_str!("The DSO is malformed somehow. Set `LD_DEBUG=all` for more information.")
c"The DSO is malformed somehow. Set `LD_DEBUG=all` for more information."
}
DlError::InvalidHandle => {
c_str!("Invalid DSO handle. Set `LD_DEBUG=all` for more information.")
c"Invalid DSO handle. Set `LD_DEBUG=all` for more information."
}
DlError::Oom => c_str!("Out of memory."),
DlError::Oom => c"Out of memory.",
}
}
}
-10
View File
@@ -1,13 +1,3 @@
#[macro_export]
macro_rules! c_str {
($lit:expr) => {
#[allow(unused_unsafe)]
unsafe {
$crate::c_str::CStr::from_bytes_with_nul_unchecked(concat!($lit, "\0").as_bytes())
}
};
}
/// Print to stdout
#[macro_export]
macro_rules! print {
+2 -2
View File
@@ -53,7 +53,7 @@ fn event_flags_to_epoll(flags: syscall::EventFlags) -> c_uint {
impl PalEpoll for Sys {
fn epoll_create1(flags: c_int) -> Result<c_int, Errno> {
Sys::open(c_str!("/scheme/event"), O_RDWR | flags, 0)
Sys::open(c"/scheme/event".into(), O_RDWR | flags, 0)
}
unsafe fn epoll_ctl(
@@ -106,7 +106,7 @@ impl PalEpoll for Sys {
}
let timer_opt = if timeout != -1 {
let mut timer = File::open(c_str!("/scheme/time/4"), O_RDWR)?;
let mut timer = File::open(c"/scheme/time/4".into(), O_RDWR)?;
Sys::write(
epfd,
&Event {
+3 -3
View File
@@ -850,7 +850,7 @@ impl Pal for Sys {
let session_id = Self::getpid();
assert!(session_id >= 0);
let mut file = File::open(
c_str!("/scheme/thisproc/current/session_id"),
c"/scheme/thisproc/current/session_id".into(),
fcntl::O_WRONLY | fcntl::O_CLOEXEC,
)?;
file.write(&usize::to_ne_bytes(session_id.try_into().unwrap()))
@@ -902,7 +902,7 @@ impl Pal for Sys {
return Ok(());
}
let mut file = File::open(c_str!("/etc/hostname"), fcntl::O_RDONLY | fcntl::O_CLOEXEC)?;
let mut file = File::open(c"/etc/hostname".into(), fcntl::O_RDONLY | fcntl::O_CLOEXEC)?;
let mut read = 0;
let name_len = name.len();
@@ -926,7 +926,7 @@ impl Pal for Sys {
Err(_) => return Err(Errno(EIO)),
}
let file_path = c_str!("/scheme/sys/uname");
let file_path = c"/scheme/sys/uname".into();
let mut file = match File::open(file_path, fcntl::O_RDONLY | fcntl::O_CLOEXEC) {
Ok(ok) => ok,
Err(_) => return Err(Errno(EIO)),
+7 -6
View File
@@ -11,13 +11,14 @@ fn access() {
use crate::header::unistd;
//TODO: create test files
assert_eq!(Sys::access(c_str!("not a file!"), unistd::F_OK), !0);
assert_eq!(Sys::access(c_str!("README.md"), unistd::F_OK), 0);
assert_eq!(Sys::access(c_str!("README.md"), unistd::R_OK), 0);
assert_eq!(Sys::access(c_str!("README.md"), unistd::W_OK), 0);
assert_eq!(Sys::access(c_str!("README.md"), unistd::X_OK), !0);
assert_eq!(Sys::access(c"not a file!".into(), unistd::F_OK), !0);
assert_eq!(Sys::access(c"README.md".into(), unistd::F_OK), 0);
assert_eq!(Sys::access(c"README.md".into(), unistd::R_OK), 0);
assert_eq!(Sys::access(c"README.md".into(), unistd::W_OK), 0);
assert_eq!(Sys::access(c"README.md".into(), unistd::X_OK), !0);
}
// FIXME: Test needs rewriting so it compiles
#[test]
fn brk() {
use core::ptr;
@@ -33,7 +34,7 @@ fn brk() {
#[test]
fn chdir() {
//TODO: create test files
assert_eq!(Sys::chdir(c_str!("src")), 0);
assert_eq!(Sys::chdir(c"src".into()), 0);
}
//TODO: chmod