summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2021-11-05 12:08:48 -0400
committerNick Mathewson <nickm@torproject.org>2021-11-05 12:36:34 -0400
commitc93114ec9e45f4fb3843012056046eec15b875aa (patch)
tree80cb7a61e78f4d0d37d308534cb1b5646231338b
parent1c77deca4f8e8027eaf130b6454af758e4d9ccc4 (diff)
downloadtor-c93114ec9e45f4fb3843012056046eec15b875aa.tar.gz
tor-c93114ec9e45f4fb3843012056046eec15b875aa.zip
Prefer use of __MINGW_PRINTF/SCANF_FORMAT if available.
Mingw headers sometimes like to define alternative scanf/printf format attributes depending on whether they're using clang, UCRT, MINGW_ANSI_STDIO, or the microsoft version of printf/scanf. This change attempts to use the right one on the given platform. This is an attempt to fix part of #40355.
-rw-r--r--changes/bug40355_part24
-rw-r--r--configure.ac4
-rw-r--r--src/feature/api/tor_api.c4
-rw-r--r--src/lib/cc/compat_compiler.h31
-rw-r--r--src/lib/string/printf.c4
5 files changed, 37 insertions, 10 deletions
diff --git a/changes/bug40355_part2 b/changes/bug40355_part2
new file mode 100644
index 0000000000..000321d912
--- /dev/null
+++ b/changes/bug40355_part2
@@ -0,0 +1,4 @@
+ o Minor features (portability):
+ - Try to prevent a compiler warning about printf arguments that could
+ sometimes occur on MSYS2 depending on the configuration.
+ Closes ticket 40355. \ No newline at end of file
diff --git a/configure.ac b/configure.ac
index 366df64609..0d95b19796 100644
--- a/configure.ac
+++ b/configure.ac
@@ -689,6 +689,7 @@ AC_CHECK_FUNCS(
readpassphrase \
rint \
sigaction \
+ snprintf \
socketpair \
statvfs \
strncasecmp \
@@ -706,7 +707,8 @@ AC_CHECK_FUNCS(
uname \
usleep \
vasprintf \
- _vscprintf
+ _vscprintf \
+ vsnprintf
)
# Apple messed up when they added some functions: they
diff --git a/src/feature/api/tor_api.c b/src/feature/api/tor_api.c
index 051be50b3a..88e91ebfd5 100644
--- a/src/feature/api/tor_api.c
+++ b/src/feature/api/tor_api.c
@@ -18,9 +18,9 @@
// Include this after the above headers, to insure that they don't
// depend on anything else.
#include "orconfig.h"
+#include "lib/cc/compat_compiler.h"
#include "lib/cc/torint.h"
#include "feature/api/tor_api_internal.h"
-#include "lib/cc/compat_compiler.h"
#include <stdio.h>
#include <stdlib.h>
@@ -39,7 +39,9 @@
#include "lib/net/socketpair.h"
#define raw_socketpair tor_ersatz_socketpair
#define raw_closesocket closesocket
+#if !defined(HAVE_SNPRINTF)
#define snprintf _snprintf
+#endif
#else /* !defined(_WIN32) */
#define raw_socketpair socketpair
#define raw_closesocket close
diff --git a/src/lib/cc/compat_compiler.h b/src/lib/cc/compat_compiler.h
index 50bfedffba..991b33d9e7 100644
--- a/src/lib/cc/compat_compiler.h
+++ b/src/lib/cc/compat_compiler.h
@@ -15,6 +15,15 @@
#include "orconfig.h"
#include <inttypes.h>
+#if defined(__MINGW32__) || defined(__MINGW64__)
+#define MINGW_ANY
+#endif
+
+#ifdef MINGW_ANY
+/* We need this for __MINGW_PRINTF_FORMAT, alas. */
+#include <stdio.h>
+#endif
+
#if defined(__has_feature)
# if __has_feature(address_sanitizer)
/* Some of the fancy glibc strcmp() macros include references to memory that
@@ -36,16 +45,30 @@
#error "It seems that you encode characters in something other than ASCII."
#endif
+/* Use the right magic attribute on mingw, which might be printf, gnu_printf,
+ * or ms_printf, depending on how we're set up to build.
+ */
+#ifdef __MINGW_PRINTF_FORMAT
+#define PRINTF_FORMAT_ATTR __MINGW_PRINTF_FORMAT
+#else
+#define PRINTF_FORMAT_ATTR printf
+#endif
+#ifdef __MINGW_SCANF_FORMAT
+#define SCANF_FORMAT_ATTR __MINGW_SCANF_FORMAT
+#else
+#define SCANF_FORMAT_ATTR scanf
+#endif
+
/* GCC can check printf and scanf types on arbitrary functions. */
#ifdef __GNUC__
#define CHECK_PRINTF(formatIdx, firstArg) \
- __attribute__ ((format(printf, formatIdx, firstArg)))
+ __attribute__ ((format(PRINTF_FORMAT_ATTR, formatIdx, firstArg)))
#else
#define CHECK_PRINTF(formatIdx, firstArg)
#endif /* defined(__GNUC__) */
#ifdef __GNUC__
#define CHECK_SCANF(formatIdx, firstArg) \
- __attribute__ ((format(scanf, formatIdx, firstArg)))
+ __attribute__ ((format(SCANF_FORMAT_ATTR, formatIdx, firstArg)))
#else
#define CHECK_SCANF(formatIdx, firstArg)
#endif /* defined(__GNUC__) */
@@ -191,10 +214,6 @@
#define OP_EQ ==
#define OP_NE !=
-#if defined(__MINGW32__) || defined(__MINGW64__)
-#define MINGW_ANY
-#endif
-
/** Macro: yield a pointer to the field at position <b>off</b> within the
* structure <b>st</b>. Example:
* <pre>
diff --git a/src/lib/string/printf.c b/src/lib/string/printf.c
index 62758093a7..bd35b76d1b 100644
--- a/src/lib/string/printf.c
+++ b/src/lib/string/printf.c
@@ -8,9 +8,9 @@
* \brief Compatibility wrappers around snprintf and its friends
**/
+#include "lib/cc/torint.h"
#include "lib/string/printf.h"
#include "lib/err/torerr.h"
-#include "lib/cc/torint.h"
#include "lib/malloc/malloc.h"
#include <stdlib.h>
@@ -45,7 +45,7 @@ tor_vsnprintf(char *str, size_t size, const char *format, va_list args)
return -1; /* no place for the NUL */
if (size > SIZE_T_CEILING)
return -1;
-#ifdef _WIN32
+#if defined(_WIN32) && !defined(HAVE_VSNPRINTF)
r = _vsnprintf(str, size, format, args);
#else
r = vsnprintf(str, size, format, args);