Skip to content
Snippets Groups Projects
Commit 1e6f9a7f authored by Martin Kröning's avatar Martin Kröning :crab:
Browse files

Replace c_str* functions with CStr

parent 4d5d5dac
No related branches found
No related tags found
No related merge requests found
use core::{slice, str};
use super::c_char;
/// A port of [`std::ffi::CStr`].
///
/// # Safety
///
/// Refer to [`std::ffi::CStr`].
#[repr(transparent)]
pub struct CStr {
inner: [c_char],
}
impl CStr {
pub unsafe fn from_ptr<'a>(ptr: *const c_char) -> &'a Self {
unsafe {
let len = strlen(ptr);
let ptr = ptr as *const u8;
Self::from_bytes_with_nul_unchecked(slice::from_raw_parts(ptr, len as usize + 1))
}
}
pub unsafe fn from_bytes_with_nul_unchecked(bytes: &[u8]) -> &Self {
unsafe { &*(bytes as *const [u8] as *const Self) }
}
pub fn to_bytes(&self) -> &[u8] {
let bytes = self.to_bytes_with_nul();
unsafe { bytes.get_unchecked(..bytes.len() - 1) }
}
pub fn to_bytes_with_nul(&self) -> &[u8] {
unsafe { &*(&self.inner as *const [c_char] as *const [u8]) }
}
pub fn to_str(&self) -> Result<&str, str::Utf8Error> {
str::from_utf8(self.to_bytes())
}
}
unsafe fn strlen(mut s: *const c_char) -> usize {
// SAFETY: The caller must guarantee `s` points to a valid 0-terminated string.
unsafe {
let mut n = 0;
while *s != 0 {
n += 1;
s = s.offset(1);
}
n
}
}
#![warn(unsafe_op_in_unsafe_fn)]
#[allow(non_camel_case_types)]
pub type c_char = i8;
mod c_str;
pub use c_str::CStr;
...@@ -92,6 +92,7 @@ mod console; ...@@ -92,6 +92,7 @@ mod console;
mod drivers; mod drivers;
pub mod environment; pub mod environment;
mod errno; mod errno;
mod ffi;
mod kernel_message_buffer; mod kernel_message_buffer;
mod mm; mod mm;
#[cfg(target_os = "hermit")] #[cfg(target_os = "hermit")]
......
...@@ -16,8 +16,8 @@ use crate::arch; ...@@ -16,8 +16,8 @@ use crate::arch;
use crate::console::CONSOLE; use crate::console::CONSOLE;
use crate::environment; use crate::environment;
use crate::errno::*; use crate::errno::*;
use crate::ffi::CStr;
use crate::syscalls::fs::{self, FilePerms, PosixFile, SeekWhence}; use crate::syscalls::fs::{self, FilePerms, PosixFile, SeekWhence};
use crate::util;
pub use self::generic::*; pub use self::generic::*;
pub use self::uhyve::*; pub use self::uhyve::*;
...@@ -208,12 +208,12 @@ pub trait SyscallInterface: Send + Sync { ...@@ -208,12 +208,12 @@ pub trait SyscallInterface: Send + Sync {
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
fn unlink(&self, name: *const u8) -> i32 { fn unlink(&self, name: *const u8) -> i32 {
let name = unsafe { util::c_str_to_str(name) }; let name = unsafe { CStr::from_ptr(name as _) }.to_str().unwrap();
debug!("unlink {}", name); debug!("unlink {}", name);
fs::FILESYSTEM fs::FILESYSTEM
.lock() .lock()
.unlink(&name) .unlink(name)
.expect("Unlinking failed!"); // TODO: error handling .expect("Unlinking failed!"); // TODO: error handling
0 0
} }
...@@ -230,11 +230,11 @@ pub trait SyscallInterface: Send + Sync { ...@@ -230,11 +230,11 @@ pub trait SyscallInterface: Send + Sync {
//! flags is bitmask of O_DEC_* defined above. //! flags is bitmask of O_DEC_* defined above.
//! (taken from rust stdlib/sys hermit target ) //! (taken from rust stdlib/sys hermit target )
let name = unsafe { util::c_str_to_str(name) }; let name = unsafe { CStr::from_ptr(name as _) }.to_str().unwrap();
debug!("Open {}, {}, {}", name, flags, mode); debug!("Open {}, {}, {}", name, flags, mode);
let mut fs = fs::FILESYSTEM.lock(); let mut fs = fs::FILESYSTEM.lock();
let fd = fs.open(&name, open_flags_to_perm(flags, mode as u32)); let fd = fs.open(name, open_flags_to_perm(flags, mode as u32));
if let Ok(fd) = fd { if let Ok(fd) = fd {
fd as i32 fd as i32
......
...@@ -8,25 +8,6 @@ ...@@ -8,25 +8,6 @@
use alloc::string::String; use alloc::string::String;
use alloc::vec::Vec; use alloc::vec::Vec;
/// Gets length of null terminated c string.
/// UNSAFE. Caller has to assert that string is null terminated!
pub unsafe fn c_strlen(c_str: *const u8) -> usize {
let mut off = c_str;
while *off != 0 {
off = off.offset(1);
}
off as usize - c_str as usize
}
/// Converts null terminated c string into onwed rust utf8 string.
/// TODO: panics if not utf8. return error
pub unsafe fn c_str_to_str(c_str: *const u8) -> String {
let len = c_strlen(c_str);
core::str::from_utf8(core::slice::from_raw_parts(c_str, len))
.unwrap()
.into()
}
/// Gets length of null terminated c string. Limited to buffer length. /// Gets length of null terminated c string. Limited to buffer length.
pub fn c_strbuflen(c_strbuf: &[u8]) -> usize { pub fn c_strbuflen(c_strbuf: &[u8]) -> usize {
c_strbuf c_strbuf
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment