From e07ac713b388f6ea44a0891241ae7c67959bc3c8 Mon Sep 17 00:00:00 2001 From: Alexandre Oliva Date: Tue, 30 Jul 2013 05:34:15 -0300 Subject: Grow the netlink buffer and retry instead of failing getifaddrs for ChangeLog * sysdeps/unix/sysv/linux/ifaddrs.c (__netlink_request): Grow buffer and retry when message is fragmented. --- sysdeps/unix/sysv/linux/ifaddrs.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/sysdeps/unix/sysv/linux/ifaddrs.c b/sysdeps/unix/sysv/linux/ifaddrs.c index 89fda156a2..c9decc30e4 100644 --- a/sysdeps/unix/sysv/linux/ifaddrs.c +++ b/sysdeps/unix/sysv/linux/ifaddrs.c @@ -135,13 +135,14 @@ __netlink_request (struct netlink_handle *h, int type) #ifdef PAGE_SIZE /* Help the compiler optimize out the malloc call if PAGE_SIZE is constant and smaller or equal to PTHREAD_STACK_MIN/4. */ - const size_t buf_size = PAGE_SIZE; + size_t buf_size = PAGE_SIZE; #else - const size_t buf_size = __getpagesize (); + size_t buf_size = __getpagesize (); #endif bool use_malloc = false; char *buf; + retry: if (__libc_use_alloca (buf_size)) buf = alloca (buf_size); else @@ -176,7 +177,23 @@ __netlink_request (struct netlink_handle *h, int type) continue; if (__builtin_expect (msg.msg_flags & MSG_TRUNC, 0)) - goto out_fail; + { + /* Consume the rest of the truncated response, then retry + with a larger buffer. */ + do + { + read_len = TEMP_FAILURE_RETRY (__recvmsg (h->fd, &msg, 0)); + if (read_len < 0) + break; + buf_size += read_len; + } + while ((msg.msg_flags & MSG_TRUNC) != 0); + + if (use_malloc) + free (buf); + goto retry; + } + size_t count = 0; size_t remaining_len = read_len; -- cgit v1.2.1