summaryrefslogtreecommitdiffstats
path: root/lib/libpcap/libpcap/missing/asprintf.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libpcap/libpcap/missing/asprintf.c')
-rw-r--r--lib/libpcap/libpcap/missing/asprintf.c101
1 files changed, 101 insertions, 0 deletions
diff --git a/lib/libpcap/libpcap/missing/asprintf.c b/lib/libpcap/libpcap/missing/asprintf.c
new file mode 100644
index 0000000..3aa55ed
--- /dev/null
+++ b/lib/libpcap/libpcap/missing/asprintf.c
@@ -0,0 +1,101 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+#include "portability.h"
+
+/*
+ * vasprintf() and asprintf() for platforms with a C99-compliant
+ * snprintf() - so that, if you format into a 1-byte buffer, it
+ * will return how many characters it would have produced had
+ * it been given an infinite-sized buffer.
+ */
+int
+pcap_vasprintf(char **strp, const char *format, va_list args)
+{
+ char buf;
+ int len;
+ size_t str_size;
+ char *str;
+ int ret;
+
+ /*
+ * XXX - the C99 standard says, in section 7.19.6.5 "Thes
+ * nprintf function":
+ *
+ * The snprintf function is equivalent to fprintf, except that
+ * the output is written into an array (specified by argument s)
+ * rather than to a stream. If n is zero, nothing is written,
+ * and s may be a null pointer. Otherwise, output characters
+ * beyond the n-1st are discarded rather than being written
+ * to the array, and a null character is written at the end
+ * of the characters actually written into the array.
+ *
+ * ...
+ *
+ * The snprintf function returns the number of characters that
+ * would have been written had n been sufficiently large, not
+ * counting the terminating null character, or a negative value
+ * if an encoding error occurred. Thus, the null-terminated
+ * output has been completely written if and only if the returned
+ * value is nonnegative and less than n.
+ *
+ * That doesn't make it entirely clear whether, if a null buffer
+ * pointer and a zero count are passed, it will return the number
+ * of characters that would have been written had a buffer been
+ * passed.
+ *
+ * And, even if C99 *does*, in fact, say it has to work, it
+ * doesn't work in Solaris 8, for example - it returns -1 for
+ * NULL/0, but returns the correct character count for a 1-byte
+ * buffer.
+ *
+ * So we pass a one-character pointer in order to find out how
+ * many characters this format and those arguments will need
+ * without actually generating any more of those characters
+ * than we need.
+ *
+ * (The fact that it might happen to work with GNU libc or with
+ * various BSD libcs is completely uninteresting, as those tend
+ * to have asprintf() already and thus don't even *need* this
+ * code; this is for use in those UN*Xes that *don't* have
+ * asprintf().)
+ */
+ len = vsnprintf(&buf, sizeof buf, format, args);
+ if (len == -1) {
+ *strp = NULL;
+ return (-1);
+ }
+ str_size = len + 1;
+ str = malloc(str_size);
+ if (str == NULL) {
+ *strp = NULL;
+ return (-1);
+ }
+ ret = vsnprintf(str, str_size, format, args);
+ if (ret == -1) {
+ free(str);
+ *strp = NULL;
+ return (-1);
+ }
+ *strp = str;
+ /*
+ * vsnprintf() shouldn't truncate the string, as we have
+ * allocated a buffer large enough to hold the string, so its
+ * return value should be the number of characters written.
+ */
+ return (ret);
+}
+
+int
+pcap_asprintf(char **strp, const char *format, ...)
+{
+ va_list args;
+ int ret;
+
+ va_start(args, format);
+ ret = pcap_vasprintf(strp, format, args);
+ va_end(args);
+ return (ret);
+}
+