Looks good. Ethan
On Tue, Sep 27, 2011 at 16:27, Ben Pfaff <[email protected]> wrote: > This will be used in an upcoming commit. > --- > lib/socket-util.c | 60 > ++++++++++++++++++++++++++++++++++++++--------------- > lib/socket-util.h | 1 + > 2 files changed, 44 insertions(+), 17 deletions(-) > > diff --git a/lib/socket-util.c b/lib/socket-util.c > index 65b57ca..6e248c8 100644 > --- a/lib/socket-util.c > +++ b/lib/socket-util.c > @@ -59,6 +59,9 @@ VLOG_DEFINE_THIS_MODULE(socket_util); > #define O_DIRECTORY 0 > #endif > > +static int getsockopt_int(int fd, int level, int option, const char *optname, > + int *valuep); > + > /* Sets 'fd' to non-blocking mode. Returns 0 if successful, otherwise a > * positive errno value. */ > int > @@ -182,11 +185,9 @@ int > get_socket_error(int fd) > { > int error; > - socklen_t len = sizeof(error); > - if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { > - static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 10); > + > + if (getsockopt_int(fd, SOL_SOCKET, SO_ERROR, "SO_ERROR", &error)) { > error = errno; > - VLOG_ERR_RL(&rl, "getsockopt(SO_ERROR): %s", strerror(error)); > } > return error; > } > @@ -221,15 +222,13 @@ check_connection_completion(int fd) > int > drain_rcvbuf(int fd) > { > - socklen_t rcvbuf_len; > - size_t rcvbuf = 0; > + size_t rcvbuf; > > - rcvbuf_len = sizeof rcvbuf; > - if (getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, &rcvbuf_len) < 0) { > - static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 10); > - VLOG_ERR_RL(&rl, "getsockopt(SO_RCVBUF) failed: %s", > strerror(errno)); > - return errno; > + rcvbuf = get_socket_rcvbuf(fd); > + if (rcvbuf < 0) { > + return -rcvbuf; > } > + > while (rcvbuf > 0) { > /* In Linux, specifying MSG_TRUNC in the flags argument causes the > * datagram length to be returned, even if that is longer than the > @@ -250,6 +249,18 @@ drain_rcvbuf(int fd) > return 0; > } > > +/* Returns the size of socket 'sock''s receive buffer (SO_RCVBUF), or a > + * negative errno value if an error occurs. */ > +int > +get_socket_rcvbuf(int sock) > +{ > + int rcvbuf; > + int error; > + > + error = getsockopt_int(sock, SOL_SOCKET, SO_RCVBUF, "SO_RCVBUF", > &rcvbuf); > + return error ? -error : rcvbuf; > +} > + > /* Reads and discards up to 'n' datagrams from 'fd', stopping as soon as no > * more data can be immediately read. ('fd' should therefore be in > * non-blocking mode.)*/ > @@ -846,13 +857,27 @@ xpipe(int fds[2]) > } > > static int > -getsockopt_int(int fd, int level, int optname, int *valuep) > +getsockopt_int(int fd, int level, int option, const char *optname, int > *valuep) > { > - socklen_t len = sizeof *valuep; > + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 10); > + socklen_t len; > + int value; > + int error; > > - return (getsockopt(fd, level, optname, valuep, &len) ? errno > - : len == sizeof *valuep ? 0 > - : EINVAL); > + len = sizeof value; > + if (getsockopt(fd, level, option, &value, &len)) { > + error = errno; > + VLOG_ERR_RL(&rl, "getsockopt(%s): %s", optname, strerror(error)); > + } else if (len != sizeof value) { > + error = EINVAL; > + VLOG_ERR_RL(&rl, "getsockopt(%s): value is %u bytes (expected %zu)", > + optname, (unsigned int) len, sizeof value); > + } else { > + error = 0; > + } > + > + *valuep = error ? 0 : value; > + return error; > } > > static void > @@ -890,7 +915,8 @@ describe_sockaddr(struct ds *string, int fd, > #define SO_PROTOCOL 38 > #endif > > - if (!getsockopt_int(fd, SOL_SOCKET, SO_PROTOCOL, &protocol)) { > + if (!getsockopt_int(fd, SOL_SOCKET, SO_PROTOCOL, "SO_PROTOCOL", > + &protocol)) { > switch (protocol) { > case NETLINK_ROUTE: > ds_put_cstr(string, "NETLINK_ROUTE"); > diff --git a/lib/socket-util.h b/lib/socket-util.h > index 1059139..422cea9 100644 > --- a/lib/socket-util.h > +++ b/lib/socket-util.h > @@ -33,6 +33,7 @@ int lookup_ipv6(const char *host_name, struct in6_addr > *address); > int lookup_hostname(const char *host_name, struct in_addr *); > > int get_socket_error(int sock); > +int get_socket_rcvbuf(int sock); > int check_connection_completion(int fd); > int drain_rcvbuf(int fd); > void drain_fd(int fd, size_t n_packets); > -- > 1.7.4.4 > > _______________________________________________ > dev mailing list > [email protected] > http://openvswitch.org/mailman/listinfo/dev > _______________________________________________ dev mailing list [email protected] http://openvswitch.org/mailman/listinfo/dev
