This is the mail archive of the
libc-alpha@sources.redhat.com
mailing list for the glibc project.
bug in __ifreq
- From: Bruno Haible <bruno at clisp dot org>
- To: libc-alpha at sources dot redhat dot com
- Date: Fri, 20 Sep 2002 16:22:03 +0200 (CEST)
- Subject: bug in __ifreq
The __ifreq implementations have a bug in the termination condition,
which causes them to never return more than 4 interfaces. Which you might
not notice on Linux, but on FreeBSD you see it because FreeBSD has a dozen
of interfaces configured into the kernel by default.
2002-09-17 Bruno Haible <bruno@clisp.org>
* sysdeps/generic/ifreq.h (__ifreq): Compute termination condition
before doubling rq_len.
* sysdeps/unix/sysv/linux/ifreq.h (__ifreq): Likewise.
diff -r -c3 glibc-20020910.bak/sysdeps/generic/ifreq.h glibc-20020910/sysdeps/generic/ifreq.h
*** glibc-20020910.bak/sysdeps/generic/ifreq.h Thu Jul 25 13:18:17 2002
--- glibc-20020910/sysdeps/generic/ifreq.h Tue Sep 17 02:22:05 2002
***************
*** 45,51 ****
ifc.ifc_buf = NULL;
rq_len = RQ_IFS * sizeof (struct ifreq);
! do
{
ifc.ifc_len = rq_len;
ifc.ifc_buf = realloc (ifc.ifc_buf, ifc.ifc_len);
--- 45,51 ----
ifc.ifc_buf = NULL;
rq_len = RQ_IFS * sizeof (struct ifreq);
! for (;;)
{
ifc.ifc_len = rq_len;
ifc.ifc_buf = realloc (ifc.ifc_buf, ifc.ifc_len);
***************
*** 60,68 ****
*ifreqs = NULL;
return;
}
rq_len *= 2;
}
- while (rq_len < sizeof (struct ifreq) + ifc.ifc_len);
nifs = ifc.ifc_len / sizeof (struct ifreq);
--- 60,69 ----
*ifreqs = NULL;
return;
}
+ if (ifc.ifc_len + sizeof (struct ifreq) <= rq_len)
+ break;
rq_len *= 2;
}
nifs = ifc.ifc_len / sizeof (struct ifreq);
diff -r -c3 glibc-20020910.bak/sysdeps/unix/sysv/linux/ifreq.h glibc-20020910/sysdeps/unix/sysv/linux/ifreq.h
*** glibc-20020910.bak/sysdeps/unix/sysv/linux/ifreq.h Thu Jul 25 13:18:34 2002
--- glibc-20020910/sysdeps/unix/sysv/linux/ifreq.h Tue Sep 17 02:22:07 2002
***************
*** 73,79 ****
rq_len = RQ_IFS * sizeof (struct ifreq);
/* Read all the interfaces out of the kernel. */
! do
{
ifc.ifc_len = rq_len;
ifc.ifc_buf = realloc (ifc.ifc_buf, ifc.ifc_len);
--- 73,79 ----
rq_len = RQ_IFS * sizeof (struct ifreq);
/* Read all the interfaces out of the kernel. */
! for (;;)
{
ifc.ifc_len = rq_len;
ifc.ifc_buf = realloc (ifc.ifc_buf, ifc.ifc_len);
***************
*** 89,97 ****
*ifreqs = NULL;
return;
}
rq_len *= 2;
}
- while (ifc.ifc_len == rq_len && old_siocgifconf);
nifs = ifc.ifc_len / sizeof (struct ifreq);
--- 89,98 ----
*ifreqs = NULL;
return;
}
+ if (!old_siocgifconf || ifc.ifc_len < rq_len)
+ break;
rq_len *= 2;
}
nifs = ifc.ifc_len / sizeof (struct ifreq);