diff --git a/src/header/wchar/mod.rs b/src/header/wchar/mod.rs
index ce00f3d1b2c71525b2ee0fb522a297dbda2cdc04..a6bf6b3e7375ab4091e49591c24e870eb6b1ab94 100644
--- a/src/header/wchar/mod.rs
+++ b/src/header/wchar/mod.rs
@@ -360,7 +360,7 @@ pub unsafe extern "C" fn wcrtomb(s: *mut c_char, wc: wchar_t, ps: *mut mbstate_t
 pub unsafe extern "C" fn wcsdup(s: *const wchar_t) -> *mut wchar_t {
     let l = wcslen(s);
     
-    let mut d = malloc((l + 1)*mem::size_of::<wchar_t>()) as *mut wchar_t;
+    let d = malloc((l + 1)*mem::size_of::<wchar_t>()) as *mut wchar_t;
 
     if d.is_null() {
         errno = ENOMEM;
@@ -372,86 +372,16 @@ pub unsafe extern "C" fn wcsdup(s: *const wchar_t) -> *mut wchar_t {
 
 #[no_mangle]
 pub unsafe extern "C" fn wcsrtombs(
-    mut s: *mut c_char,
+    s: *mut c_char,
     ws: *mut *const wchar_t,
-    mut n: size_t,
-    st: *mut mbstate_t,
+    n: size_t,
+    mut st: *mut mbstate_t,
 ) -> size_t {
-    let mut ws2 = 0 as *const wchar_t;
-    let mut buf = [0i8; 4];
-    let N = n;
-    let mut l = 0usize;
-
-    if s.is_null() {
-        n = 0;
-        ws2 = *ws;
-        while *ws2 != 0 {
-            if *ws2 >= 0x80 {
-                l = wcrtomb(buf.as_mut_ptr(), *ws2, ptr::null_mut());
-                if l.wrapping_add(1) == 0 {
-                    return usize::MAX;
-                }
-                n = n.wrapping_add(l);
-            } else {
-                n = n.wrapping_add(1);
-            }
-            ws2 = ws2.offset(1);
-        }
-        return n;
+    let mut mbs = mbstate_t {};
+    if st.is_null() {
+        st = &mut mbs;
     }
-
-    while n >= 4 {
-        if (**ws).wrapping_sub(1) >= 0x7f {
-            if **ws == 0 {
-                *s = 0;
-                *ws = 0 as *const wchar_t;
-                return N.wrapping_sub(n);
-            }
-
-            l = wcrtomb(s, **ws, ptr::null_mut());
-            if l.wrapping_add(1) == 0 {
-                return usize::MAX;
-            }
-
-            s = s.offset(l as isize);
-            n = n.wrapping_sub(l);
-        } else {
-            let new_s = s;
-            s = s.offset(1);
-            *new_s = **ws as c_char;
-            n = n.wrapping_sub(1);
-        }
-
-        *ws = (*ws).offset(1);
-    }
-
-    while n != 0 {
-        if (**ws).wrapping_sub(1) >= 0x7f {
-            if **ws == 0 {
-                *s = 0;
-                *ws = 0 as *const wchar_t;
-                return N.wrapping_sub(n);
-            }
-            l = wcrtomb(buf.as_mut_ptr(), **ws, ptr::null_mut());
-            if l.wrapping_add(1) == 0 {
-                return usize::MAX;
-            }
-            if l > n {
-                return N.wrapping_sub(n);
-            }
-            wcrtomb(s, **ws, ptr::null_mut());
-            s = s.offset(l as isize);
-            n = n.wrapping_sub(l) as size_t;
-        } else {
-            let new_s = s;
-            s = s.offset(1);
-            *new_s = **ws as c_char;
-            n = n.wrapping_sub(1);
-        }
-        *ws = (*ws).offset(1);
-    }
-
-    return N;
+    wcsnrtombs(s, ws, size_t::MAX, n, st)
 }
 
 #[no_mangle]
@@ -610,11 +540,16 @@ pub unsafe extern "C" fn wcsnrtombs(
     src: *mut *const wchar_t,
     nwc: size_t,
     len: size_t,
-    ps: *mut mbstate_t,
+    mut ps: *mut mbstate_t,
 ) -> size_t {
     let mut written = 0;
     let mut read = 0;
     let mut buf: [c_char; MB_LEN_MAX as usize] = [0; MB_LEN_MAX as usize];
+    let mut mbs = mbstate_t {};
+
+    if ps.is_null() {
+        ps = &mut mbs;
+    }
     
     while read < nwc {
         buf.fill(0);
@@ -639,7 +574,7 @@ pub unsafe extern "C" fn wcsnrtombs(
             *src = ptr::null();
             return written;
         }
-
+        
         *src = (*src).add(1);
         read += 1;
         written += ret;
@@ -926,9 +861,9 @@ pub unsafe extern "C" fn wcstoumax(
     result
 }
 
-// #[no_mangle]
-pub extern "C" fn wcswcs(ws1: *const wchar_t, ws2: *const wchar_t) -> *mut wchar_t {
-    unimplemented!();
+#[no_mangle]
+pub unsafe extern "C" fn wcswcs(ws1: *const wchar_t, ws2: *const wchar_t) -> *mut wchar_t {
+    wcsstr(ws1, ws2)
 }
 
 #[no_mangle]
diff --git a/tests/wchar/wcsrtombs.c b/tests/wchar/wcsrtombs.c
index 53bbd8044f0c48b19a531ec9dff9bf4e64b195ef..087a8862ae4644f14abe4c96516132e17a76390c 100644
--- a/tests/wchar/wcsrtombs.c
+++ b/tests/wchar/wcsrtombs.c
@@ -12,6 +12,8 @@ int main() {
     size_t mb_len2 = wcsrtombs(NULL, &wcs2, 0, NULL);
     assert(mb_len2 == strlen("Hello, world!"));
 
+    // wcsrtombs resets wcs2 to zero, so we need to fill it again
+    wcs2 = L"Hello, world!";
     char *mbs2 = malloc(mb_len2 + 1);
     wcsrtombs(mbs2, &wcs2, mb_len2 + 1, NULL);
     assert(strcmp(mbs2, "Hello, world!") == 0);