aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--sysdeps/posix/getaddrinfo.c27
2 files changed, 27 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index 67465e8..0ee9a24 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2007-10-17 Jakub Jelinek <jakub@redhat.com>
+
+ * sysdeps/posix/getaddrinfo.c (getaddrinfo): When sorting addresses
+ and admin selects to be able to replace the gai.conf file, lock
+ data structures around the qsort call.
+
2007-10-17 Ulrich Drepper <drepper@redhat.com>
* sysdeps/x86_64/cacheinfo.c: Comment out code added in support of
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
index 8f37ec5..8cf9c6b 100644
--- a/sysdeps/posix/getaddrinfo.c
+++ b/sysdeps/posix/getaddrinfo.c
@@ -1426,10 +1426,13 @@ in6aicmp (const void *p1, const void *p2)
#define GAICONF_FNAME "/etc/gai.conf"
-/* Nozero if we are supposed to reload the config file automatically
+/* Non-zero if we are supposed to reload the config file automatically
whenever it changed. */
static int gaiconf_reload_flag;
+/* Non-zero if gaiconf_reload_flag was ever set to true. */
+static int gaiconf_reload_flag_ever_set;
+
/* Last modification time. */
static struct timespec gaiconf_mtime;
@@ -1611,7 +1614,11 @@ gaiconf_init (void)
case 6:
if (strcmp (cmd, "reload") == 0)
- gaiconf_reload_flag = strcmp (val1, "yes") == 0;
+ {
+ gaiconf_reload_flag = strcmp (val1, "yes") == 0;
+ if (gaiconf_reload_flag)
+ gaiconf_reload_flag_ever_set = 1;
+ }
break;
case 10:
@@ -1934,9 +1941,6 @@ getaddrinfo (const char *name, const char *service,
__libc_once_define (static, once);
__typeof (once) old_once = once;
__libc_once (once, gaiconf_init);
- if (old_once && gaiconf_reload_flag)
- gaiconf_reload ();
-
/* Sort results according to RFC 3484. */
struct sort_result results[nresults];
struct addrinfo *q;
@@ -2055,7 +2059,18 @@ getaddrinfo (const char *name, const char *service,
/* We got all the source addresses we can get, now sort using
the information. */
- qsort (results, nresults, sizeof (results[0]), rfc3484_sort);
+ if (__builtin_expect (gaiconf_reload_flag_ever_set, 0))
+ {
+ __libc_lock_define_initialized (static, lock);
+
+ __libc_lock_lock (lock);
+ if (old_once && gaiconf_reload_flag)
+ gaiconf_reload ();
+ qsort (results, nresults, sizeof (results[0]), rfc3484_sort);
+ __libc_lock_unlock (lock);
+ }
+ else
+ qsort (results, nresults, sizeof (results[0]), rfc3484_sort);
/* Queue the results up as they come out of sorting. */
q = p = results[0].dest_addr;