diff --git a/AK/kstdio.h b/AK/kstdio.h index 78ca52bc9a6..98f69caeb2a 100644 --- a/AK/kstdio.h +++ b/AK/kstdio.h @@ -37,6 +37,7 @@ int vdbgprintf(const char* fmt, va_list); int dbgprintf(const char* fmt, ...); ssize_t dbgputstr(const char*, ssize_t); int sprintf(char* buf, const char* fmt, ...); +int snprintf(char* buffer, size_t, const char* fmt, ...); } # endif #else diff --git a/Kernel/kprintf.cpp b/Kernel/kprintf.cpp index 3e2eff5b04c..6834ce00bd0 100644 --- a/Kernel/kprintf.cpp +++ b/Kernel/kprintf.cpp @@ -144,6 +144,34 @@ int sprintf(char* buffer, const char* fmt, ...) return ret; } +static size_t __vsnprintf_space_remaining; +ALWAYS_INLINE void sized_buffer_putch(char*& bufptr, char ch) +{ + if (__vsnprintf_space_remaining) { + *bufptr++ = ch; + --__vsnprintf_space_remaining; + } +} + +int snprintf(char* buffer, size_t size, const char* fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + if (size) { + __vsnprintf_space_remaining = size - 1; + } else { + __vsnprintf_space_remaining = 0; + } + int ret = printf_internal(sized_buffer_putch, buffer, fmt, ap); + if (__vsnprintf_space_remaining) { + buffer[ret] = '\0'; + } else if (size > 0) { + buffer[size - 1] = '\0'; + } + va_end(ap); + return ret; +} + static void debugger_out(char ch) { if (serial_debug) diff --git a/Kernel/kstdio.h b/Kernel/kstdio.h index b6f3d17cf96..32f3b1adda3 100644 --- a/Kernel/kstdio.h +++ b/Kernel/kstdio.h @@ -34,6 +34,7 @@ int dbgputstr(const char*, int); int kernelputstr(const char*, int); int kprintf(const char* fmt, ...); int sprintf(char* buf, const char* fmt, ...); +int snprintf(char* buf, size_t, const char* fmt, ...); void set_serial_debug(bool on_or_off); int get_serial_debug(); }