Blob Blame History Raw
--- 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)
 
 /**