jD91mZM2 hace 6 años
padre
commit
3bb3a3e322

+ 33 - 13
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]

+ 24 - 16
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]

+ 1 - 0
tests/Makefile

@@ -32,6 +32,7 @@ EXPECT_BINS=\
 	stdlib/system \
 	string/mem \
 	string/strchr \
+	string/strcpy \
 	string/strcspn \
 	string/strncmp \
 	string/strpbrk \

+ 0 - 0
tests/expected/string/strcpy.stderr


+ 3 - 0
tests/expected/string/strcpy.stdout

@@ -0,0 +1,3 @@
+strcpy works!
+strncpy works!
+strncpy shaaaaaaaaa

+ 17 - 0
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);
+}