diff --git a/src/header/unistd/mod.rs b/src/header/unistd/mod.rs
index b64997d0b0eb2787e42e102d05b434ca6d183249..1a8e5a905196723090ea5042e4f4f4bdb92bf2c8 100644
--- a/src/header/unistd/mod.rs
+++ b/src/header/unistd/mod.rs
@@ -4,7 +4,7 @@ use core::{convert::TryFrom, mem, ptr, slice};
 
 use crate::{
     c_str::CStr,
-    header::{errno, limits, stdlib::getenv, sys_ioctl, sys_time, termios, time::timespec},
+    header::{errno, limits, fcntl::sys::O_WRONLY, stdlib::getenv, sys_ioctl, sys_time, termios, time::timespec},
     platform::{self, types::*, Pal, Sys},
 };
 use alloc::collections::LinkedList;
@@ -647,9 +647,19 @@ pub extern "C" fn tcsetpgrp(fd: c_int, pgrp: pid_t) -> c_int {
     pgrp
 }
 
-// #[no_mangle]
+#[no_mangle]
 pub extern "C" fn truncate(path: *const c_char, length: off_t) -> c_int {
-    unimplemented!();
+    let file = unsafe { CStr::from_ptr(path) };
+    let fd = Sys::open(file, O_WRONLY, 0);
+    if fd < 0 {
+        return -1;
+    }
+
+    let res = ftruncate(fd, length);
+
+    Sys::close(fd);
+
+    res
 }
 
 #[no_mangle]
diff --git a/tests/unistd/ftruncate.c b/tests/unistd/ftruncate.c
index 63b159abb6f5a2428c6c65f8f7f2071c4173d0c9..c1b35cefa593c56031815fc6c983d649c45b8351 100644
--- a/tests/unistd/ftruncate.c
+++ b/tests/unistd/ftruncate.c
@@ -17,4 +17,8 @@ int main(void) {
     int c = close(fd);
     ERROR_IF(close, c, == -1);
     UNEXP_IF(close, c, != 0);
+
+    status = truncate("ftruncate.out", 100);
+    ERROR_IF(truncate, status, == -1);
+    UNEXP_IF(truncate, status, != 0);
 }