From a31e1628b1f73e6fa2d3cb9754b9dcdcd45c13e7 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Aug 14 2006 20:35:18 +0000 Subject: - fix for ppc64 --- diff --git a/libnl-1.0-pre5-nl_recv.patch b/libnl-1.0-pre5-nl_recv.patch new file mode 100644 index 0000000..92f02d5 --- /dev/null +++ b/libnl-1.0-pre5-nl_recv.patch @@ -0,0 +1,197 @@ +--- 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) + + /** diff --git a/libnl.spec b/libnl.spec index 4d95bc6..a706e71 100644 --- a/libnl.spec +++ b/libnl.spec @@ -5,7 +5,7 @@ Group: Development/Libraries License: LGPL Name: libnl Version: 1.0 -Release: 0.10.%{preversion}.3 +Release: 0.10.%{preversion}.4 URL: http://people.suug.ch/~tgr/libnl/ Source: http://people.suug.ch/~tgr/libnl/files/libnl-%{version}-%{preversion}.tar.gz BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root @@ -15,6 +15,7 @@ Patch2: libnl-1.0-install-no-root.patch Patch3: libnl-1.0-pre5-static.patch Patch4: libnl-1.0-pre5-__u64_x86_64.patch Patch5: libnl-1.0-pre5-debuginfo.patch +Patch6: libnl-1.0-pre5-nl_recv.patch %description This package contains a convenience library to simplify @@ -37,6 +38,7 @@ This package contains various headers for using libnl %patch3 -p1 %patch4 -p1 %patch5 -p1 +%patch6 -p1 %build %configure @@ -82,6 +84,9 @@ EOF %{_libdir}/pkgconfig/%{name}-1.pc %changelog +* Mon Aug 14 2006 Peter Jones - 1.0-0.10.pre5.4 +- Fix nl_recv() for ppc64 + * Mon Jul 31 2006 Jeremy Katz - 1.0-0.10.pre5.3 - unbreak the pkgconfig file