> + retval = recvmsg(sock, &msg, 0); > + } while (retval < 0 && errno == EINTR); > + if (retval <= 0) { > + return retval < 0 ? -errno : 0; > + } > + > + for (p = CMSG_FIRSTHDR(&msg); p; p = CMSG_NXTHDR(&msg, p)) { > + if (p->cmsg_level != SOL_SOCKET || p->cmsg_type != SCM_RIGHTS) { > + VLOG_ERR("unexpected control message %d:%d", > + (int) p->cmsg_level, (int) p->cmsg_type);
Are the casts necessary here? At least in the sparse version of the header the type is int. > + goto error; > + } else if (*n_fdsp) { > + VLOG_ERR("multiple SCM_RIGHTS received"); > + goto error; > + } else { > + 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); > + if (n_fds > SOUTIL_MAX_FDS) { > + VLOG_ERR("%zu fds received but only %d supported", > + n_fds, SOUTIL_MAX_FDS); > + for (i = 0; i < n_fds; i++) { > + close(fds_data[i]); > + } > + goto error; > + } > + > + *n_fdsp = n_fds; > + memcpy(fds, fds_data, n_fds * sizeof *fds); > + } > + } > + > + return retval; > + > +error: > + for (i = 0; i < *n_fdsp; i++) { > + close(fds[i]); > + } This doesn't seem right to me. fds is only written to when there's no error. Really this should be closing the file descriptors in fds_data, but that's done already. If it turns out this is unnecessary we can probably remove the goto altogether and just use return EPROTO. Ethan > + *n_fdsp = 0; > + return EPROTO; > +} > diff --git a/lib/socket-util.h b/lib/socket-util.h > index e2e0d9a..a0e7970 100644 > --- a/lib/socket-util.h > +++ b/lib/socket-util.h > @@ -71,4 +71,28 @@ char *describe_fd(int fd); > * in <netinet/ip.h> is used. */ > #define DSCP_DEFAULT (IPTOS_PREC_INTERNETCONTROL >> 2) > > +/* Maximum number of fds that we support sending or receiving at one time > + * across a Unix domain socket. */ > +#define SOUTIL_MAX_FDS 8 > + > +/* Iovecs. */ > +size_t iovec_len(const struct iovec *iovs, size_t n_iovs); > +bool iovec_is_empty(const struct iovec *iovs, size_t n_iovs); > + > +/* Functions particularly useful for Unix domain sockets. */ > +void xsocketpair(int domain, int type, int protocol, int fds[2]); > +int send_iovec_and_fds(int sock, > + const struct iovec *iovs, size_t n_iovs, > + const int fds[], size_t n_fds); > +int send_iovec_and_fds_fully(int sock, > + const struct iovec *iovs, size_t n_iovs, > + const int fds[], size_t n_fds, > + size_t skip_bytes, size_t *bytes_sent); > +int send_iovec_and_fds_fully_block(int sock, > + const struct iovec *iovs, size_t n_iovs, > + const int fds[], size_t n_fds); > +int recv_data_and_fds(int sock, > + void *data, size_t size, > + int fds[SOUTIL_MAX_FDS], size_t *n_fdsp); > + > #endif /* socket-util.h */ > -- > 1.7.2.5 > > _______________________________________________ > dev mailing list > dev@openvswitch.org > http://openvswitch.org/mailman/listinfo/dev _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev