From bb1e8fe8d7957566b444e6b9fb74b64bb69f03c8 Mon Sep 17 00:00:00 2001
From: Agoston Szepessy <agoston.the.dev@gmail.com>
Date: Mon, 22 Jul 2024 22:24:37 +0200
Subject: [PATCH] Implement dprintf and vdprintf

---
 src/header/stdio/mod.rs                       | 15 ++++++++++++
 tests/Makefile                                |  1 +
 .../expected/bins_static/stdio/dprintf.stderr |  0
 .../expected/bins_static/stdio/dprintf.stdout |  2 ++
 tests/stdio/dprintf.c                         | 24 +++++++++++++++++++
 5 files changed, 42 insertions(+)
 create mode 100644 tests/expected/bins_static/stdio/dprintf.stderr
 create mode 100644 tests/expected/bins_static/stdio/dprintf.stdout
 create mode 100644 tests/stdio/dprintf.c

diff --git a/src/header/stdio/mod.rs b/src/header/stdio/mod.rs
index a79f19a2..5416101e 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 37abe58d..00865b52 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 00000000..e69de29b
diff --git a/tests/expected/bins_static/stdio/dprintf.stdout b/tests/expected/bins_static/stdio/dprintf.stdout
new file mode 100644
index 00000000..e12bc872
--- /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 00000000..76601281
--- /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
-- 
GitLab