diff options
author | johannst <johannes.stoelp@gmail.com> | 2020-11-24 23:46:17 +0100 |
---|---|---|
committer | johannst <johannes.stoelp@gmail.com> | 2020-11-24 23:46:17 +0100 |
commit | 9e90abfdb0b1b1f270b4ae0e4f5d8742d1f2f472 (patch) | |
tree | eaf508a17c3d54206f39f6275642bd53db70680f /include | |
parent | 046fdcf0d37359c04735c0189b350757e893723c (diff) | |
download | dynld-9e90abfdb0b1b1f270b4ae0e4f5d8742d1f2f472.tar.gz dynld-9e90abfdb0b1b1f270b4ae0e4f5d8742d1f2f472.zip |
factorize printf into io.h
Diffstat (limited to 'include')
-rw-r--r-- | include/io.h | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/include/io.h b/include/io.h new file mode 100644 index 0000000..4b3ea4b --- /dev/null +++ b/include/io.h @@ -0,0 +1,43 @@ +// Copyright (c) 2020 Johannes Stoelp + +#pragma once + +#include "fmt.h" +#include "syscall.h" + +#include <asm/unistd.h> + +// `dynld_printf` uses fixed-size buffer on the stack for formating the message +// (since we don't impl buffered I/O). +// +// Size can be re-configured by defining `MAX_PRINTF_LEN` before including +// `io.h`. +// +// NOTE: This allows to specify an arbitrarily large buffer on the stack, but +// for the purpose of this study that's fine, we are cautious. +#if !defined(MAX_PRINTF_LEN) +# define MAX_PRINTF_LEN 64 +#endif + +#define FD_STDOUT 1 +#define FD_STDERR 2 + +int dynld_printf(const char* fmt, ...) { + char buf[MAX_PRINTF_LEN]; + + va_list ap; + va_start(ap, fmt); + int ret = dynld_vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + + if (ret > MAX_PRINTF_LEN - 1) { + syscall3(__NR_write, FD_STDERR, buf, MAX_PRINTF_LEN - 1); + + static const char warn[] = "\ndynld_printf: Message truncated, max length can be configured by defining MAX_PRINTF_LEN\n"; + syscall3(__NR_write, FD_STDOUT, warn, sizeof(warn)); + return MAX_PRINTF_LEN - 1; + } + + syscall3(__NR_write, FD_STDOUT, buf, ret); + return ret; +} |