diff options
| author | Cy Schubert <cy@FreeBSD.org> | 2017-07-07 17:03:42 +0000 |
|---|---|---|
| committer | Cy Schubert <cy@FreeBSD.org> | 2017-07-07 17:03:42 +0000 |
| commit | 33a9b234e7087f573ef08cd7318c6497ba08b439 (patch) | |
| tree | d0ea40ad3bf5463a3c55795977c71bcb7d781b4b /src/util/support/printf.c | |
Diffstat (limited to 'src/util/support/printf.c')
| -rw-r--r-- | src/util/support/printf.c | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/src/util/support/printf.c b/src/util/support/printf.c new file mode 100644 index 000000000000..8228a40045d2 --- /dev/null +++ b/src/util/support/printf.c @@ -0,0 +1,100 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* util/support/printf.c */ +/* + * Copyright 2003, 2004, 2005, 2007, 2008 Massachusetts Institute of + * Technology. All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +/* Provide {,v}asprintf for platforms that don't have them. */ + +#include "k5-platform.h" + +/* On error: BSD: Set *ret to NULL. GNU: *ret is undefined. + + Since we want to be able to use the GNU version directly, we need + provide only the weaker guarantee in this version. */ +int +krb5int_vasprintf(char **ret, const char *format, va_list ap) +{ + va_list ap2; + char *str = NULL, *nstr; + size_t len = 80; + int len2; + + while (1) { + if (len >= INT_MAX || len == 0) + goto fail; + nstr = realloc(str, len); + if (nstr == NULL) + goto fail; + str = nstr; + va_copy(ap2, ap); + len2 = vsnprintf(str, len, format, ap2); + va_end(ap2); + /* ISO C vsnprintf returns the needed length. Some old + vsnprintf implementations return -1 on truncation. */ + if (len2 < 0) { + /* Don't know how much space we need, just that we didn't + supply enough; get a bigger buffer and try again. */ + if (len <= SIZE_MAX/2) + len *= 2; + else if (len < SIZE_MAX) + len = SIZE_MAX; + else + goto fail; + } else if ((unsigned int) len2 >= SIZE_MAX) { + /* Need more space than we can request. */ + goto fail; + } else if ((size_t) len2 >= len) { + /* Need more space, but we know how much. */ + len = (size_t) len2 + 1; + } else { + /* Success! */ + break; + } + } + /* We might've allocated more than we need, if we're still using + the initial guess, or we got here by doubling. */ + if ((size_t) len2 < len - 1) { + nstr = realloc(str, (size_t) len2 + 1); + if (nstr) + str = nstr; + } + *ret = str; + return len2; + +fail: + free(str); + return -1; +} + +int +krb5int_asprintf(char **ret, const char *format, ...) +{ + va_list ap; + int n; + + va_start(ap, format); + n = krb5int_vasprintf(ret, format, ap); + va_end(ap); + return n; +} |
