diff options
author | Ulrich Drepper <drepper@redhat.com> | 2007-03-05 20:32:32 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2007-03-05 20:32:32 +0000 |
commit | 0b3b1a0ce81276e92b25f71a11602ae1dd014015 (patch) | |
tree | 7a6c81787f7e9894d396b6e34655ad77cb0e2789 /sysdeps | |
parent | c1c5e654bcf7884e79c7911001b496ca7f43c1a9 (diff) | |
download | glibc-0b3b1a0ce81276e92b25f71a11602ae1dd014015.zip glibc-0b3b1a0ce81276e92b25f71a11602ae1dd014015.tar.gz glibc-0b3b1a0ce81276e92b25f71a11602ae1dd014015.tar.bz2 |
* sysdeps/unix/sysv/linux/ifaddrs.c (__netlink_request): Retry with
a new netlink socket if NLMSG_ERR -EBUSY is seen after some MSG_TRUNC
message.
Diffstat (limited to 'sysdeps')
-rw-r--r-- | sysdeps/unix/sysv/linux/ifaddrs.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/sysdeps/unix/sysv/linux/ifaddrs.c b/sysdeps/unix/sysv/linux/ifaddrs.c index e43f39f..6c0f6b3 100644 --- a/sysdeps/unix/sysv/linux/ifaddrs.c +++ b/sysdeps/unix/sysv/linux/ifaddrs.c @@ -135,6 +135,7 @@ __netlink_request (struct netlink_handle *h, int type) return -1; size_t this_buf_size = buf_size; + size_t orig_this_buf_size = this_buf_size; if (__libc_use_alloca (this_buf_size)) buf = alloca (this_buf_size); else @@ -236,6 +237,36 @@ __netlink_request (struct netlink_handle *h, int type) struct nlmsgerr *nlerr = (struct nlmsgerr *) NLMSG_DATA (nlmh); if (nlmh->nlmsg_len < NLMSG_LENGTH (sizeof (struct nlmsgerr))) errno = EIO; + else if (nlerr->error == -EBUSY + && orig_this_buf_size != this_buf_size) + { + /* If EBUSY and MSG_TRUNC was seen, try again with a new + netlink socket. */ + struct netlink_handle hold = *h; + if (__netlink_open (h) < 0) + { + *h = hold; + goto out_fail; + } + __netlink_close (&hold); + orig_this_buf_size = this_buf_size; + nlm_next = *new_nlm_list; + while (nlm_next != NULL) + { + struct netlink_res *tmpptr; + + tmpptr = nlm_next->next; + free (nlm_next); + nlm_next = tmpptr; + } + *new_nlm_list = NULL; + count = 0; + h->seq++; + + if (__netlink_sendreq (h, type) < 0) + goto out_fail; + break; + } else errno = -nlerr->error; goto out_fail; |