int nl_connect(struct nl_sock *sk, int protocol)
{
int err;
+ int flags = 0;
socklen_t addrlen;
- sk->s_fd = socket(AF_NETLINK, SOCK_RAW, protocol);
+#ifdef SOCK_CLOEXEC
+ flags = SOCK_CLOEXEC;
+#endif
+
+ sk->s_fd = socket(AF_NETLINK, SOCK_RAW | flags, protocol);
if (sk->s_fd < 0) {
err = -nl_syserr2nlerr(errno);
goto errout;
if (nl_cb_call(cb, NL_CB_MSG_OUT, msg) != NL_OK)
return 0;
+ if (sk->s_debug_tx_cb) {
+ nlmsg_set_proto(msg, sk->s_proto);
+ sk->s_debug_tx_cb(sk->s_debug_tx_priv, msg);
+ }
+
ret = sendmsg(sk->s_fd, hdr, 0);
if (ret < 0)
return -nl_syserr2nlerr(errno);
page_size = getpagesize() * 4;
iov.iov_len = page_size;
- iov.iov_base = *buf = malloc(iov.iov_len);
+ iov.iov_base = *buf = calloc(1, iov.iov_len);
+ if (!*buf)
+ return -nl_syserr2nlerr(errno);
if (sk->s_flags & NL_SOCK_PASSCRED) {
msg.msg_controllen = CMSG_SPACE(sizeof(struct ucred));
} else {
free(msg.msg_control);
free(*buf);
+ *buf = NULL;
return -nl_syserr2nlerr(errno);
}
}
- if (iov.iov_len < n ||
+ if (iov.iov_len < (size_t) n ||
msg.msg_flags & MSG_TRUNC) {
/* Provided buffer is not long enough, enlarge it
* and try again. */
if (msg.msg_namelen != sizeof(struct sockaddr_nl)) {
free(msg.msg_control);
free(*buf);
+ *buf = NULL;
return -NLE_NOADDR;
}
abort:
free(msg.msg_control);
free(*buf);
+ *buf = NULL;
return 0;
}
if (n <= 0)
return n;
+ /* make clang analyzer happy */
+ assert(n > 0 && buf);
+
NL_DBG(3, "recvmsgs(%p): Read %d bytes\n", sk, n);
hdr = (struct nlmsghdr *) buf;
if (creds)
nlmsg_set_creds(msg, creds);
+ if (sk->s_debug_rx_cb)
+ sk->s_debug_rx_cb(sk->s_debug_rx_priv, msg);
+
/* Raw callback is the first, it gives the most control
* to the user and he can do his very own parsing. */
if (cb->cb_set[NL_CB_MSG_IN])
else if (hdr->nlmsg_type == NLMSG_ERROR) {
struct nlmsgerr *e = nlmsg_data(hdr);
- if (hdr->nlmsg_len < nlmsg_msg_size(sizeof(*e))) {
+ if (hdr->nlmsg_len < (unsigned) nlmsg_msg_size(sizeof(*e))) {
/* Truncated error message, the default action
* is to stop parsing. The user may overrule
* this action by returning NL_SKIP or
NL_CB_CALL(cb, NL_CB_VALID, msg);
}
skip:
- err = 0;
hdr = nlmsg_next(hdr, &n);
}