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