2021-01-14 21:30:06 +00:00
|
|
|
#include "xsnprintf.h"
|
|
|
|
|
|
2024-09-11 20:13:30 +01:00
|
|
|
#include <errno.h>
|
2021-01-14 21:30:06 +00:00
|
|
|
#include <limits.h>
|
|
|
|
|
#include <stdio.h>
|
2021-01-15 20:39:45 +00:00
|
|
|
#include "debug.h"
|
2024-09-11 20:13:30 +01:00
|
|
|
#include "macros.h"
|
2021-01-14 21:30:06 +00:00
|
|
|
|
2024-09-11 20:13:30 +01:00
|
|
|
/*
|
|
|
|
|
* ISO C doesn't require vsnprintf(3) to set errno on failure, but
|
|
|
|
|
* POSIX does:
|
|
|
|
|
*
|
|
|
|
|
* "If an output error was encountered, these functions shall return
|
|
|
|
|
* a negative value and set errno to indicate the error."
|
|
|
|
|
*
|
|
|
|
|
* The mandated errors of interest are:
|
|
|
|
|
*
|
|
|
|
|
* - EILSEQ: A wide-character code does not correspond to a valid character
|
|
|
|
|
* - EOVERFLOW: The value of n is greater than INT_MAX
|
|
|
|
|
* - EOVERFLOW: The value to be returned is greater than INT_MAX
|
|
|
|
|
*
|
|
|
|
|
* ISO C11 states:
|
|
|
|
|
*
|
|
|
|
|
* "The vsnprintf function returns the number of characters that would
|
|
|
|
|
* have been written had n been sufficiently large, not counting the
|
|
|
|
|
* terminating null character, or a negative value if an encoding error
|
|
|
|
|
* occurred. Thus, the null-terminated output has been completely
|
|
|
|
|
* written if and only if the returned value is nonnegative and less
|
|
|
|
|
* than n."
|
|
|
|
|
*
|
|
|
|
|
* See also:
|
|
|
|
|
*
|
|
|
|
|
* - ISO C11 §7.21.6.12p3
|
|
|
|
|
* - https://pubs.opengroup.org/onlinepubs/9699919799/functions/vsnprintf.html
|
|
|
|
|
* - https://pubs.opengroup.org/onlinepubs/9699919799/functions/snprintf.html
|
|
|
|
|
*/
|
|
|
|
|
static size_t
|
|
|
|
|
xvsnprintf(char *restrict buf, size_t n, const char *restrict format, va_list ap)
|
2021-01-14 21:30:06 +00:00
|
|
|
{
|
|
|
|
|
int len = vsnprintf(buf, n, format, ap);
|
2024-09-11 20:13:30 +01:00
|
|
|
if (unlikely(len < 0 || len >= (int)n)) {
|
|
|
|
|
FATAL_ERROR(__func__, (len < 0) ? errno : ENOBUFS);
|
|
|
|
|
}
|
2021-01-14 21:30:06 +00:00
|
|
|
return (size_t)len;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
size_t
|
2024-09-11 20:13:30 +01:00
|
|
|
xsnprintf(char *restrict buf, size_t n, const char *restrict format, ...)
|
2021-01-14 21:30:06 +00:00
|
|
|
{
|
|
|
|
|
va_list ap;
|
|
|
|
|
va_start(ap, format);
|
|
|
|
|
size_t len = xvsnprintf(buf, n, format, ap);
|
|
|
|
|
va_end(ap);
|
|
|
|
|
return len;
|
|
|
|
|
}
|