diff --git a/src/header/wchar/mod.rs b/src/header/wchar/mod.rs
index 52655c061d4ae673d0cbea8c3a1b26a826854140..514666110e0fecb05f77933cbc827acebdb4c7d9 100644
--- a/src/header/wchar/mod.rs
+++ b/src/header/wchar/mod.rs
@@ -4,9 +4,10 @@ use core::{char, ffi::VaList as va_list, mem, ptr, slice, usize};
 
 use crate::{
     header::{
-        ctype::isspace, errno::ERANGE, stdio::*, stdlib::MB_CUR_MAX, string, time::*, wctype::*,
+        ctype::isspace, errno::{ERANGE, EILSEQ}, stdio::*, 
+        stdlib::MB_CUR_MAX, string, time::*, wctype::*,
     },
-    platform::{self, types::*},
+    platform::{self, errno, types::*},
 };
 
 mod utf8;
@@ -38,8 +39,45 @@ pub unsafe extern "C" fn btowc(c: c_int) -> wint_t {
 
 #[no_mangle]
 pub unsafe extern "C" fn fgetwc(stream: *mut FILE) -> wint_t {
-    //TODO: Real multibyte
-    btowc(fgetc(stream))
+    // TODO: Process locale
+    let mut buf: [c_uchar; MB_CUR_MAX as usize] = [0; MB_CUR_MAX as usize];
+    let mut encoded_length = 0;
+    let mut bytes_read = 0;
+    let mut wc: wchar_t = 0;
+
+    loop {
+        let nread = fread(buf[bytes_read..bytes_read+1].as_mut_ptr() as *mut c_void, 1, 1, stream);
+        
+        if nread != 1 {
+            errno = EILSEQ;
+            return WEOF;
+        }
+
+        bytes_read += 1;
+
+        if bytes_read == 1 {
+            encoded_length = if buf[0] >> 7 == 0 {
+                1
+            } else if buf[0] >> 5 == 6 {
+                2
+            } else if buf[0] >> 4 == 0xe {
+                3
+            } else if buf[0] >> 3 == 0x1e {
+                4
+            } else {
+                errno = EILSEQ;
+                return WEOF;
+            };
+        }
+
+        if bytes_read >= encoded_length {
+            break;
+        }
+    }
+
+    mbrtowc(&mut wc, buf.as_ptr() as *const c_char, encoded_length, ptr::null_mut());
+
+    wc as wint_t
 }
 
 #[no_mangle]
diff --git a/tests/expected/bins_static/wchar/fgetwc.stderr b/tests/expected/bins_static/wchar/fgetwc.stderr
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/tests/expected/bins_static/wchar/fgetwc.stdout b/tests/expected/bins_static/wchar/fgetwc.stdout
new file mode 100644
index 0000000000000000000000000000000000000000..e7cabf537eb68c3c10a494f39fc28b1009114358
--- /dev/null
+++ b/tests/expected/bins_static/wchar/fgetwc.stdout
@@ -0,0 +1,3 @@
+êçã
+こんにちは世界
+Привет мир
\ No newline at end of file
diff --git a/tests/wchar/fgetwc.c b/tests/wchar/fgetwc.c
new file mode 100644
index 0000000000000000000000000000000000000000..1aeeff16ffc1f3f0231bf8be9be6a2c3a9bcdcbd
--- /dev/null
+++ b/tests/wchar/fgetwc.c
@@ -0,0 +1,19 @@
+#include <stdio.h>
+#include <wchar.h>
+#include <locale.h>
+
+int main(void)
+{
+    setlocale(LC_ALL, "");
+    wint_t wc;
+    FILE *fp = fopen("wchar/fgetwc.in", "r");
+    if (!fp) {
+        return 1;
+    }
+
+    while (WEOF != (wc = fgetwc(fp)))                      
+      printf("%lc", wc);
+
+    fclose(fp);
+    return 0;
+}
diff --git a/tests/wchar/fgetwc.in b/tests/wchar/fgetwc.in
new file mode 100644
index 0000000000000000000000000000000000000000..e7cabf537eb68c3c10a494f39fc28b1009114358
--- /dev/null
+++ b/tests/wchar/fgetwc.in
@@ -0,0 +1,3 @@
+êçã
+こんにちは世界
+Привет мир
\ No newline at end of file