diff --git a/src/header/stdio/mod.rs b/src/header/stdio/mod.rs
index a79f19a29baa5af9ccdaafddbe6751432850e2d0..5416101ec13c216f2ebaddfb9dc9e5a24d96bdd5 100644
--- a/src/header/stdio/mod.rs
+++ b/src/header/stdio/mod.rs
@@ -1185,6 +1185,21 @@ pub unsafe extern "C" fn fprintf(
     vfprintf(file, format, __valist.as_va_list())
 }
 
+#[no_mangle]
+pub unsafe extern "C" fn vdprintf(fd: c_int, format: *const c_char, ap: va_list) -> c_int {
+    let mut f = File::new(fd);
+
+    // We don't want to close the file on drop; we're merely
+    // borrowing the file descriptor here
+    f.reference = true;
+
+    printf::printf(f, format, ap)
+}
+#[no_mangle]
+pub unsafe extern "C" fn dprintf(fd: c_int, format: *const c_char, mut __valist: ...) -> c_int {
+    vdprintf(fd, format, __valist.as_va_list())
+}
+
 #[no_mangle]
 pub unsafe extern "C" fn vprintf(format: *const c_char, ap: va_list) -> c_int {
     vfprintf(&mut *stdout, format, ap)
diff --git a/tests/Makefile b/tests/Makefile
index 636df83cc759f37430fb6311975a49435996d105..5ebaf278bfad76b9d9ade8f4486bfb9ca3f5546e 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -33,6 +33,7 @@ EXPECT_NAMES=\
 	signal \
 	stdio/all \
 	stdio/buffer \
+	stdio/dprintf \
 	stdio/fgets \
 	stdio/fputs \
 	stdio/fread \
diff --git a/tests/expected/bins_static/stdio/dprintf.stderr b/tests/expected/bins_static/stdio/dprintf.stderr
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/tests/expected/bins_static/stdio/dprintf.stdout b/tests/expected/bins_static/stdio/dprintf.stdout
new file mode 100644
index 0000000000000000000000000000000000000000..e12bc872a0105a859af557e40d49cf679e8a43cb
--- /dev/null
+++ b/tests/expected/bins_static/stdio/dprintf.stdout
@@ -0,0 +1,2 @@
+Hello, world
+a
diff --git a/tests/stdio/dprintf.c b/tests/stdio/dprintf.c
new file mode 100644
index 0000000000000000000000000000000000000000..766012818ca0bbde8f209900aa28a56f4c5aeee8
--- /dev/null
+++ b/tests/stdio/dprintf.c
@@ -0,0 +1,24 @@
+#include <stdio.h>
+#include <fcntl.h>
+
+#include "test_helpers.h"
+
+int main(void)
+{
+    int fd = open("/dev/stdout", O_WRONLY, 0222);
+    ERROR_IF(open, fd, < 0);
+
+    const char *msg = "Hello, %s";
+
+    int result = dprintf(fd, msg, "world");
+    ERROR_IF(dprintf, result, != sizeof("Hello, world") - 1);
+    UNEXP_IF(dprintf, result, < 0);
+
+    result = dprintf(fd, "\na\n");
+    UNEXP_IF(dprintf, result, < 0);
+    ERROR_IF(dprintf, result, != sizeof("\na\n") - 1);
+
+    close(fd);
+
+    return 0;
+}
\ No newline at end of file