diff --git a/src/header/stdio/default.rs b/src/header/stdio/default.rs
index b86115e2d6f33caf73831d1704aee07ad360c87e..90aa709b025c848085fdbe4110debd96f74bcfb4 100644
--- a/src/header/stdio/default.rs
+++ b/src/header/stdio/default.rs
@@ -21,6 +21,8 @@ impl GlobalFile {
             writer,
 
             pid: None,
+
+            orientation: 0,
         }))
     }
     pub fn get(&self) -> *mut FILE {
diff --git a/src/header/stdio/helpers.rs b/src/header/stdio/helpers.rs
index 6d5d9da8414e1dcb7bb84153a978ca08a296c3a6..be7aa9fa0bb83cd3c203c8aca6d296e4d34ec384 100644
--- a/src/header/stdio/helpers.rs
+++ b/src/header/stdio/helpers.rs
@@ -76,5 +76,7 @@ pub unsafe fn _fdopen(fd: c_int, mode: *const c_char) -> Option<*mut FILE> {
         writer,
 
         pid: None,
+
+        orientation: 0,
     })))
 }
diff --git a/src/header/stdio/mod.rs b/src/header/stdio/mod.rs
index 7693cd2157255e5cce08876fbaa9f5b9f4ea907d..b6c9c916a71a62e962a02e51e719d3e5220de525 100644
--- a/src/header/stdio/mod.rs
+++ b/src/header/stdio/mod.rs
@@ -9,7 +9,7 @@ use core::{
     cmp,
     ffi::VaList as va_list,
     fmt::{self, Write as WriteFmt},
-    mem,
+    i32, mem,
     ops::{Deref, DerefMut},
     ptr, slice, str,
 };
@@ -85,6 +85,9 @@ pub struct FILE {
 
     // Optional pid for use with popen/pclose
     pid: Option<c_int>,
+
+    // wchar support
+    pub(crate) orientation: c_int,
 }
 
 impl Read for FILE {
@@ -169,6 +172,18 @@ impl FILE {
         }
         LockGuard(self)
     }
+
+    pub fn try_set_orientation(&mut self, mode: c_int) -> c_int {
+        let mut stream = self.lock();
+        if stream.0.orientation == 0 {
+            stream.0.orientation = match mode {
+                1..=i32::MAX => 1,
+                i32::MIN..=-1 => -1,
+                0 => stream.0.orientation,
+            };
+        }
+        stream.0.orientation
+    }
 }
 
 pub struct LockGuard<'a>(&'a mut FILE);
diff --git a/src/header/wchar/mod.rs b/src/header/wchar/mod.rs
index 4c4a281bbd97a1e4f3736176b87d48be8fdc2de5..cde6a5e85bbaccabe79fd808e5b5e7828bbc8f3a 100644
--- a/src/header/wchar/mod.rs
+++ b/src/header/wchar/mod.rs
@@ -89,9 +89,9 @@ pub unsafe extern "C" fn fputws(ws: *const wchar_t, stream: *mut FILE) -> c_int
     }
 }
 
-// #[no_mangle]
-pub extern "C" fn fwide(stream: *mut FILE, mode: c_int) -> c_int {
-    unimplemented!();
+#[no_mangle]
+pub unsafe extern "C" fn fwide(stream: *mut FILE, mode: c_int) -> c_int {
+    (*stream).try_set_orientation(mode)
 }
 
 #[no_mangle]
diff --git a/src/platform/types.rs b/src/platform/types.rs
index 85e3ba3aafbb9ca64627ba4ebc70baccb106552d..5d604d383a0f3e8a995aaad7c7a8f05caab30c7b 100644
--- a/src/platform/types.rs
+++ b/src/platform/types.rs
@@ -1,3 +1,5 @@
+use core::i32;
+
 // Use repr(u8) as LLVM expects `void*` to be the same as `i8*` to help enable
 // more optimization opportunities around it recognizing things like
 // malloc/free.
diff --git a/tests/Makefile b/tests/Makefile
index fde26810307dc8de69790d4f76e1e7e619577db7..a1f07bb9a2e11141e64e18a217e716132b0cd32f 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -100,6 +100,7 @@ EXPECT_NAMES=\
 	unistd/swab \
 	unistd/write \
 	waitpid \
+	wchar/fwide \
 	wchar/mbrtowc \
 	wchar/mbsrtowcs \
 	wchar/printf-on-wchars \
diff --git a/tests/expected/wchar/fwide.stderr b/tests/expected/wchar/fwide.stderr
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/tests/expected/wchar/fwide.stdout b/tests/expected/wchar/fwide.stdout
new file mode 100644
index 0000000000000000000000000000000000000000..bb0b1cf658d18a1b6001d4344351d3abd3829104
--- /dev/null
+++ b/tests/expected/wchar/fwide.stdout
@@ -0,0 +1,3 @@
+0
+0
+0
diff --git a/tests/wchar/fwide.c b/tests/wchar/fwide.c
new file mode 100644
index 0000000000000000000000000000000000000000..4338d02c36eaedd4eb0754c4f66fd7c1683f30da
--- /dev/null
+++ b/tests/wchar/fwide.c
@@ -0,0 +1,47 @@
+#include <assert.h>
+#include <stdio.h>
+#include <wchar.h>
+
+int test_initial_orientation(void) {
+	FILE *f = tmpfile();
+	assert(fwide(f, 0) == 0);
+	return 0;
+}
+
+int test_manual_byte_orientation(void) {
+	FILE *f = tmpfile();
+
+	// set manually to byte orientation
+	assert(fwide(f, -483) == -1);
+
+	// Cannot change to wchar orientation
+	assert(fwide(f, 1) == -1);
+
+	fclose(f);
+	return 0;
+}
+
+int test_manual_wchar_orientation(void) {
+	FILE *f = tmpfile();
+
+	// set manually to wchar orientation
+	assert(fwide(f, 483) == 1);
+
+	// Cannot change to byte orientation
+	assert(fwide(f, -1) == 1);
+
+	fclose(f);
+	return 0;
+}
+
+int main() {
+	int(*tests[])(void) = {
+		&test_initial_orientation,
+		&test_manual_byte_orientation,
+		&test_manual_wchar_orientation,
+	};
+	for(int i=0; i<sizeof(tests)/sizeof(int(*)(void)); i++) {
+		printf("%d\n", (*tests[i])());
+	}
+}
+