Browse Source

Merge branch 'strerror_r' into 'master'

Add POSIX strerror_r

See merge request redox-os/relibc!207
jD91mZM2 6 years ago
parent
commit
601cb43f6c
3 changed files with 32 additions and 1 deletions
  1. 19 0
      src/header/string/mod.rs
  2. 11 1
      tests/error.c
  3. 2 0
      tests/expected/error.stdout

+ 19 - 0
src/header/string/mod.rs

@@ -259,6 +259,25 @@ pub unsafe extern "C" fn strerror(errnum: c_int) -> *mut c_char {
     strerror_buf.as_mut_ptr() as *mut c_char
 }
 
+#[no_mangle]
+pub unsafe extern "C" fn strerror_r(
+    errnum: c_int,
+    buf: *mut c_char,
+    buflen: size_t,
+) -> c_int {
+    let msg = strerror(errnum);
+    let len = strlen(msg);
+
+    if len >= buflen {
+        memcpy(buf as *mut c_void, msg as *const c_void, buflen - 1);
+        *buf.add(buflen - 1) = 0;
+        return ERANGE as c_int;
+    }
+    memcpy(buf as *mut c_void, msg as *const c_void, len + 1);
+
+    0
+}
+
 #[no_mangle]
 pub unsafe extern "C" fn strlen(s: *const c_char) -> size_t {
     strnlen(s, usize::MAX)

+ 11 - 1
tests/error.c

@@ -7,6 +7,16 @@
 
 int main(void) {
     chdir("nonexistent");
-    printf("errno: %d = %s\n", errno, strerror(errno));
+    int err = errno;
+
+    printf("errno: %d = %s\n", err, strerror(errno));
     perror("perror");
+
+    char buf1[256];
+    int ret1 = strerror_r(err, buf1, 256);
+    printf("errno: %d = %s, return: %d\n", err, buf1, ret1);
+
+    char buf2[3];
+    int ret2 = strerror_r(err, buf2, 3);
+    printf("errno: %d = %s, return: %d\n", err, buf2, ret2);
 }

+ 2 - 0
tests/expected/error.stdout

@@ -1 +1,3 @@
 errno: 2 = No such file or directory
+errno: 2 = No such file or directory, return: 0
+errno: 2 = No, return: 34