#include <config.h>
#include "socket-util.h"
#include <arpa/inet.h>
-#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <net/if.h>
: EINVAL);
}
-/* Returns the error condition associated with socket 'fd' and resets the
- * socket's error status. */
-int
-get_socket_error(int fd)
-{
- int error;
-
- if (getsockopt_int(fd, SOL_SOCKET, SO_ERROR, "SO_ERROR", &error)) {
- error = errno;
- }
- return error;
-}
-
int
check_connection_completion(int fd)
{
+ static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 10);
struct pollfd pfd;
int retval;
retval = poll(&pfd, 1, 0);
} while (retval < 0 && errno == EINTR);
if (retval == 1) {
- return get_socket_error(fd);
+ if (pfd.revents & POLLERR) {
+ ssize_t n = send(fd, "", 1, MSG_DONTWAIT);
+ if (n < 0) {
+ return errno;
+ } else {
+ VLOG_ERR_RL(&rl, "poll return POLLERR but send succeeded");
+ return EPROTO;
+ }
+ }
+ return 0;
} else if (retval < 0) {
- static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 10);
VLOG_ERR_RL(&rl, "poll: %s", strerror(errno));
return errno;
} else {
* it will only happen if style is SOCK_STREAM or SOCK_SEQPACKET, and only
* if a backlog of un-accepted connections has built up in the kernel.) */
if (nonblock) {
- int flags = fcntl(fd, F_GETFL, 0);
- if (flags == -1) {
- error = errno;
- goto error;
- }
- if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) {
- error = errno;
+ error = set_nonblocking(fd);
+ if (error) {
goto error;
}
}
}
} else if (fd >= 0) {
close(fd);
+ fd = -1;
}
*fdp = fd;
return error;
memcpy(&sin, &ss, sizeof sin);
ds_put_format(string, IP_FMT":%"PRIu16,
- IP_ARGS(&sin.sin_addr.s_addr), ntohs(sin.sin_port));
+ IP_ARGS(sin.sin_addr.s_addr), ntohs(sin.sin_port));
} else if (ss.ss_family == AF_UNIX) {
struct sockaddr_un sun;
const char *null;
const struct iovec *iovs, size_t n_iovs,
const int fds[], size_t n_fds)
{
- assert(sock >= 0);
+ ovs_assert(sock >= 0);
if (n_fds > 0) {
union {
struct cmsghdr cm;
} cmsg;
struct msghdr msg;
- assert(!iovec_is_empty(iovs, n_iovs));
- assert(n_fds <= SOUTIL_MAX_FDS);
+ ovs_assert(!iovec_is_empty(iovs, n_iovs));
+ ovs_assert(n_fds <= SOUTIL_MAX_FDS);
memset(&cmsg, 0, sizeof cmsg);
cmsg.cm.cmsg_len = CMSG_LEN(n_fds * sizeof *fds);
msg.msg_name = NULL;
msg.msg_namelen = 0;
- msg.msg_iov = (struct iovec *) iovs;
+ msg.msg_iov = CONST_CAST(struct iovec *, iovs);
msg.msg_iovlen = n_iovs;
msg.msg_control = &cmsg.cm;
msg.msg_controllen = CMSG_SPACE(n_fds * sizeof *fds);
size_t n_fds = (p->cmsg_len - CMSG_LEN(0)) / sizeof *fds;
const int *fds_data = (const int *) CMSG_DATA(p);
- assert(n_fds > 0);
+ ovs_assert(n_fds > 0);
if (n_fds > SOUTIL_MAX_FDS) {
VLOG_ERR("%zu fds received but only %d supported",
n_fds, SOUTIL_MAX_FDS);