14a71e5f3Schristos #include <stdio.h> 24a71e5f3Schristos #include <stdlib.h> 34a71e5f3Schristos #include <stdarg.h> 44a71e5f3Schristos 54a71e5f3Schristos #include "portability.h" 64a71e5f3Schristos 74a71e5f3Schristos /* 84a71e5f3Schristos * vasprintf() and asprintf() for platforms with a C99-compliant 94a71e5f3Schristos * snprintf() - so that, if you format into a 1-byte buffer, it 104a71e5f3Schristos * will return how many characters it would have produced had 114a71e5f3Schristos * it been given an infinite-sized buffer. 124a71e5f3Schristos */ 134a71e5f3Schristos int 14*f73a5f05Schristos pcapint_vasprintf(char **strp, const char *format, va_list args) 154a71e5f3Schristos { 164a71e5f3Schristos char buf; 174a71e5f3Schristos int len; 184a71e5f3Schristos size_t str_size; 194a71e5f3Schristos char *str; 204a71e5f3Schristos int ret; 214a71e5f3Schristos 224a71e5f3Schristos /* 23748408edSchristos * XXX - the C99 standard says, in section 7.19.6.5 "The 24*f73a5f05Schristos * snprintf function": 254a71e5f3Schristos * 264a71e5f3Schristos * The snprintf function is equivalent to fprintf, except that 274a71e5f3Schristos * the output is written into an array (specified by argument s) 284a71e5f3Schristos * rather than to a stream. If n is zero, nothing is written, 294a71e5f3Schristos * and s may be a null pointer. Otherwise, output characters 304a71e5f3Schristos * beyond the n-1st are discarded rather than being written 314a71e5f3Schristos * to the array, and a null character is written at the end 324a71e5f3Schristos * of the characters actually written into the array. 334a71e5f3Schristos * 344a71e5f3Schristos * ... 354a71e5f3Schristos * 364a71e5f3Schristos * The snprintf function returns the number of characters that 374a71e5f3Schristos * would have been written had n been sufficiently large, not 384a71e5f3Schristos * counting the terminating null character, or a negative value 394a71e5f3Schristos * if an encoding error occurred. Thus, the null-terminated 404a71e5f3Schristos * output has been completely written if and only if the returned 414a71e5f3Schristos * value is nonnegative and less than n. 424a71e5f3Schristos * 434a71e5f3Schristos * That doesn't make it entirely clear whether, if a null buffer 444a71e5f3Schristos * pointer and a zero count are passed, it will return the number 454a71e5f3Schristos * of characters that would have been written had a buffer been 464a71e5f3Schristos * passed. 474a71e5f3Schristos * 484a71e5f3Schristos * And, even if C99 *does*, in fact, say it has to work, it 494a71e5f3Schristos * doesn't work in Solaris 8, for example - it returns -1 for 504a71e5f3Schristos * NULL/0, but returns the correct character count for a 1-byte 514a71e5f3Schristos * buffer. 524a71e5f3Schristos * 534a71e5f3Schristos * So we pass a one-character pointer in order to find out how 544a71e5f3Schristos * many characters this format and those arguments will need 554a71e5f3Schristos * without actually generating any more of those characters 564a71e5f3Schristos * than we need. 574a71e5f3Schristos * 584a71e5f3Schristos * (The fact that it might happen to work with GNU libc or with 594a71e5f3Schristos * various BSD libcs is completely uninteresting, as those tend 604a71e5f3Schristos * to have asprintf() already and thus don't even *need* this 614a71e5f3Schristos * code; this is for use in those UN*Xes that *don't* have 624a71e5f3Schristos * asprintf().) 634a71e5f3Schristos */ 644a71e5f3Schristos len = vsnprintf(&buf, sizeof buf, format, args); 654a71e5f3Schristos if (len == -1) { 664a71e5f3Schristos *strp = NULL; 674a71e5f3Schristos return (-1); 684a71e5f3Schristos } 694a71e5f3Schristos str_size = len + 1; 704a71e5f3Schristos str = malloc(str_size); 714a71e5f3Schristos if (str == NULL) { 724a71e5f3Schristos *strp = NULL; 734a71e5f3Schristos return (-1); 744a71e5f3Schristos } 754a71e5f3Schristos ret = vsnprintf(str, str_size, format, args); 764a71e5f3Schristos if (ret == -1) { 774a71e5f3Schristos free(str); 784a71e5f3Schristos *strp = NULL; 794a71e5f3Schristos return (-1); 804a71e5f3Schristos } 814a71e5f3Schristos *strp = str; 824a71e5f3Schristos /* 834a71e5f3Schristos * vsnprintf() shouldn't truncate the string, as we have 844a71e5f3Schristos * allocated a buffer large enough to hold the string, so its 854a71e5f3Schristos * return value should be the number of characters written. 864a71e5f3Schristos */ 874a71e5f3Schristos return (ret); 884a71e5f3Schristos } 894a71e5f3Schristos 904a71e5f3Schristos int 91*f73a5f05Schristos pcapint_asprintf(char **strp, const char *format, ...) 924a71e5f3Schristos { 934a71e5f3Schristos va_list args; 944a71e5f3Schristos int ret; 954a71e5f3Schristos 964a71e5f3Schristos va_start(args, format); 97*f73a5f05Schristos ret = pcapint_vasprintf(strp, format, args); 984a71e5f3Schristos va_end(args); 994a71e5f3Schristos return (ret); 1004a71e5f3Schristos } 1014a71e5f3Schristos 102