GNU C Library master sources branch, master, updated. glibc-2.11-312-gb8b14c4

drepper@sourceware.org drepper@sourceware.org
Sun Apr 4 03:37:00 GMT 2010


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, master has been updated
       via  b8b14c4cc38883032b8ebae50c9a8b3efd256483 (commit)
      from  3ed8e241229e370cca96650ed727f09838c51d67 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://sources.redhat.com/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=b8b14c4cc38883032b8ebae50c9a8b3efd256483

commit b8b14c4cc38883032b8ebae50c9a8b3efd256483
Author: Ulrich Drepper <drepper@redhat.com>
Date:   Sat Apr 3 20:36:59 2010 -0700

    Fix changes to interface list during getifaddrs calls.

diff --git a/ChangeLog b/ChangeLog
index 6420b9d..2b735fc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2010-04-03  Ulrich Drepper  <drepper@redhat.com>
+
+	[BZ #11387]
+	* sysdeps/unix/sysv/linux/ifaddrs.c (map_newlin): Don't abort on
+	unknown interface, return -1.
+	(getifaddrs_internal): Rename from getifaddrs.  Handle errors in
+	map_newlink be returning -EAGAIN.
+	(getifaddrs): If -EAGAIN is returned from getifaddrs_internal try
+	again.
+
 2010-03-25  Ryan S. Arnold  <rsa@us.ibm.com>
 
 	* sysdeps/unix/sysv/linux/getsysstats.c (next_line): Remove
diff --git a/sysdeps/unix/sysv/linux/ifaddrs.c b/sysdeps/unix/sysv/linux/ifaddrs.c
index 149bd1c..84f223d 100644
--- a/sysdeps/unix/sysv/linux/ifaddrs.c
+++ b/sysdeps/unix/sysv/linux/ifaddrs.c
@@ -1,5 +1,5 @@
 /* getifaddrs -- get names and addresses of all network interfaces
-   Copyright (C) 2003-2008, 2009 Free Software Foundation, Inc.
+   Copyright (C) 2003-2008, 2009, 2010 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -315,17 +315,19 @@ map_newlink (int index, struct ifaddrs_storage *ifas, int *map, int max)
       else if (map[i] == index)
 	return i;
     }
-  /* This should never be reached. If this will be reached, we have
-     a very big problem.  */
-  abort ();
+
+  /* This means interfaces changed inbetween the reading of the
+     RTM_GETLINK and RTM_GETADDR information.  We have to repeat
+     everything.  */
+  return -1;
 }
 
 
 /* Create a linked list of `struct ifaddrs' structures, one for each
    network interface on the host machine.  If successful, store the
    list in *IFAP and return 0.  On errors, return -1 and set `errno'.  */
-int
-getifaddrs (struct ifaddrs **ifap)
+static int
+getifaddrs_internal (struct ifaddrs **ifap)
 {
   struct netlink_handle nh = { 0, 0, 0, NULL, NULL };
   struct netlink_res *nlp;
@@ -481,6 +483,13 @@ getifaddrs (struct ifaddrs **ifap)
 		 kernel.  */
 	      ifa_index = map_newlink (ifim->ifi_index - 1, ifas,
 				       map_newlink_data, newlink);
+	      if (__builtin_expect (ifa_index == -1, 0))
+		{
+		try_again:
+		  result = -EAGAIN;
+		  free (ifas);
+		  goto exit_free;
+		}
 	      ifas[ifa_index].ifa.ifa_flags = ifim->ifi_flags;
 
 	      while (RTA_OK (rta, rtasize))
@@ -565,9 +574,11 @@ getifaddrs (struct ifaddrs **ifap)
 		 that we have holes in the interface part of the list,
 		 but we always have already the interface for this address.  */
 	      ifa_index = newlink + newaddr_idx;
-	      ifas[ifa_index].ifa.ifa_flags
-		= ifas[map_newlink (ifam->ifa_index - 1, ifas,
-				    map_newlink_data, newlink)].ifa.ifa_flags;
+	      int idx = map_newlink (ifam->ifa_index - 1, ifas,
+				     map_newlink_data, newlink);
+	      if (__builtin_expect (idx == -1, 0))
+		goto try_again;
+	      ifas[ifa_index].ifa.ifa_flags = ifas[idx].ifa.ifa_flags;
 	      if (ifa_index > 0)
 		ifas[ifa_index - 1].ifa.ifa_next = &ifas[ifa_index].ifa;
 	      ++newaddr_idx;
@@ -747,9 +758,13 @@ getifaddrs (struct ifaddrs **ifap)
 	      /* If we didn't get the interface name with the
 		 address, use the name from the interface entry.  */
 	      if (ifas[ifa_index].ifa.ifa_name == NULL)
-		ifas[ifa_index].ifa.ifa_name
-		  = ifas[map_newlink (ifam->ifa_index - 1, ifas,
-				      map_newlink_data, newlink)].ifa.ifa_name;
+		{
+		  int idx = map_newlink (ifam->ifa_index - 1, ifas,
+					 map_newlink_data, newlink);
+		  if (__builtin_expect (idx == -1, 0))
+		    goto try_again;
+		  ifas[ifa_index].ifa.ifa_name = ifas[idx].ifa.ifa_name;
+		}
 
 	      /* Calculate the netmask.  */
 	      if (ifas[ifa_index].ifa.ifa_addr
@@ -826,6 +841,22 @@ getifaddrs (struct ifaddrs **ifap)
 
   return result;
 }
+
+
+/* Create a linked list of `struct ifaddrs' structures, one for each
+   network interface on the host machine.  If successful, store the
+   list in *IFAP and return 0.  On errors, return -1 and set `errno'.  */
+int
+getifaddrs (struct ifaddrs **ifap)
+{
+  int res;
+
+  do
+    res = getifaddrs_internal (ifap);
+  while (res == -EAGAIN);
+
+  return res;
+}
 libc_hidden_def (getifaddrs)
 
 

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog                         |   10 +++++++
 sysdeps/unix/sysv/linux/ifaddrs.c |   55 +++++++++++++++++++++++++++++--------
 2 files changed, 53 insertions(+), 12 deletions(-)


hooks/post-receive
-- 
GNU C Library master sources



More information about the Glibc-cvs mailing list