]> eyrie.org Git - kerberos/krb5-strength.git/blob - portable/asprintf.c
Add a basic portability library
[kerberos/krb5-strength.git] / portable / asprintf.c
1 /*
2  * Replacement for a missing asprintf and vasprintf.
3  *
4  * Provides the same functionality as the standard GNU library routines
5  * asprintf and vasprintf for those platforms that don't have them.
6  *
7  * Written by Russ Allbery <rra@stanford.edu>
8  * This work is hereby placed in the public domain by its author.
9  */
10
11 #include <config.h>
12 #include <portable/system.h>
13
14 /*
15  * If we're running the test suite, rename the functions to avoid conflicts
16  * with the system versions.
17  */
18 #if TESTING
19 # define asprintf test_asprintf
20 # define vasprintf test_vasprintf
21 int test_asprintf(char **, const char *, ...)
22     __attribute__((__format__(printf, 2, 3)));
23 int test_vasprintf(char **, const char *, va_list);
24 #endif
25
26 int
27 asprintf(char **strp, const char *fmt, ...)
28 {
29     va_list args;
30     int status;
31
32     va_start(args, fmt);
33     status = vasprintf(strp, fmt, args);
34     va_end(args);
35     return status;
36 }
37
38 int
39 vasprintf(char **strp, const char *fmt, va_list args)
40 {
41     va_list args_copy;
42     int status, needed;
43
44     va_copy(args_copy, args);
45     needed = vsnprintf(NULL, 0, fmt, args_copy);
46     va_end(args_copy);
47     if (needed < 0) {
48         *strp = NULL;
49         return needed;
50     }
51     *strp = malloc(needed + 1);
52     if (*strp == NULL)
53         return -1;
54     status = vsnprintf(*strp, needed + 1, fmt, args);
55     if (status >= 0)
56         return status;
57     else {
58         free(*strp);
59         *strp = NULL;
60         return status;
61     }
62 }