summaryrefslogtreecommitdiffstats
path: root/isys
diff options
context:
space:
mode:
authorPeter Jones <pjones@redhat.com>2007-09-06 15:17:45 +0000
committerPeter Jones <pjones@redhat.com>2007-09-06 15:17:45 +0000
commitf79f9ae3c1c9bc74df2d447b02264d8021621dd4 (patch)
tree3fcf7745eef5719386bb9b0fb15f1edbe4c0523d /isys
parent296f45ab04b828d9d3ee425dbba1489809caa206 (diff)
downloadanaconda-f79f9ae3c1c9bc74df2d447b02264d8021621dd4.tar.gz
anaconda-f79f9ae3c1c9bc74df2d447b02264d8021621dd4.tar.xz
anaconda-f79f9ae3c1c9bc74df2d447b02264d8021621dd4.zip
rework netlink_get_interface_ip to handle large recvfrom() responses
without doing its own buffering or leaking memory.
Diffstat (limited to 'isys')
-rw-r--r--isys/nl.c41
1 files changed, 18 insertions, 23 deletions
diff --git a/isys/nl.c b/isys/nl.c
index 0d19ad038..771ee2947 100644
--- a/isys/nl.c
+++ b/isys/nl.c
@@ -257,7 +257,8 @@ int netlink_get_interface_ip(int index, int family, void *addr) {
* @return 0 on succes, -1 on error.
*/
int netlink_init_interfaces_list(void) {
- int sock, len, alen, r, bufsz, readsz, havemsg, namelen;
+ int sock, len, alen, r, namelen;
+ ssize_t bufsz, readsz;
char *buf = NULL;
struct nlmsghdr *nlh;
struct ifinfomsg *ifi;
@@ -283,34 +284,28 @@ int netlink_init_interfaces_list(void) {
return -1;
}
- /* read back messages */
- if ((buf = calloc(BUFSZ, sizeof(char))) == NULL) {
- perror("calloc on 1st buf in netlink_init_interfaces_list");
+ while ((bufsz = recvfrom(sock, NULL, 0, MSG_PEEK|MSG_TRUNC|MSG_WAITALL,
+ NULL, 0)) <= 0) {
+ if (bufsz < 0 && errno != EAGAIN) {
+ perror("1st recvfrom in netlink_init_interfaces_list");
+ close(sock);
+ return -1;
+ }
+ }
+
+ if ((buf = alloca(bufsz)) == NULL) {
+ perror("calloc on msg buf in netlink_init_interfaces_list");
close(sock);
return -1;
}
+ memset(buf, '\0', bufsz);
- havemsg = 0;
- readsz = BUFSZ;
- while (!havemsg) {
- bufsz = recvfrom(sock, buf, readsz, 0, NULL, 0);
-
- if (bufsz < 0) {
- perror("recvfrom in netlink_init_interfaces_list");
+ recvfrom(sock, buf, bufsz, 0, NULL, 0);
+ while ((readsz = recvfrom(sock, buf, bufsz, MSG_WAITALL, NULL, 0)) < 0) {
+ if (errno != EAGAIN) {
+ perror("2nd recvfrom in netlink_init_interfaces_list");
close(sock);
return -1;
- } else if (bufsz > readsz) {
- free(buf);
- buf = NULL;
-
- readsz = bufsz;
- if ((buf = calloc(readsz, sizeof(char))) == NULL) {
- perror("calloc on 2nd buf in netlink_init_interfaces_list");
- close(sock);
- return -1;
- }
- } else {
- havemsg = 1;
}
}