diff options
-rw-r--r-- | build/has/dprintf.c | 8 | ||||
-rw-r--r-- | build/header.mk | 1 | ||||
-rw-r--r-- | src/diag.c | 19 |
3 files changed, 25 insertions, 3 deletions
diff --git a/build/has/dprintf.c b/build/has/dprintf.c new file mode 100644 index 0000000..c206fa3 --- /dev/null +++ b/build/has/dprintf.c @@ -0,0 +1,8 @@ +// Copyright © Tavian Barnes <tavianator@tavianator.com> +// SPDX-License-Identifier: 0BSD + +#include <stdio.h> + +int main(void) { + return dprintf(1, "%s\n", "Hello world!"); +} diff --git a/build/header.mk b/build/header.mk index 6a63221..f8aee4b 100644 --- a/build/header.mk +++ b/build/header.mk @@ -21,6 +21,7 @@ HEADERS := \ gen/has/builtin-riscv-pause.h \ gen/has/compound-literal-storage.h \ gen/has/confstr.h \ + gen/has/dprintf.h \ gen/has/extattr-get-file.h \ gen/has/extattr-get-link.h \ gen/has/extattr-list-file.h \ @@ -14,13 +14,26 @@ #include <stdarg.h> #include <stdio.h> #include <stdlib.h> +#include <unistd.h> + +/** + * Print an error using dprintf() if possible, because it's more likely to be + * async-signal-safe in practice. + */ +#if BFS_HAS_DPRINTF +# define eprintf(...) dprintf(STDERR_FILENO, __VA_ARGS__) +# define veprintf(...) vdprintf(STDERR_FILENO, __VA_ARGS__) +#else +# define eprintf(...) fprintf(stderr, __VA_ARGS__) +# define veprintf(...) vfprintf(stderr, __VA_ARGS__) +#endif /** bfs_diagf() implementation. */ _printf(2, 0) static void bfs_vdiagf(const struct bfs_loc *loc, const char *format, va_list args) { - fprintf(stderr, "%s: %s@%s:%d: ", xgetprogname(), loc->func, loc->file, loc->line); - vfprintf(stderr, format, args); - fprintf(stderr, "\n"); + eprintf("%s: %s@%s:%d: ", xgetprogname(), loc->func, loc->file, loc->line); + veprintf(format, args); + eprintf("\n"); } void bfs_diagf(const struct bfs_loc *loc, const char *format, ...) { |