Line | Branch | Exec | Source |
---|---|---|---|
1 | #include <errno.h> | ||
2 | #include <stdio.h> | ||
3 | #include "xsnprintf.h" | ||
4 | #include "debug.h" | ||
5 | |||
6 | /* | ||
7 | * ISO C doesn't require vsnprintf(3) to set errno on failure, but | ||
8 | * POSIX does: | ||
9 | * | ||
10 | * "If an output error was encountered, these functions shall return | ||
11 | * a negative value and set errno to indicate the error." | ||
12 | * | ||
13 | * The mandated errors of interest are: | ||
14 | * | ||
15 | * • EILSEQ: A wide-character code does not correspond to a valid character | ||
16 | * • EOVERFLOW: The value of n is greater than INT_MAX | ||
17 | * • EOVERFLOW: The value to be returned is greater than INT_MAX | ||
18 | * | ||
19 | * ISO C11 states: | ||
20 | * | ||
21 | * "The vsnprintf function returns the number of characters that would | ||
22 | * have been written had n been sufficiently large, not counting the | ||
23 | * terminating null character, or a negative value if an encoding error | ||
24 | * occurred. Thus, the null-terminated output has been completely | ||
25 | * written if and only if the returned value is nonnegative and less | ||
26 | * than n." | ||
27 | * | ||
28 | * See also: | ||
29 | * | ||
30 | * • ISO C11 §7.21.6.12p3 | ||
31 | * • https://pubs.opengroup.org/onlinepubs/9699919799/functions/vsnprintf.html | ||
32 | * • https://pubs.opengroup.org/onlinepubs/9699919799/functions/snprintf.html | ||
33 | */ | ||
34 | 5603 | size_t xvsnprintf(char *restrict buf, size_t n, const char *restrict fmt, va_list v) | |
35 | { | ||
36 | 5603 | int r = vsnprintf(buf, n, fmt, v); | |
37 |
2/4✓ Branch 0 taken 5603 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 5603 times.
|
5603 | if (unlikely(r < 0 || r >= (int)n)) { |
38 | − | fatal_error(__func__, (r < 0) ? errno : ENOBUFS); | |
39 | } | ||
40 | 5603 | return (size_t)r; | |
41 | } | ||
42 | |||
43 | 5601 | size_t xsnprintf(char *restrict buf, size_t n, const char *restrict fmt, ...) | |
44 | { | ||
45 | 5601 | va_list v; | |
46 | 5601 | va_start(v, fmt); | |
47 | 5601 | size_t r = xvsnprintf(buf, n, fmt, v); | |
48 | 5601 | va_end(v); | |
49 | 5601 | return r; | |
50 | } | ||
51 |