diff options
Diffstat (limited to 'source4/lib/talloc/talloc.c')
-rw-r--r-- | source4/lib/talloc/talloc.c | 79 |
1 files changed, 29 insertions, 50 deletions
diff --git a/source4/lib/talloc/talloc.c b/source4/lib/talloc/talloc.c index 0b4d977aa7..033e70d2f9 100644 --- a/source4/lib/talloc/talloc.c +++ b/source4/lib/talloc/talloc.c @@ -1313,30 +1313,18 @@ char *talloc_asprintf(const void *t, const char *fmt, ...) return ret; } - -/** - * Realloc @p s to append the formatted result of @p fmt and @p ap, - * and return @p s, which may have moved. Good for gradually - * accumulating output into a string buffer. Appends at the end - * of the string. - **/ -char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap) +static inline char *__talloc_vaslenprintf_append(char *s, size_t slen, + const char *fmt, va_list ap) { - int len, s_len; + ssize_t alen; va_list ap2; char c; - if (s == NULL) { - return talloc_vasprintf(NULL, fmt, ap); - } - - s_len = strlen(s); - va_copy(ap2, ap); - len = vsnprintf(&c, 1, fmt, ap2); + alen = vsnprintf(&c, 1, fmt, ap2); va_end(ap2); - if (len <= 0) { + if (alen <= 0) { /* Either the vsnprintf failed or the format resulted in * no characters being formatted. In the former case, we * ought to return NULL, in the latter we ought to return @@ -1346,60 +1334,51 @@ char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap) return s; } - s = talloc_realloc(NULL, s, char, s_len + len+1); + s = talloc_realloc(NULL, s, char, slen + alen + 1); if (!s) return NULL; va_copy(ap2, ap); - vsnprintf(s+s_len, len+1, fmt, ap2); + vsnprintf(s + slen, alen + 1, fmt, ap2); va_end(ap2); - _talloc_set_name_const(s, s); + _talloc_set_name_const(s, s); return s; } /** * Realloc @p s to append the formatted result of @p fmt and @p ap, + * and return @p s, which may have moved. Good for gradually + * accumulating output into a string buffer. Appends at the end + * of the string. + **/ +char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap) +{ + if (unlikely(!s)) { + return talloc_vasprintf(NULL, fmt, ap); + } + + return __talloc_vaslenprintf_append(s, strlen(s), fmt, ap); +} + +/** + * Realloc @p s to append the formatted result of @p fmt and @p ap, * and return @p s, which may have moved. Always appends at the * end of the talloc'ed buffer, not the end of the string. **/ char *talloc_vasprintf_append_buffer(char *s, const char *fmt, va_list ap) { - struct talloc_chunk *tc; - int len, s_len; - va_list ap2; - char c; + size_t slen; - if (s == NULL) { + if (unlikely(!s)) { return talloc_vasprintf(NULL, fmt, ap); } - tc = talloc_chunk_from_ptr(s); - - s_len = tc->size - 1; - - va_copy(ap2, ap); - len = vsnprintf(&c, 1, fmt, ap2); - va_end(ap2); - - if (len <= 0) { - /* Either the vsnprintf failed or the format resulted in - * no characters being formatted. In the former case, we - * ought to return NULL, in the latter we ought to return - * the original string. Most current callers of this - * function expect it to never return NULL. - */ - return s; + slen = talloc_get_size(s); + if (likely(slen > 0)) { + slen--; } - s = talloc_realloc(NULL, s, char, s_len + len+1); - if (!s) return NULL; - - va_copy(ap2, ap); - vsnprintf(s+s_len, len+1, fmt, ap2); - va_end(ap2); - _talloc_set_name_const(s, s); - - return s; + return __talloc_vaslenprintf_append(s, slen, fmt, ap); } /* |