va_end(arglist);
}
+static const char*
+openvpn_strerror(int err, bool crt_error, struct gc_arena *gc)
+{
+#ifdef _WIN32
+ if (!crt_error)
+ {
+ return strerror_win32(err, gc);
+ }
+#endif
+ return strerror(err);
+}
+
void
x_msg_va(const unsigned int flags, const char *format, va_list arglist)
{
return;
}
- e = openvpn_errno();
+ bool crt_error = false;
+ e = openvpn_errno_maybe_crt(&crt_error);
/*
* Apply muting filter.
if ((flags & M_ERRNO) && e)
{
openvpn_snprintf(m2, ERR_BUF_SIZE, "%s: %s (errno=%d)",
- m1, strerror(e), e);
+ m1, openvpn_strerror(e, crt_error, &gc), e);
SWAP;
}
struct link_socket *sock,
struct tuntap *tt)
{
- const int my_errno = openvpn_errno();
const char *extended_msg = NULL;
msg(x_cs_verbose_level, "%s %s returned %d",
sock->info.mtu_changed = true;
}
}
-#elif defined(_WIN32)
+#endif /* EXTENDED_SOCKET_ERROR_CAPABILITY */
+
+#ifdef _WIN32
/* get possible driver error from TAP-Windows driver */
if (tuntap_defined(tt))
{
extended_msg = tap_win_getinfo(tt, &gc);
}
#endif
- if (!ignore_sys_error(my_errno))
+
+ bool crt_error = false;
+ int my_errno = openvpn_errno_maybe_crt(&crt_error);
+
+ if (!ignore_sys_error(my_errno, crt_error))
{
if (extended_msg)
{
msg(x_cs_info_level, "%s %s [%s]: %s (fd=%d,code=%d)", description,
sock ? proto2ascii(sock->info.proto, sock->info.af, true) : "",
- extended_msg, strerror(my_errno), sock ? sock->sd : -1, my_errno);
+ extended_msg, openvpn_strerror(my_errno, crt_error, &gc),
+ sock ? sock->sd : -1, my_errno);
}
else
{
msg(x_cs_info_level, "%s %s: %s (fd=%d,code=%d)", description,
sock ? proto2ascii(sock->info.proto, sock->info.af, true) : "",
- strerror(my_errno), sock ? sock->sd : -1, my_errno);
+ openvpn_strerror(my_errno, crt_error, &gc),
+ sock ? sock->sd : -1, my_errno);
}
if (x_cs_err_delay_ms)
/* String and Error functions */
#ifdef _WIN32
-#define openvpn_errno() GetLastError()
-#define openvpn_strerror(e, gc) strerror_win32(e, gc)
+#define openvpn_errno() GetLastError()
const char *strerror_win32(DWORD errnum, struct gc_arena *gc);
-
#else
-#define openvpn_errno() errno
-#define openvpn_strerror(x, gc) strerror(x)
+#define openvpn_errno() errno
#endif
/*
* which can be safely ignored.
*/
static inline bool
-ignore_sys_error(const int err)
+ignore_sys_error(const int err, bool crt_error)
{
- /* I/O operation pending */
#ifdef _WIN32
- if (err == WSAEWOULDBLOCK || err == WSAEINVAL)
+ if (!crt_error && ((err == WSAEWOULDBLOCK || err == WSAEINVAL)))
{
return true;
}
#else
- if (err == EAGAIN)
+ crt_error = true;
+#endif
+
+ /* I/O operation pending */
+ if (crt_error && (err == EAGAIN))
{
return true;
}
-#endif
#if 0 /* if enabled, suppress ENOBUFS errors */
#ifdef ENOBUFS
return err & M_FATAL ? (err ^ M_FATAL) | M_NONFATAL : err;
}
+static inline int
+openvpn_errno_maybe_crt(bool *crt_error)
+{
+ int err = 0;
+ *crt_error = false;
+#ifdef _WIN32
+ err = GetLastError();
+ if (err == ERROR_SUCCESS)
+ {
+ /* error is likely C runtime */
+ *crt_error = true;
+ err = errno;
+ }
+#else
+ *crt_error = true;
+ err = errno;
+#endif
+ return err;
+}
+
#include "errlevel.h"
#endif /* ifndef ERROR_H */
static bool
man_io_error(struct management *man, const char *prefix)
{
- const int err = openvpn_errno();
+ bool crt_error = false;
+ int err = openvpn_errno_maybe_crt(&crt_error);
- if (!ignore_sys_error(err))
+ if (!ignore_sys_error(err, crt_error))
{
struct gc_arena gc = gc_new();
msg(D_MANAGEMENT, "MANAGEMENT: TCP %s error: %s", prefix,