]> The Tcpdump Group git mirrors - tcpdump/commitdiff
Pick up Windows snprintf and strdup replacements from libpcap.
authorGuy Harris <[email protected]>
Mon, 29 Jan 2018 04:57:15 +0000 (20:57 -0800)
committerGuy Harris <[email protected]>
Mon, 29 Jan 2018 04:57:15 +0000 (20:57 -0800)
CMakeLists.txt
Makefile.in
interface.h
missing/win_snprintf.c [new file with mode: 0644]
netdissect-stdinc.h
netdissect.h

index bb9e7458ff329f2db400bfbe85f27316f199221a..c34d21bc6220941abd09340836346228886fe32d 100644 (file)
@@ -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
index 6169bd116c74ab880df0fad48ff762265552c423..185e44b5b4a8b0675e920ef0c9483c91bc791f63 100644 (file)
@@ -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 \
index 7abf9c41da9edd7095723e42a085be9ea6aa1779..8927a19bad22213e59fb298244b5c19aa1ff9fa2 100644 (file)
 #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 (file)
index 0000000..17dc633
--- /dev/null
@@ -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);
+}
index 8ef4e2a704326f1577f264e0c2af6c87f40e0e76..1324ae18f2d005eabc5a90837578c8403902bb9d 100644 (file)
 #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.
  */
index 323343dc8f680c2810bdd84a6f3784493b4f6375..3e76468bd92bf8d8621688ce9f1368630a2be48f 100644 (file)
@@ -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