diff --git a/src/crt0/src/lib.rs b/src/crt0/src/lib.rs index c9cc2739a4a7e877d23f07f507fb83569111d58e..2d2ce8f5eba844940b4f8fc387b688d7fb50b308 100644 --- a/src/crt0/src/lib.rs +++ b/src/crt0/src/lib.rs @@ -53,6 +53,7 @@ impl Stack { &self.argv0 as *const *const u8 } + #[cfg(not(target_os = "redox"))] fn envp(&self) -> *const *const u8 { unsafe { self.argv().offset(self.argc() + 1) } } @@ -62,30 +63,43 @@ impl Stack { #[no_mangle] pub unsafe extern "C" fn _start_rust(sp: &'static Stack) -> ! { extern "C" { + #[cfg(not(target_os = "redox"))] fn main(argc: isize, argv: *const *const c_char, envp: *const *const c_char) -> c_int; + #[cfg(target_os = "redox")] + fn main(argc: isize, argv: *const *const c_char) -> c_int; } let argc = sp.argc(); let argv = sp.argv(); - let envp = sp.envp(); - let mut len = 0; - while *envp.offset(len) != ptr::null() { - len += 1; + #[cfg(target_os = "redox")] + { + // TODO: Redox will support environ like on linux, eventually. + // We could implement it using the env: scheme here, but eh. + platform::inner_environ = Vec::with_capacity(1); } - platform::inner_environ = Vec::with_capacity(len as usize + 1); - for i in 0..len { - let mut item = *envp.offset(i); + #[cfg(not(target_os = "redox"))] + let envp = sp.envp(); + #[cfg(not(target_os = "redox"))] + { let mut len = 0; - while *item.offset(len) != 0 { + while *envp.offset(len) != ptr::null() { len += 1; } - - let buf = platform::alloc(len as usize + 1) as *mut c_char; - for i in 0..=len { - *buf.offset(i) = *item.offset(i) as c_char; + platform::inner_environ = Vec::with_capacity(len as usize + 1); + for i in 0..len { + let mut item = *envp.offset(i); + let mut len = 0; + while *item.offset(len) != 0 { + len += 1; + } + + let buf = platform::alloc(len as usize + 1) as *mut c_char; + for i in 0..=len { + *buf.offset(i) = *item.offset(i) as c_char; + } + platform::inner_environ.push(buf); } - platform::inner_environ.push(buf); } platform::inner_environ.push(ptr::null_mut()); platform::environ = platform::inner_environ.as_mut_ptr(); @@ -95,11 +109,17 @@ pub unsafe extern "C" fn _start_rust(sp: &'static Stack) -> ! { stdio::stdout = stdio::default_stdout.get(); stdio::stderr = stdio::default_stderr.get(); + #[cfg(not(target_os = "redox"))] platform::exit(main( argc, argv as *const *const c_char, envp as *const *const c_char, )); + #[cfg(target_os = "redox")] + platform::exit(main( + argc, + argv as *const *const c_char, + )); } #[panic_implementation] diff --git a/src/string/src/lib.rs b/src/string/src/lib.rs index ea9606dca60851d1e8229895ce9aaf426caf38e0..7960febbce5d49fb349247e9d3269b80959fcd25 100644 --- a/src/string/src/lib.rs +++ b/src/string/src/lib.rs @@ -150,8 +150,21 @@ pub unsafe extern "C" fn strcoll(s1: *const c_char, s2: *const c_char) -> c_int } #[no_mangle] -pub unsafe extern "C" fn strcpy(s1: *mut c_char, s2: *const c_char) -> *mut c_char { - strncpy(s1, s2, usize::MAX) +pub unsafe extern "C" fn strcpy(dst: *mut c_char, src: *const c_char) -> *mut c_char { + let mut i = 0; + + loop { + let byte = *src.offset(i); + *dst.offset(i) = byte; + + if byte == 0 { + break; + } + + i += 1; + } + + dst } pub unsafe fn inner_strspn(s1: *const c_char, s2: *const c_char, cmp: bool) -> size_t { @@ -270,24 +283,19 @@ pub unsafe extern "C" fn strncmp(s1: *const c_char, s2: *const c_char, n: usize) } #[no_mangle] -pub unsafe extern "C" fn strncpy(s1: *mut c_char, s2: *const c_char, n: usize) -> *mut c_char { - let s2_slice = platform::c_str_n(s2, n); - let s2_len = s2_slice.len(); - - //memcpy(s1 as *mut _, s2 as *const _, cmp::min(n, s2_len)); - let mut idx = 0; - for _ in 0..cmp::min(n, s2_len) { - *s1.offset(idx as isize) = s2_slice[idx] as c_char; - idx += 1; +pub unsafe extern "C" fn strncpy(dst: *mut c_char, src: *const c_char, n: usize) -> *mut c_char { + let mut i = 0; + + while *src.offset(i) != 0 && (i as usize) < n { + *dst.offset(i) = *src.offset(i); + i += 1; } - // if length of s2 < n, pad s1 with zeroes - while idx < s2_len { - *s1.offset(idx as isize) = 0; - idx += 1; + for i in i..n as isize { + *dst.offset(i) = 0; } - s1 + dst } #[no_mangle] diff --git a/tests/Makefile b/tests/Makefile index 82bd1f8074973bf2615fa84edd505e41738ab1a8..de3e0b85b5b2ae29fcd3223d6d9c3bc2b765ab8d 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -32,6 +32,7 @@ EXPECT_BINS=\ stdlib/system \ string/mem \ string/strchr \ + string/strcpy \ string/strcspn \ string/strncmp \ string/strpbrk \ diff --git a/tests/expected/string/strcpy.stderr b/tests/expected/string/strcpy.stderr new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/tests/expected/string/strcpy.stdout b/tests/expected/string/strcpy.stdout new file mode 100644 index 0000000000000000000000000000000000000000..84caf120d631da5d3ad544722fa9360c41029fc2 --- /dev/null +++ b/tests/expected/string/strcpy.stdout @@ -0,0 +1,3 @@ +strcpy works! +strncpy works! +strncpy shaaaaaaaaa diff --git a/tests/string/strcpy.c b/tests/string/strcpy.c new file mode 100644 index 0000000000000000000000000000000000000000..f0c7d792590ccd67b2a6057e8c009715f3429e09 --- /dev/null +++ b/tests/string/strcpy.c @@ -0,0 +1,17 @@ +#include <stdio.h> +#include <string.h> + +int main() { + char dst[20]; + + strcpy(dst, "strcpy works!"); + puts(dst); + strncpy(dst, "strncpy works!", 20); + puts(dst); + + // Make sure no NUL is placed + memset(dst, 'a', 20); + dst[19] = 0; + strncpy(dst, "strncpy should work here too", 10); + puts(dst); +}