--- libnl-1.0-pre5/lib/attr.c.nl_recv 2006-08-14 05:36:27.000000000 -0400
+++ libnl-1.0-pre5/lib/attr.c 2006-08-14 05:36:43.000000000 -0400
@@ -504,7 +504,7 @@
nla = nla_reserve(n, attrtype, attrlen);
if (!nla)
- return nl_errno(ENOMEM);
+ return -nl_get_errno();
memcpy(nla_data(nla), data, attrlen);
--- libnl-1.0-pre5/lib/nl.c.nl_recv 2006-08-14 05:36:27.000000000 -0400
+++ libnl-1.0-pre5/lib/nl.c 2006-08-14 05:40:48.000000000 -0400
@@ -569,14 +569,16 @@
*
* @return Number of octets read, 0 on EOF or a negative error code.
*/
+
+
int nl_recv(struct nl_handle *handle, struct sockaddr_nl *nla,
unsigned char **buf)
{
- int n;
- int flags = MSG_PEEK;
+ int n = -1;
+ int flags = MSG_PEEK | MSG_WAITALL;
struct iovec iov = {
- .iov_len = 4096,
+ .iov_len = 256,
};
struct msghdr msg = {
@@ -589,47 +591,61 @@
.msg_flags = 0,
};
- iov.iov_base = *buf = calloc(1, iov.iov_len);
+ iov.iov_base = calloc(1, iov.iov_len);
+ if (iov.iov_base == NULL)
+ return nl_error(errno, "calloc failed");
+
+ do {
+ if (!(n = recvmsg(handle->h_fd, &msg, flags)))
+ break;
+ if (n < 0) {
+ if (errno == EINTR || errno == EAGAIN) {
+ n = -1;
+ continue;
+ } else if (errno == ENOBUFS) {
+ n = -1;
+ continue;
+ } else {
+ n = nl_error(errno, "recvmsg failed");
+ break;
+ }
+ }
-retry:
+ if (msg.msg_flags & MSG_TRUNC) {
+ unsigned char *tbuf = iov.iov_base;
- if ((n = recvmsg(handle->h_fd, &msg, flags)) <= 0) {
- if (!n)
- goto abort;
- else if (n < 0) {
- if (errno == EINTR)
- goto retry;
- else if (errno == EAGAIN)
- goto abort;
- else {
- free(*buf);
- return nl_error(errno, "recvmsg failed");
+ /* Provided buffer is not long enough, enlarge it
+ * and try again. */
+ iov.iov_len += 256;
+ iov.iov_base = realloc(tbuf, iov.iov_len);
+ if (!iov.iov_base) {
+ n = nl_error(errno, "realloc failed");
+ iov.iov_base = NULL;
+ memset(tbuf, '\0', sizeof (*tbuf));
+ free(tbuf);
+ break;
}
+ n = -1;
+ continue;
}
- }
-
- if (iov.iov_len < n) {
- /* Provided buffer is not long enough, enlarge it
- * and try again. */
- iov.iov_len *= 2;
- iov.iov_base = *buf = realloc(*buf, iov.iov_len);
- goto retry;
- } else if (flags != 0) {
- /* Buffer is big enough, do the actual reading */
- flags = 0;
- goto retry;
- }
- if (msg.msg_namelen != sizeof(struct sockaddr_nl)) {
- free(*buf);
- return nl_error(EADDRNOTAVAIL, "socket address size mismatch");
- }
+ if (msg.msg_namelen != sizeof(struct sockaddr_nl)) {
+ n = nl_error(EADDRNOTAVAIL, "socket address size mismatch");
+ memset(iov.iov_base, '\0', iov.iov_len);
+ free(iov.iov_base);
+ iov.iov_base = NULL;
+ break;
+ }
- return n;
+ if (n > 0 && (flags & MSG_PEEK)) {
+ flags &= ~MSG_PEEK;
+ n = -1;
+ }
+ } while (n < 0);
-abort:
- free(*buf);
- return 0;
+ if (iov.iov_base)
+ *buf = iov.iov_base;
+ return n;
}
@@ -652,7 +668,7 @@
int n, err = 0;
unsigned char *buf = NULL;
struct nlmsghdr *hdr;
- struct sockaddr_nl nla = {0};
+ struct sockaddr_nl nla = { 16, 0, 0, 0 };
continue_reading:
if (cb->cb_recv_ow)
@@ -665,7 +681,6 @@
hdr = (struct nlmsghdr *) buf;
while (nlmsg_ok(hdr, n)) {
-
/* 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]) {
--- libnl-1.0-pre5/lib/utils.c.nl_recv 2006-08-14 05:36:27.000000000 -0400
+++ libnl-1.0-pre5/lib/utils.c 2006-08-14 05:42:00.000000000 -0400
@@ -36,7 +36,7 @@
int __nl_error(int err, const char *file, unsigned int line, const char *func,
const char *fmt, ...)
{
- char *user_err;
+ char *user_err = NULL;
va_list args;
if (errbuf) {
@@ -54,13 +54,13 @@
#ifdef VERBOSE_ERRORS
asprintf(&errbuf, "%s:%u:%s: %s (errno = %s)",
- file, line, func, fmt ? user_err : "", strerror(err));
+ file, line, func, user_err ? user_err : "", strerror(err));
#else
asprintf(&errbuf, "%s (errno = %s)",
- fmt ? user_err : "", strerror(err));
+ user_err ? user_err : "", strerror(err));
#endif
- if (fmt)
+ if (user_err)
free(user_err);
return -err;
@@ -79,7 +79,9 @@
*/
char *nl_geterror(void)
{
- return errbuf ? : "Success\n";
+ if (!errbuf)
+ return strerror(nlerrno);
+ return errbuf;
}
/** @} */
--- libnl-1.0-pre5/include/netlink/attr.h.nl_recv 2006-08-14 05:36:28.000000000 -0400
+++ libnl-1.0-pre5/include/netlink/attr.h 2006-08-14 05:36:44.000000000 -0400
@@ -164,8 +164,7 @@
*/
#define NLA_PUT_TYPE(n, type, attrtype, value) \
do { \
- type __tmp = value; \
- NLA_PUT(n, attrtype, sizeof(type), &__tmp); \
+ NLA_PUT(n, attrtype, sizeof(type), &(value)); \
} while(0)
/**