* 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);
int
set_nonblocking(int fd)
{
+#ifndef _WIN32
int flags = fcntl(fd, F_GETFL, 0);
if (flags != -1) {
if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) != -1) {
VLOG_ERR("fcntl(F_GETFL) failed: %s", ovs_strerror(errno));
return errno;
}
+#else
+ unsigned long arg = 1;
+ if (ioctlsocket(fd, FIONBIO, &arg)) {
+ int error = sock_errno();
+ VLOG_ERR("set_nonblocking failed: %s", sock_strerror(error));
+ return error;
+ }
+ return 0;
+#endif
}
void
val = dscp << 2;
if (setsockopt(fd, IPPROTO_IP, IP_TOS, &val, sizeof val)) {
- return errno;
+ return sock_errno();
}
return 0;
case EAI_MEMORY:
return ENOMEM;
-#ifdef EAI_NODATA
+#if defined (EAI_NODATA) && EAI_NODATA != EAI_NONAME
case EAI_NODATA:
return ENXIO;
#endif
+#ifdef EAI_SYSTEM
case EAI_SYSTEM:
- return errno;
+ return sock_errno();
+#endif
default:
return EPROTO;
/* Create non-blocking socket. */
fd = socket(ss.ss_family, style, 0);
if (fd < 0) {
- VLOG_ERR("%s: socket: %s", target, ovs_strerror(errno));
- error = errno;
+ error = sock_errno();
+ VLOG_ERR("%s: socket: %s", target, sock_strerror(error));
goto exit;
}
error = set_nonblocking(fd);
* connect(), the handshake SYN frames will be sent with a TOS of 0. */
error = set_dscp(fd, dscp);
if (error) {
- VLOG_ERR("%s: socket: %s", target, ovs_strerror(error));
+ VLOG_ERR("%s: socket: %s", target, sock_strerror(error));
goto exit;
}
/* Connect. */
error = connect(fd, (struct sockaddr *) &ss, ss_length(&ss)) == 0
? 0
- : errno;
- if (error == EINPROGRESS) {
+ : sock_errno();
+ if (error == EINPROGRESS
+#ifdef _WIN32
+ || error == WSAEALREADY || error == WSAEWOULDBLOCK
+#endif
+ ) {
error = EAGAIN;
}
memset(ssp, 0, sizeof *ssp);
}
if (fd >= 0) {
- close(fd);
+ closesocket(fd);
fd = -1;
}
} else {
/* Create non-blocking socket, set SO_REUSEADDR. */
fd = socket(ss.ss_family, style, 0);
if (fd < 0) {
- error = errno;
- VLOG_ERR("%s: socket: %s", target, ovs_strerror(error));
+ error = sock_errno();
+ VLOG_ERR("%s: socket: %s", target, sock_strerror(error));
return -error;
}
error = set_nonblocking(fd);
}
if (style == SOCK_STREAM
&& setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes) < 0) {
- error = errno;
+ error = sock_errno();
VLOG_ERR("%s: setsockopt(SO_REUSEADDR): %s",
- target, ovs_strerror(error));
+ target, sock_strerror(error));
goto error;
}
/* Bind. */
if (bind(fd, (struct sockaddr *) &ss, ss_length(&ss)) < 0) {
- error = errno;
- VLOG_ERR("%s: bind: %s", target, ovs_strerror(error));
+ error = sock_errno();
+ VLOG_ERR("%s: bind: %s", target, sock_strerror(error));
goto error;
}
* connect(), the handshake SYN frames will be sent with a TOS of 0. */
error = set_dscp(fd, dscp);
if (error) {
- VLOG_ERR("%s: socket: %s", target, ovs_strerror(error));
+ VLOG_ERR("%s: socket: %s", target, sock_strerror(error));
goto error;
}
/* Listen. */
if (style == SOCK_STREAM && listen(fd, 10) < 0) {
- error = errno;
- VLOG_ERR("%s: listen: %s", target, ovs_strerror(error));
+ error = sock_errno();
+ VLOG_ERR("%s: listen: %s", target, sock_strerror(error));
goto error;
}
if (ssp || kernel_chooses_port) {
socklen_t ss_len = sizeof ss;
if (getsockname(fd, (struct sockaddr *) &ss, &ss_len) < 0) {
- error = errno;
- VLOG_ERR("%s: getsockname: %s", target, ovs_strerror(error));
+ error = sock_errno();
+ VLOG_ERR("%s: getsockname: %s", target, sock_strerror(error));
goto error;
}
if (kernel_chooses_port) {
if (ssp) {
memset(ssp, 0, sizeof *ssp);
}
- close(fd);
+ closesocket(fd);
return -error;
}
len = sizeof value;
if (getsockopt(fd, level, option, &value, &len)) {
- error = errno;
- VLOG_ERR_RL(&rl, "getsockopt(%s): %s", optname, ovs_strerror(error));
+ error = sock_errno();
+ VLOG_ERR_RL(&rl, "getsockopt(%s): %s", optname, sock_strerror(error));
} else if (len != sizeof value) {
error = EINVAL;
VLOG_ERR_RL(&rl, "getsockopt(%s): value is %u bytes (expected %"PRIuSIZE")",
if (ovsthread_once_start(&once)) {
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0) {
- sock = -errno;
- VLOG_ERR("failed to create inet socket: %s", ovs_strerror(errno));
+ int error = sock_errno();
+ VLOG_ERR("failed to create inet socket: %s", sock_strerror(error));
+ sock = -error;
}
ovsthread_once_done(&once);
}
/* 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.
-
+ * 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;
+ return ovs_format_message(error);
#else
return ovs_strerror(error);
#endif