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 pcapint_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 "The 24 * snprintf 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 pcapint_asprintf(char **strp, const char *format, ...) 92 { 93 va_list args; 94 int ret; 95 96 va_start(args, format); 97 ret = pcapint_vasprintf(strp, format, args); 98 va_end(args); 99 return (ret); 100 } 101 102