]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/libpcap/missing/asprintf.c
MFV r353141 (by phillip):
[FreeBSD/FreeBSD.git] / contrib / libpcap / missing / asprintf.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <stdarg.h>
4
5 #include "portability.h"
6
7 /*
8  * vasprintf() and asprintf() for platforms with a C99-compliant
9  * snprintf() - so that, if you format into a 1-byte buffer, it
10  * will return how many characters it would have produced had
11  * it been given an infinite-sized buffer.
12  */
13 int
14 pcap_vasprintf(char **strp, const char *format, va_list args)
15 {
16         char buf;
17         int len;
18         size_t str_size;
19         char *str;
20         int ret;
21
22         /*
23          * XXX - the C99 standard says, in section 7.19.6.5 "Thes
24          * nprintf function":
25          *
26          *    The snprintf function is equivalent to fprintf, except that
27          *    the output is written into an array (specified by argument s)
28          *    rather than to a stream.  If n is zero, nothing is written,
29          *    and s may be a null pointer.  Otherwise, output characters
30          *    beyond the n-1st are discarded rather than being written
31          *    to the array, and a null character is written at the end
32          *    of the characters actually written into the array.
33          *
34          *        ...
35          *
36          *    The snprintf function returns the number of characters that
37          *    would have been written had n been sufficiently large, not
38          *    counting the terminating null character, or a negative value
39          *    if an encoding error occurred. Thus, the null-terminated
40          *    output has been completely written if and only if the returned
41          *    value is nonnegative and less than n.
42          *
43          * That doesn't make it entirely clear whether, if a null buffer
44          * pointer and a zero count are passed, it will return the number
45          * of characters that would have been written had a buffer been
46          * passed.
47          *
48          * And, even if C99 *does*, in fact, say it has to work, it
49          * doesn't work in Solaris 8, for example - it returns -1 for
50          * NULL/0, but returns the correct character count for a 1-byte
51          * buffer.
52          *
53          * So we pass a one-character pointer in order to find out how
54          * many characters this format and those arguments will need
55          * without actually generating any more of those characters
56          * than we need.
57          *
58          * (The fact that it might happen to work with GNU libc or with
59          * various BSD libcs is completely uninteresting, as those tend
60          * to have asprintf() already and thus don't even *need* this
61          * code; this is for use in those UN*Xes that *don't* have
62          * asprintf().)
63          */
64         len = vsnprintf(&buf, sizeof buf, format, args);
65         if (len == -1) {
66                 *strp = NULL;
67                 return (-1);
68         }
69         str_size = len + 1;
70         str = malloc(str_size);
71         if (str == NULL) {
72                 *strp = NULL;
73                 return (-1);
74         }
75         ret = vsnprintf(str, str_size, format, args);
76         if (ret == -1) {
77                 free(str);
78                 *strp = NULL;
79                 return (-1);
80         }
81         *strp = str;
82         /*
83          * vsnprintf() shouldn't truncate the string, as we have
84          * allocated a buffer large enough to hold the string, so its
85          * return value should be the number of characters written.
86          */
87         return (ret);
88 }
89
90 int
91 pcap_asprintf(char **strp, const char *format, ...)
92 {
93         va_list args;
94         int ret;
95
96         va_start(args, format);
97         ret = pcap_vasprintf(strp, format, args);
98         va_end(args);
99         return (ret);
100 }
101