summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2018-01-28 20:57:15 -0800
committerGuy Harris <guy@alum.mit.edu>2018-01-28 20:57:15 -0800
commitb3703ed9cfac43b0026fc2e2013e1612edad4300 (patch)
treeedf46516bcff6163fc4258c0d20665d3707a8c87
parenta909db55ebc50de487e65f19b3250d0b45763d2d (diff)
downloadtcpdump-b3703ed9cfac43b0026fc2e2013e1612edad4300.tar.gz
Pick up Windows snprintf and strdup replacements from libpcap.
-rw-r--r--CMakeLists.txt6
-rw-r--r--Makefile.in1
-rw-r--r--interface.h10
-rw-r--r--missing/win_snprintf.c31
-rw-r--r--netdissect-stdinc.h62
-rw-r--r--netdissect.h10
6 files changed, 93 insertions, 27 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index bb9e7458..c34d21bc 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -884,7 +884,11 @@ foreach(FUNC strlcat strlcpy strdup strsep getservent getopt_long)
endif()
endforeach()
if(NOT HAVE_VSNPRINTF OR NOT HAVE_SNPRINTF)
- set(NETDISSECT_SOURCE_LIST_C ${NETDISSECT_SOURCE_LIST_C} missing/snprintf.c)
+ if(WIN32)
+ set(NETDISSECT_SOURCE_LIST_C ${NETDISSECT_SOURCE_LIST_C} missing/win_snprintf.c)
+ else(WIN32)
+ set(NETDISSECT_SOURCE_LIST_C ${NETDISSECT_SOURCE_LIST_C} missing/snprintf.c)
+ endif(WIN32)
endif(NOT HAVE_VSNPRINTF OR NOT HAVE_SNPRINTF)
add_library(netdissect STATIC
diff --git a/Makefile.in b/Makefile.in
index 6169bd11..185e44b5 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -358,6 +358,7 @@ EXTRA_DIST = \
missing/strsep.c \
missing/win_ether_ntohost.c \
missing/win_ether_ntohost.h \
+ missing/win_snprintf.c \
mkdep \
packetdat.awk \
pcap_dump_ftell.c \
diff --git a/interface.h b/interface.h
index 7abf9c41..8927a19b 100644
--- a/interface.h
+++ b/interface.h
@@ -36,16 +36,6 @@
#include <stdint.h>
#endif
-#if !defined(HAVE_SNPRINTF)
-int snprintf(char *, size_t, FORMAT_STRING(const char *), ...)
- PRINTFLIKE(3, 4);
-#endif /* !defined(HAVE_SNPRINTF) */
-
-#if !defined(HAVE_VSNPRINTF)
-int vsnprintf(char *, size_t, FORMAT_STRING(const char *), va_list)
- PRINTFLIKE(3, 0);
-#endif /* !defined(HAVE_VSNPRINTF) */
-
#ifndef HAVE_STRLCAT
extern size_t strlcat(char *, const char *, size_t);
#endif
diff --git a/missing/win_snprintf.c b/missing/win_snprintf.c
new file mode 100644
index 00000000..17dc633c
--- /dev/null
+++ b/missing/win_snprintf.c
@@ -0,0 +1,31 @@
+#include <stdio.h>
+#include <stdarg.h>
+
+int
+vsnprintf(char *str, size_t str_size, const char *format, va_list args)
+{
+ int ret;
+
+ ret = _vsnprintf_s(str, str_size, _TRUNCATE, format, args);
+
+ /*
+ * XXX - _vsnprintf() and _snprintf() do *not* guarantee
+ * that str is null-terminated, but C99's vsnprintf()
+ * and snprintf() do, and we want to offer C99 behavior,
+ * so forcibly null-terminate the string.
+ */
+ str[str_size - 1] = '\0';
+ return (ret);
+}
+
+int
+snprintf(char *str, size_t str_size, const char *format, ...)
+{
+ va_list args;
+ int ret;
+
+ va_start(args, format);
+ ret = vsnprintf(str, str_size, format, args);
+ va_end(args);
+ return (ret);
+}
diff --git a/netdissect-stdinc.h b/netdissect-stdinc.h
index 8ef4e2a7..1324ae18 100644
--- a/netdissect-stdinc.h
+++ b/netdissect-stdinc.h
@@ -209,12 +209,23 @@
#endif
#ifdef _MSC_VER
-#define stat _stat
-#define open _open
-#define fstat _fstat
-#define read _read
-#define close _close
-#define O_RDONLY _O_RDONLY
+ #define stat _stat
+ #define strdup _strdup
+ #define open _open
+ #define fstat _fstat
+ #define read _read
+ #define close _close
+ #define O_RDONLY _O_RDONLY
+
+ /*
+ * If <crtdbg.h> has been included, and _DEBUG is defined, and
+ * __STDC__ is zero, <crtdbg.h> will define strdup() to call
+ * _strdup_dbg(). So if it's already defined, don't redefine
+ * it.
+ */
+ #ifndef strdup
+ #define strdup _strdup
+ #endif
#endif /* _MSC_VER */
/*
@@ -277,6 +288,45 @@ typedef char* caddr_t;
#endif /* _WIN32 */
+#ifdef _MSC_VER
+ /*
+ * MSVC.
+ */
+ #if _MSC_VER >= 1900
+ /*
+ * VS 2015 or newer; we have snprintf() function.
+ */
+ #define HAVE_SNPRINTF
+ #endif
+#endif
+
+/*
+ * On Windows, snprintf(), with that name and with C99 behavior - i.e.,
+ * guaranteeing that the formatted string is null-terminated - didn't
+ * appear until Visual Studio 2015. Prior to that, the C runtime had
+ * only _snprintf(), which *doesn't* guarantee that the string is
+ * null-terminated if it is truncated due to the buffer being too
+ * small. We therefore can't just define snprintf to be _snprintf
+ * and define vsnprintf to be _vsnprintf, as we're relying on null-
+ * termination of strings in all cases.
+ *
+ * We also want to allow this to be built with versions of Visual Studio
+ * prior to VS 2015, so we can't rely on snprintf() being present.
+ *
+ * And, if there are any UN*Xes out there on which we can run that
+ * don't have snprintf() or don't have vsnprintf(), we define our
+ * own as well.
+ */
+#if !defined(HAVE_SNPRINTF)
+int snprintf (char *str, size_t sz, FORMAT_STRING(const char *format), ...)
+ PRINTFLIKE(3, 4);
+#endif /* !defined(HAVE_SNPRINTF) */
+
+#if !defined(HAVE_VSNPRINTF)
+int vsnprintf (char *str, size_t sz, FORMAT_STRING(const char *format),
+ va_list ap) PRINTFLIKE(3, 0);
+#endif /* !defined(HAVE_VSNPRINTF) */
+
/*
* fopen() read and write modes for text files and binary files.
*/
diff --git a/netdissect.h b/netdissect.h
index 323343dc..3e76468b 100644
--- a/netdissect.h
+++ b/netdissect.h
@@ -164,16 +164,6 @@ extern int32_t thiszone; /* seconds offset from gmt to local time */
/* invalid string to print '(invalid)' for malformed or corrupted packets */
extern const char istr[];
-#if !defined(HAVE_SNPRINTF)
-int snprintf (char *str, size_t sz, FORMAT_STRING(const char *format), ...)
- PRINTFLIKE(3, 4);
-#endif /* !defined(HAVE_SNPRINTF) */
-
-#if !defined(HAVE_VSNPRINTF)
-int vsnprintf (char *str, size_t sz, FORMAT_STRING(const char *format),
- va_list ap) PRINTFLIKE(3, 0);
-#endif /* !defined(HAVE_VSNPRINTF) */
-
#ifndef HAVE_STRLCAT
extern size_t strlcat (char *, const char *, size_t);
#endif