diff --git a/libc/file.cc b/libc/file.cc
index 97d0b90e716d966aaa0dade22f0c7ea65ad3f356..d0c27c9f2a35a0e2f939bee543521c922313a975 100644
--- a/libc/file.cc
+++ b/libc/file.cc
@@ -61,6 +61,27 @@ FILE* fopen(const char* fname, const char* fmode)
     return new std_file(fd);
 }
 
+char *fgets(char *s, int size, FILE *stream)
+{
+    char* orig = s;
+    while (size > 1) {
+        int r = ::read(stream->_fileno, s, 1);
+        assert(r != -1);
+        if (r == 0) {
+            break;
+        }
+        ++s;
+        --size;
+        if (s[-1] == '\n') {
+            break;
+        }
+    }
+    if (size) {
+        *s = '\0';
+    }
+    return s == orig ? nullptr : orig;
+}
+
 DIR* opendir(const char* fname)
 {
     auto f = rootfs->open(fname);
diff --git a/runtime.cc b/runtime.cc
index 631db5d018d4c7c9c5eec3a3dbb57f9783726e8c..93132cabe917582ec580cf4e6fc09bfc1cde1f8c 100644
--- a/runtime.cc
+++ b/runtime.cc
@@ -402,11 +402,6 @@ int fgetc(FILE *stream)
     UNIMPLEMENTED("fgetc");
 }
 
-char *fgets(char *s, int size, FILE *stream)
-{
-    UNIMPLEMENTED("fgets");
-}
-
 #undef getc
 int getc(FILE *stream)
 {