This commit is contained in:
nora 2023-10-08 11:25:39 +02:00
parent 9e2cf38cd5
commit 8d1795ad1a
8 changed files with 126 additions and 5 deletions

1
.envrc Normal file
View file

@ -0,0 +1 @@
use nix

View file

@ -73,8 +73,8 @@ fn getenv_inner(mut envp: EnvP, name: SharedThinCstr<'_>) -> Option<SharedThinCs
let mut env_iter = env.into_iter();
eq_idx = 0;
loop {
let name = name_iter.next().map(|c| c as u8);
let env = env_iter.next().map(|c| c as u8);
let name = name_iter.next().map(|c| c);
let env = env_iter.next().map(|c| c);
if let (None, Some(b'=')) = (name, env) {
return true;
}

View file

@ -40,7 +40,7 @@ pub use println;
use self::fd::Fd;
pub unsafe fn sys_read(fd: Fd, buf: &mut [u8]) -> Result<usize, Error> {
syscall::syscall!(syscall::SYS_READ, fd.0, buf.as_ptr(), buf.len()).syscall_resultify()
syscall::syscall!(syscall::SYS_READ, fd.0, buf.as_mut_ptr(), buf.len()).syscall_resultify()
}
pub unsafe fn sys_write(fd: Fd, buf: &[u8]) -> Result<usize, Error> {

View file

@ -1,3 +1,5 @@
use crate::utils::SharedThinCstr;
#[inline]
pub unsafe fn memset(ptr: *mut u8, constant: u8, len: usize) {
for i in 0..len {
@ -56,6 +58,17 @@ pub unsafe fn memcmp(s1: *const u8, s2: *const u8, size: usize) -> i32 {
0
}
#[inline]
pub unsafe fn strcmp(s1: SharedThinCstr<'_>, s2: SharedThinCstr<'_>) -> i32 {
s1.into_iter().cmp(s2) as i8 as i32
}
// This technically violates the safety precondition of SharedThinCstr but that's fine, we're careful.
#[inline]
pub unsafe fn strncmp(s1: SharedThinCstr<'_>, s2: SharedThinCstr<'_>, size: usize) -> i32 {
s1.into_iter().take(size).cmp(s2.into_iter().take(size)) as i8 as i32
}
#[inline]
pub unsafe fn strlen(mut s: *const u8) -> usize {
let mut len = 0;
@ -68,6 +81,8 @@ pub unsafe fn strlen(mut s: *const u8) -> usize {
#[cfg(test)]
mod tests {
use crate::{cstr, utils::SharedThinCstr};
#[test]
fn memcpy_null() {
unsafe { super::memcpy(std::ptr::null_mut(), std::ptr::null_mut(), 0) };
@ -204,6 +219,95 @@ mod tests {
assert_eq!(result, 1);
}
#[test]
fn strcmp_empty() {
let a = cstr!("");
let b = cstr!("");
let result = unsafe { super::strcmp(a, b) };
assert_eq!(result, 0);
}
#[test]
fn strcmp_against_empty() {
let a = cstr!("aa");
let b = cstr!("");
let result = unsafe { super::strcmp(a, b) };
assert_eq!(result, 1);
}
#[test]
fn strcmp_against_empty_rev() {
let a = cstr!("");
let b = cstr!("aa");
let result = unsafe { super::strcmp(a, b) };
assert_eq!(result, -1);
}
#[test]
fn strcmp_equal_len() {
let a = cstr!("00");
let b = cstr!("11");
let result = unsafe { super::strcmp(a, b) };
assert_eq!(result, -1);
}
#[test]
fn strcmp_equal_len_rev() {
let a = cstr!("11");
let b = cstr!("00");
let result = unsafe { super::strcmp(a, b) };
assert_eq!(result, 1);
}
#[test]
fn strncmp_empty() {
let a = cstr!("");
let b = cstr!("");
let result = unsafe { super::strncmp(a, b, 10) };
assert_eq!(result, 0);
}
#[test]
fn strncmp_no_null_term() {
// Note: this is violating the safety invariant of SharedThinCstr but thats fine, we're careful.
let a = unsafe { SharedThinCstr::from_raw(b"0000".as_ptr()) };
let b = unsafe { SharedThinCstr::from_raw(b"0001".as_ptr()) };
let result = unsafe { super::strncmp(a, b, 4) };
assert_eq!(result, -1);
}
#[test]
fn strncmp_against_empty() {
let a = cstr!("aa");
let b = cstr!("");
let result = unsafe { super::strncmp(a, b, 2) };
assert_eq!(result, 1);
}
#[test]
fn strncmp_against_empty_rev() {
let a = cstr!("");
let b = cstr!("aa");
let result = unsafe { super::strncmp(a, b, 2) };
assert_eq!(result, -1);
}
#[test]
fn strncmp_equal_len() {
let a = cstr!("00");
let b = cstr!("11");
let result = unsafe { super::strncmp(a, b, 2) };
assert_eq!(result, -1);
}
#[test]
fn strncmp_equal_len_rev() {
let a = cstr!("11");
let b = cstr!("00");
let result = unsafe { super::strncmp(a, b, 2) };
assert_eq!(result, 1);
}
#[test]
fn strlen_empty() {
let str = b"\0";

View file

@ -73,7 +73,7 @@ impl<'a> Iterator for CStrIter<'a> {
}
self.0 = self.0.add(1);
Some(c as u8)
Some(c)
}
}
}

View file

@ -1,4 +1,4 @@
use libuwuc::error::Error;
use libuwuc::{error::Error, utils::SharedThinCstr};
#[no_mangle]
pub unsafe extern "C" fn memset(ptr: *mut u8, constant: u8, len: usize) {
@ -25,6 +25,17 @@ pub unsafe extern "C" fn bcmp(s1: *const u8, s2: *const u8, size: usize) -> i32
libuwuc::mem::memcmp(s1, s2, size)
}
#[no_mangle]
pub unsafe extern "C" fn strcmp(s1: SharedThinCstr<'_>, s2: SharedThinCstr<'_>) -> i32 {
libuwuc::mem::strcmp(s1, s2)
}
// This technically violates the safety precondition of SharedThinCstr but that's fine, we're careful.
#[no_mangle]
pub unsafe extern "C" fn strncmp(s1: SharedThinCstr<'_>, s2: SharedThinCstr<'_>, n: usize) -> i32 {
libuwuc::mem::strncmp(s1, s2, n)
}
#[no_mangle]
pub unsafe extern "C" fn strlen(s: *const u8) -> usize {
libuwuc::mem::strlen(s)

View file

@ -3,6 +3,10 @@
rustup
gcc
clang_16
# for building things
gnumake
];
shellHook = ''
export PATH=$PATH:''${CARGO_HOME:-~/.cargo}/bin

View file

@ -16,3 +16,4 @@ ensure_cloned() {
ensure_cloned "https://github.com/tsoding/noed.git" "tsoding_noed" "1c2bd182139080a8448a59589e8d457a7019d553"
ensure_cloned "https://github.com/zesterer/tosh.git" "zest_tosh" "fa43ee9ec01a625f6a96cb48662f6c8911d8cc8c"
ensure_cloned "https://github.com/tsoding/ebisp.git" "tsoding_ebisp" "1f522883ac99b5fdcd310cccc2b03e73a281f962"