summaryrefslogtreecommitdiffstats
path: root/isys
diff options
context:
space:
mode:
authorPeter Jones <pjones@redhat.com>2007-09-13 22:11:44 +0000
committerPeter Jones <pjones@redhat.com>2007-09-13 22:11:44 +0000
commit9399e046d61aa91b3b671ba7b8b7671de1404169 (patch)
tree9a6d189497ef44ac3d76609babe37383a91707d9 /isys
parent7f9fb698ec1c15ba2d1519fa950ed95af418b304 (diff)
downloadanaconda-9399e046d61aa91b3b671ba7b8b7671de1404169.tar.gz
anaconda-9399e046d61aa91b3b671ba7b8b7671de1404169.tar.xz
anaconda-9399e046d61aa91b3b671ba7b8b7671de1404169.zip
- another recvfrom() rewrite, this one doesn't rely on MSG_TRUNC working.
Diffstat (limited to 'isys')
-rw-r--r--isys/nl.c58
1 files changed, 40 insertions, 18 deletions
diff --git a/isys/nl.c b/isys/nl.c
index dec359ccf..041b2cb79 100644
--- a/isys/nl.c
+++ b/isys/nl.c
@@ -187,19 +187,30 @@ int netlink_get_interface_ip(int index, int family, void *addr) {
return ret < 0 ? -1 : 0;
}
- while ((bufsz = recvfrom(sock, NULL, 0, MSG_PEEK|MSG_TRUNC|MSG_WAITALL,
- NULL, 0)) <= 0) {
- if (bufsz < 0) {
- if (errno == EAGAIN)
- continue;
+ /* MSG_TRUNC doesn't actually seem to /work/ with netlink on RHEL 5,
+ * so we do this lame growth game until we have a buffer big enough.
+ * When we're done (which is the first time if MSG_TRUNC does its job),
+ * bufsz is the size of the message. Then we allocate a real buffer and
+ * do recvfrom again without MSG_PEEK. */
+ len = 32;
+ do {
+ len <<= 1;
+ char tmpbuf[len];
+ bufsz = recvfrom(sock, tmpbuf, len, MSG_PEEK|MSG_TRUNC|MSG_WAITALL,
+ NULL, 0);
+ if (bufsz < 0 && errno == EAGAIN)
+ bufsz = len;
+ } while (bufsz == len);
+
+ if (bufsz <= 0) {
+ if (bufsz < 0)
perror("1st recvfrom in netlink_get_interface_ip");
- }
close(sock);
- return bufsz < 0 ? -1 : 0;
+ return -1;
}
if ((buf = alloca(bufsz)) == NULL) {
- perror("calloc on msg buf in netlink_get_interface_ip");
+ perror("alloca on msg buf in netlink_get_interface_ip");
close(sock);
return -1;
}
@@ -308,19 +319,30 @@ int netlink_init_interfaces_list(void) {
return r < 0 ? -1 : r;
}
- while ((bufsz = recvfrom(sock, NULL, 0, MSG_PEEK|MSG_TRUNC|MSG_WAITALL,
- NULL, 0)) <= 0) {
- if (bufsz < 0) {
- if (errno == EAGAIN)
- continue;
- perror("1st recvfrom in netlink_get_interface_list");
- }
- close(sock);
- return bufsz < 0 ? -1 : bufsz;
+ /* MSG_TRUNC doesn't actually seem to /work/ with netlink on RHEL 5,
+ * so we do this lame growth game until we have a buffer big enough.
+ * When we're done (which is the first time if MSG_TRUNC does its job),
+ * bufsz is the size of the message. Then we allocate a real buffer and
+ * do recvfrom again without MSG_PEEK. */
+ len = 32;
+ do {
+ len <<= 1;
+ char tmpbuf[len];
+ bufsz = recvfrom(sock, tmpbuf, len, MSG_PEEK|MSG_TRUNC|MSG_WAITALL,
+ NULL, 0);
+ if (bufsz < 0 && errno == EAGAIN)
+ bufsz = len;
+ } while (bufsz == len);
+
+ if (bufsz <= 0) {
+ if (bufsz < 0)
+ perror("1st recvfrom in netlink_get_interface_list");
+ close(sock);
+ return -1;
}
if ((buf = alloca(bufsz)) == NULL) {
- perror("calloc on msg buf in netlink_get_interface_list");
+ perror("alloca on msg buf in netlink_get_interface_list");
close(sock);
return -1;
}