Change the printing mahine used by BIO_printf() and friends so it can
handle an externally provided "static" buffer as well a a dynamic buffer. The "static" buffer is filled first, but if overflowed, the dynamic buffer is used instead, being allocated somewhere i the heap. This combines the benefits of putting the output in a preallocated buffer (on the stack, for example) and in a buffer that grows somewhere in the heap.
This commit is contained in:
parent
47770c4dfb
commit
827dbcb150
@ -113,24 +113,15 @@
|
|||||||
#define LLONG long
|
#define LLONG long
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void fmtstr (void (*)(char **, size_t *, size_t *, int),
|
static void fmtstr (char **, char **, size_t *, size_t *,
|
||||||
char **, size_t *, size_t *, const char *, int, int,
|
const char *, int, int, int);
|
||||||
int);
|
static void fmtint (char **, char **, size_t *, size_t *,
|
||||||
static void fmtint (void (*)(char **, size_t *, size_t *, int),
|
LLONG, int, int, int, int);
|
||||||
char **, size_t *, size_t *, LLONG, int, int, int, int);
|
static void fmtfp (char **, char **, size_t *, size_t *,
|
||||||
static void fmtfp (void (*)(char **, size_t *, size_t *, int),
|
LDOUBLE, int, int, int);
|
||||||
char **, size_t *, size_t *, LDOUBLE, int, int, int);
|
static void doapr_outch (char **, char **, size_t *, size_t *, int);
|
||||||
static int dopr_isbig (size_t, size_t);
|
static void _dopr(char **sbuffer, char **buffer,
|
||||||
static int dopr_copy (size_t);
|
size_t *maxlen, size_t *retlen, int *truncated,
|
||||||
static void dopr_outch (char **, size_t *, size_t *, int);
|
|
||||||
#ifdef USE_ALLOCATING_PRINT
|
|
||||||
static int doapr_isbig (size_t, size_t);
|
|
||||||
static int doapr_copy (size_t);
|
|
||||||
static void doapr_outch (char **, size_t *, size_t *, int);
|
|
||||||
#endif
|
|
||||||
static void _dopr(void (*)(char **, size_t *, size_t *, int),
|
|
||||||
int (*)(size_t, size_t), int (*)(size_t),
|
|
||||||
char **buffer, size_t *maxlen, size_t *retlen, int *truncated,
|
|
||||||
const char *format, va_list args);
|
const char *format, va_list args);
|
||||||
|
|
||||||
/* format read states */
|
/* format read states */
|
||||||
@ -162,40 +153,9 @@ static void _dopr(void (*)(char **, size_t *, size_t *, int),
|
|||||||
#define char_to_int(p) (p - '0')
|
#define char_to_int(p) (p - '0')
|
||||||
#define MAX(p,q) ((p >= q) ? p : q)
|
#define MAX(p,q) ((p >= q) ? p : q)
|
||||||
|
|
||||||
#ifndef USE_ALLOCATING_PRINT
|
|
||||||
static void
|
|
||||||
dopr(
|
|
||||||
char *buffer,
|
|
||||||
size_t maxlen,
|
|
||||||
size_t *retlen,
|
|
||||||
const char *format,
|
|
||||||
va_list args)
|
|
||||||
{
|
|
||||||
int ignored;
|
|
||||||
_dopr(dopr_outch, dopr_isbig, dopr_copy,
|
|
||||||
&buffer, &maxlen, retlen, &ignored, format, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
static void
|
|
||||||
doapr(
|
|
||||||
char **buffer,
|
|
||||||
size_t *retlen,
|
|
||||||
const char *format,
|
|
||||||
va_list args)
|
|
||||||
{
|
|
||||||
size_t dummy_maxlen = 0;
|
|
||||||
int ignored;
|
|
||||||
_dopr(doapr_outch, doapr_isbig, doapr_copy,
|
|
||||||
buffer, &dummy_maxlen, retlen, &ignored, format, args);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_dopr(
|
_dopr(
|
||||||
void (*outch_fn)(char **, size_t *, size_t *, int),
|
char **sbuffer,
|
||||||
int (*isbig_fn)(size_t, size_t),
|
|
||||||
int (*copy_fn)(size_t),
|
|
||||||
char **buffer,
|
char **buffer,
|
||||||
size_t *maxlen,
|
size_t *maxlen,
|
||||||
size_t *retlen,
|
size_t *retlen,
|
||||||
@ -220,7 +180,7 @@ _dopr(
|
|||||||
ch = *format++;
|
ch = *format++;
|
||||||
|
|
||||||
while (state != DP_S_DONE) {
|
while (state != DP_S_DONE) {
|
||||||
if ((ch == '\0') || (*isbig_fn)(currlen, *maxlen))
|
if (ch == '\0' || (buffer == NULL && currlen >= *maxlen))
|
||||||
state = DP_S_DONE;
|
state = DP_S_DONE;
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
@ -228,7 +188,7 @@ _dopr(
|
|||||||
if (ch == '%')
|
if (ch == '%')
|
||||||
state = DP_S_FLAGS;
|
state = DP_S_FLAGS;
|
||||||
else
|
else
|
||||||
(*outch_fn)(buffer, &currlen, maxlen, ch);
|
doapr_outch(sbuffer,buffer, &currlen, maxlen, ch);
|
||||||
ch = *format++;
|
ch = *format++;
|
||||||
break;
|
break;
|
||||||
case DP_S_FLAGS:
|
case DP_S_FLAGS:
|
||||||
@ -334,7 +294,7 @@ _dopr(
|
|||||||
value = va_arg(args, int);
|
value = va_arg(args, int);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
fmtint(outch_fn, buffer, &currlen, maxlen,
|
fmtint(sbuffer, buffer, &currlen, maxlen,
|
||||||
value, 10, min, max, flags);
|
value, 10, min, max, flags);
|
||||||
break;
|
break;
|
||||||
case 'X':
|
case 'X':
|
||||||
@ -360,7 +320,7 @@ _dopr(
|
|||||||
unsigned int);
|
unsigned int);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
fmtint(outch_fn, buffer, &currlen, maxlen, value,
|
fmtint(sbuffer, buffer, &currlen, maxlen, value,
|
||||||
ch == 'o' ? 8 : (ch == 'u' ? 10 : 16),
|
ch == 'o' ? 8 : (ch == 'u' ? 10 : 16),
|
||||||
min, max, flags);
|
min, max, flags);
|
||||||
break;
|
break;
|
||||||
@ -369,7 +329,7 @@ _dopr(
|
|||||||
fvalue = va_arg(args, LDOUBLE);
|
fvalue = va_arg(args, LDOUBLE);
|
||||||
else
|
else
|
||||||
fvalue = va_arg(args, double);
|
fvalue = va_arg(args, double);
|
||||||
fmtfp(outch_fn, buffer, &currlen, maxlen,
|
fmtfp(sbuffer, buffer, &currlen, maxlen,
|
||||||
fvalue, min, max, flags);
|
fvalue, min, max, flags);
|
||||||
break;
|
break;
|
||||||
case 'E':
|
case 'E':
|
||||||
@ -389,19 +349,23 @@ _dopr(
|
|||||||
fvalue = va_arg(args, double);
|
fvalue = va_arg(args, double);
|
||||||
break;
|
break;
|
||||||
case 'c':
|
case 'c':
|
||||||
(*outch_fn)(buffer, &currlen, maxlen,
|
doapr_outch(sbuffer, buffer, &currlen, maxlen,
|
||||||
va_arg(args, int));
|
va_arg(args, int));
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
strvalue = va_arg(args, char *);
|
strvalue = va_arg(args, char *);
|
||||||
if (max < 0)
|
if (max < 0) {
|
||||||
max = (*copy_fn)(*maxlen);
|
if (buffer)
|
||||||
fmtstr(outch_fn, buffer, &currlen, maxlen, strvalue,
|
max = INT_MAX;
|
||||||
|
else
|
||||||
|
max = *maxlen;
|
||||||
|
}
|
||||||
|
fmtstr(sbuffer, buffer, &currlen, maxlen, strvalue,
|
||||||
flags, min, max);
|
flags, min, max);
|
||||||
break;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
value = (long)va_arg(args, void *);
|
value = (long)va_arg(args, void *);
|
||||||
fmtint(outch_fn, buffer, &currlen, maxlen,
|
fmtint(sbuffer, buffer, &currlen, maxlen,
|
||||||
value, 16, min, max, flags);
|
value, 16, min, max, flags);
|
||||||
break;
|
break;
|
||||||
case 'n': /* XXX */
|
case 'n': /* XXX */
|
||||||
@ -424,7 +388,7 @@ _dopr(
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '%':
|
case '%':
|
||||||
(*outch_fn)(buffer, &currlen, maxlen, ch);
|
doapr_outch(sbuffer, buffer, &currlen, maxlen, ch);
|
||||||
break;
|
break;
|
||||||
case 'w':
|
case 'w':
|
||||||
/* not supported yet, treat as next char */
|
/* not supported yet, treat as next char */
|
||||||
@ -448,14 +412,14 @@ _dopr(
|
|||||||
*truncated = (currlen > *maxlen - 1);
|
*truncated = (currlen > *maxlen - 1);
|
||||||
if (*truncated)
|
if (*truncated)
|
||||||
currlen = *maxlen - 1;
|
currlen = *maxlen - 1;
|
||||||
(*buffer)[currlen] = '\0';
|
doapr_outch(sbuffer, buffer, &currlen, maxlen, '\0');
|
||||||
*retlen = currlen;
|
*retlen = currlen - 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fmtstr(
|
fmtstr(
|
||||||
void (*outch_fn)(char **, size_t *, size_t *, int),
|
char **sbuffer,
|
||||||
char **buffer,
|
char **buffer,
|
||||||
size_t *currlen,
|
size_t *currlen,
|
||||||
size_t *maxlen,
|
size_t *maxlen,
|
||||||
@ -478,16 +442,16 @@ fmtstr(
|
|||||||
padlen = -padlen;
|
padlen = -padlen;
|
||||||
|
|
||||||
while ((padlen > 0) && (cnt < max)) {
|
while ((padlen > 0) && (cnt < max)) {
|
||||||
(*outch_fn)(buffer, currlen, maxlen, ' ');
|
doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
|
||||||
--padlen;
|
--padlen;
|
||||||
++cnt;
|
++cnt;
|
||||||
}
|
}
|
||||||
while (*value && (cnt < max)) {
|
while (*value && (cnt < max)) {
|
||||||
(*outch_fn)(buffer, currlen, maxlen, *value++);
|
doapr_outch(sbuffer, buffer, currlen, maxlen, *value++);
|
||||||
++cnt;
|
++cnt;
|
||||||
}
|
}
|
||||||
while ((padlen < 0) && (cnt < max)) {
|
while ((padlen < 0) && (cnt < max)) {
|
||||||
(*outch_fn)(buffer, currlen, maxlen, ' ');
|
doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
|
||||||
++padlen;
|
++padlen;
|
||||||
++cnt;
|
++cnt;
|
||||||
}
|
}
|
||||||
@ -495,7 +459,7 @@ fmtstr(
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
fmtint(
|
fmtint(
|
||||||
void (*outch_fn)(char **, size_t *, size_t *, int),
|
char **sbuffer,
|
||||||
char **buffer,
|
char **buffer,
|
||||||
size_t *currlen,
|
size_t *currlen,
|
||||||
size_t *maxlen,
|
size_t *maxlen,
|
||||||
@ -552,28 +516,28 @@ fmtint(
|
|||||||
|
|
||||||
/* spaces */
|
/* spaces */
|
||||||
while (spadlen > 0) {
|
while (spadlen > 0) {
|
||||||
(*outch_fn)(buffer, currlen, maxlen, ' ');
|
doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
|
||||||
--spadlen;
|
--spadlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* sign */
|
/* sign */
|
||||||
if (signvalue)
|
if (signvalue)
|
||||||
(*outch_fn)(buffer, currlen, maxlen, signvalue);
|
doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue);
|
||||||
|
|
||||||
/* zeros */
|
/* zeros */
|
||||||
if (zpadlen > 0) {
|
if (zpadlen > 0) {
|
||||||
while (zpadlen > 0) {
|
while (zpadlen > 0) {
|
||||||
(*outch_fn)(buffer, currlen, maxlen, '0');
|
doapr_outch(sbuffer, buffer, currlen, maxlen, '0');
|
||||||
--zpadlen;
|
--zpadlen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* digits */
|
/* digits */
|
||||||
while (place > 0)
|
while (place > 0)
|
||||||
(*outch_fn)(buffer, currlen, maxlen, convert[--place]);
|
doapr_outch(sbuffer, buffer, currlen, maxlen, convert[--place]);
|
||||||
|
|
||||||
/* left justified spaces */
|
/* left justified spaces */
|
||||||
while (spadlen < 0) {
|
while (spadlen < 0) {
|
||||||
(*outch_fn)(buffer, currlen, maxlen, ' ');
|
doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
|
||||||
++spadlen;
|
++spadlen;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@ -612,7 +576,7 @@ round(LDOUBLE value)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
fmtfp(
|
fmtfp(
|
||||||
void (*outch_fn)(char **, size_t *, size_t *, int),
|
char **sbuffer,
|
||||||
char **buffer,
|
char **buffer,
|
||||||
size_t *currlen,
|
size_t *currlen,
|
||||||
size_t *maxlen,
|
size_t *maxlen,
|
||||||
@ -693,117 +657,85 @@ fmtfp(
|
|||||||
|
|
||||||
if ((flags & DP_F_ZERO) && (padlen > 0)) {
|
if ((flags & DP_F_ZERO) && (padlen > 0)) {
|
||||||
if (signvalue) {
|
if (signvalue) {
|
||||||
(*outch_fn)(buffer, currlen, maxlen, signvalue);
|
doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue);
|
||||||
--padlen;
|
--padlen;
|
||||||
signvalue = 0;
|
signvalue = 0;
|
||||||
}
|
}
|
||||||
while (padlen > 0) {
|
while (padlen > 0) {
|
||||||
(*outch_fn)(buffer, currlen, maxlen, '0');
|
doapr_outch(sbuffer, buffer, currlen, maxlen, '0');
|
||||||
--padlen;
|
--padlen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (padlen > 0) {
|
while (padlen > 0) {
|
||||||
(*outch_fn)(buffer, currlen, maxlen, ' ');
|
doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
|
||||||
--padlen;
|
--padlen;
|
||||||
}
|
}
|
||||||
if (signvalue)
|
if (signvalue)
|
||||||
(*outch_fn)(buffer, currlen, maxlen, signvalue);
|
doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue);
|
||||||
|
|
||||||
while (iplace > 0)
|
while (iplace > 0)
|
||||||
(*outch_fn)(buffer, currlen, maxlen, iconvert[--iplace]);
|
doapr_outch(sbuffer, buffer, currlen, maxlen, iconvert[--iplace]);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Decimal point. This should probably use locale to find the correct
|
* Decimal point. This should probably use locale to find the correct
|
||||||
* char to print out.
|
* char to print out.
|
||||||
*/
|
*/
|
||||||
if (max > 0) {
|
if (max > 0) {
|
||||||
(*outch_fn)(buffer, currlen, maxlen, '.');
|
doapr_outch(sbuffer, buffer, currlen, maxlen, '.');
|
||||||
|
|
||||||
while (fplace > 0)
|
while (fplace > 0)
|
||||||
(*outch_fn)(buffer, currlen, maxlen, fconvert[--fplace]);
|
doapr_outch(sbuffer, buffer, currlen, maxlen, fconvert[--fplace]);
|
||||||
}
|
}
|
||||||
while (zpadlen > 0) {
|
while (zpadlen > 0) {
|
||||||
(*outch_fn)(buffer, currlen, maxlen, '0');
|
doapr_outch(sbuffer, buffer, currlen, maxlen, '0');
|
||||||
--zpadlen;
|
--zpadlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (padlen < 0) {
|
while (padlen < 0) {
|
||||||
(*outch_fn)(buffer, currlen, maxlen, ' ');
|
doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
|
||||||
++padlen;
|
++padlen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
dopr_copy(
|
|
||||||
size_t len)
|
|
||||||
{
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef USE_ALLOCATING_PRINT
|
|
||||||
static int
|
|
||||||
doapr_copy(
|
|
||||||
size_t len)
|
|
||||||
{
|
|
||||||
/* Return as high an integer as possible */
|
|
||||||
return INT_MAX;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int
|
|
||||||
dopr_isbig(
|
|
||||||
size_t currlen,
|
|
||||||
size_t maxlen)
|
|
||||||
{
|
|
||||||
return currlen > maxlen;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef USE_ALLOCATING_PRINT
|
|
||||||
static int
|
|
||||||
doapr_isbig(
|
|
||||||
size_t currlen,
|
|
||||||
size_t maxlen)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void
|
|
||||||
dopr_outch(
|
|
||||||
char **buffer,
|
|
||||||
size_t *currlen,
|
|
||||||
size_t *maxlen,
|
|
||||||
int c)
|
|
||||||
{
|
|
||||||
if (*currlen < *maxlen)
|
|
||||||
(*buffer)[(*currlen)++] = (char)c;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef USE_ALLOCATING_PRINT
|
|
||||||
static void
|
static void
|
||||||
doapr_outch(
|
doapr_outch(
|
||||||
|
char **sbuffer,
|
||||||
char **buffer,
|
char **buffer,
|
||||||
size_t *currlen,
|
size_t *currlen,
|
||||||
size_t *maxlen,
|
size_t *maxlen,
|
||||||
int c)
|
int c)
|
||||||
{
|
{
|
||||||
|
/* If we haven't at least one buffer, someone has doe a big booboo */
|
||||||
|
assert(*sbuffer != NULL || buffer != NULL);
|
||||||
|
|
||||||
|
if (buffer) {
|
||||||
|
while (*currlen >= *maxlen) {
|
||||||
if (*buffer == NULL) {
|
if (*buffer == NULL) {
|
||||||
|
assert(*sbuffer != NULL);
|
||||||
if (*maxlen == 0)
|
if (*maxlen == 0)
|
||||||
*maxlen = 1024;
|
*maxlen = 1024;
|
||||||
*buffer = OPENSSL_malloc(*maxlen);
|
*buffer = OPENSSL_malloc(*maxlen);
|
||||||
}
|
if (*currlen > 0)
|
||||||
while (*currlen >= *maxlen) {
|
memcpy(*buffer, *sbuffer, *currlen);
|
||||||
|
*sbuffer = NULL;
|
||||||
|
} else {
|
||||||
*maxlen += 1024;
|
*maxlen += 1024;
|
||||||
*buffer = OPENSSL_realloc(*buffer, *maxlen);
|
*buffer = OPENSSL_realloc(*buffer, *maxlen);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/* What to do if *buffer is NULL? */
|
/* What to do if *buffer is NULL? */
|
||||||
assert(*buffer != NULL);
|
assert(*sbuffer != NULL || *buffer != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*currlen < *maxlen) {
|
||||||
|
if (*sbuffer)
|
||||||
|
(*sbuffer)[(*currlen)++] = (char)c;
|
||||||
|
else
|
||||||
(*buffer)[(*currlen)++] = (char)c;
|
(*buffer)[(*currlen)++] = (char)c;
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
@ -824,29 +756,26 @@ int BIO_vprintf (BIO *bio, const char *format, va_list args)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
size_t retlen;
|
size_t retlen;
|
||||||
#ifdef USE_ALLOCATING_PRINT
|
|
||||||
char *hugebuf;
|
|
||||||
#else
|
|
||||||
MS_STATIC char hugebuf[1024*10];
|
MS_STATIC char hugebuf[1024*10];
|
||||||
#endif
|
char *hugebufp = hugebuf;
|
||||||
|
size_t hugebufsize = sizeof(hugebuf);
|
||||||
|
char *dynbuf = NULL;
|
||||||
|
int ignored;
|
||||||
|
|
||||||
#ifndef USE_ALLOCATING_PRINT
|
dynbuf = NULL;
|
||||||
hugebuf[0]='\0';
|
|
||||||
dopr(hugebuf, sizeof(hugebuf), &retlen, format, args);
|
|
||||||
#else
|
|
||||||
hugebuf = NULL;
|
|
||||||
CRYPTO_push_info("doapr()");
|
CRYPTO_push_info("doapr()");
|
||||||
doapr(&hugebuf, &retlen, format, args);
|
_dopr(&hugebufp, &dynbuf, &hugebufsize,
|
||||||
if (hugebuf)
|
&retlen, &ignored, format, args);
|
||||||
|
if (dynbuf)
|
||||||
|
{
|
||||||
|
ret=BIO_write(bio, dynbuf, (int)retlen);
|
||||||
|
OPENSSL_free(dynbuf);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
#endif
|
|
||||||
ret=BIO_write(bio, hugebuf, (int)retlen);
|
ret=BIO_write(bio, hugebuf, (int)retlen);
|
||||||
|
|
||||||
#ifdef USE_ALLOCATING_PRINT
|
|
||||||
OPENSSL_free(hugebuf);
|
|
||||||
}
|
}
|
||||||
CRYPTO_pop_info();
|
CRYPTO_pop_info();
|
||||||
#endif
|
|
||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -872,8 +801,8 @@ int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args)
|
|||||||
size_t retlen;
|
size_t retlen;
|
||||||
int truncated;
|
int truncated;
|
||||||
|
|
||||||
_dopr(dopr_outch, dopr_isbig, dopr_copy,
|
_dopr(&buf, NULL, &n, &retlen, &truncated, format, args);
|
||||||
&buf, &n, &retlen, &truncated, format, args);
|
|
||||||
if (truncated)
|
if (truncated)
|
||||||
/* In case of truncation, return -1 like traditional snprintf.
|
/* In case of truncation, return -1 like traditional snprintf.
|
||||||
* (Current drafts for ISO/IEC 9899 say snprintf should return
|
* (Current drafts for ISO/IEC 9899 say snprintf should return
|
||||||
|
Loading…
x
Reference in New Issue
Block a user