#include <unistd.h>
#include "dynamic-string.h"
#include "fatal-signal.h"
+#include "ovs-thread.h"
#include "packets.h"
#include "poll-loop.h"
#include "util.h"
* space for a null terminator. */
#define MAX_UN_LEN (sizeof(((struct sockaddr_un *) 0)->sun_path) - 1)
+#ifdef _WIN32
+/* Buffer used by sock_strerror(). */
+DEFINE_STATIC_PER_THREAD_DATA(struct { char s[128]; },
+ sockerror_buffer,
+ { "" });
+#endif
+
static int getsockopt_int(int fd, int level, int option, const char *optname,
int *valuep);
OVS_NOT_REACHED();
}
}
+
+/* For Windows socket calls, 'errno' is not set. One has to call
+ * WSAGetLastError() to get the error number and then pass it to
+ * FormatMessage() (through this function) to get the correct error string.
+
+ * ovs_strerror() calls strerror_r() and would not get the correct error
+ * string for Windows sockets, but is good for POSIX. */
+const char *
+sock_strerror(int error)
+{
+#ifdef _WIN32
+ enum { BUFSIZE = sizeof sockerror_buffer_get()->s };
+ char *buffer = sockerror_buffer_get()->s;
+
+ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
+ | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, error, 0,
+ buffer, BUFSIZE, NULL);
+ return buffer;
+#else
+ return ovs_strerror(error);
+#endif
+}
char *ss_format_address(const struct sockaddr_storage *,
char *buf, size_t bufsize);
size_t ss_length(const struct sockaddr_storage *);
+const char *sock_strerror(int error);
#endif /* socket-util.h */
: ovs_strerror(retval));
}
+/* This function returns the string describing the error number in 'error'
+ * for POSIX platforms. For Windows, this function can be used for C library
+ * calls. For socket calls that are also used in Windows, use sock_strerror()
+ * instead. For WINAPI calls, look at ovs_lasterror_to_string(). */
const char *
ovs_strerror(int error)
{