diff options
author | Guy Harris <guy@alum.mit.edu> | 2018-01-28 20:57:15 -0800 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2018-01-28 20:57:15 -0800 |
commit | b3703ed9cfac43b0026fc2e2013e1612edad4300 (patch) | |
tree | edf46516bcff6163fc4258c0d20665d3707a8c87 | |
parent | a909db55ebc50de487e65f19b3250d0b45763d2d (diff) | |
download | tcpdump-b3703ed9cfac43b0026fc2e2013e1612edad4300.tar.gz |
Pick up Windows snprintf and strdup replacements from libpcap.
-rw-r--r-- | CMakeLists.txt | 6 | ||||
-rw-r--r-- | Makefile.in | 1 | ||||
-rw-r--r-- | interface.h | 10 | ||||
-rw-r--r-- | missing/win_snprintf.c | 31 | ||||
-rw-r--r-- | netdissect-stdinc.h | 62 | ||||
-rw-r--r-- | netdissect.h | 10 |
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 |