diff options
author | Ulrich Drepper <drepper@redhat.com> | 2007-10-17 16:05:34 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2007-10-17 16:05:34 +0000 |
commit | fc4837e5d7548b94630054f517eeb13f2cfaf7a9 (patch) | |
tree | 7956a7dc542c86dabdd65a707d964958d460737f /sysdeps | |
parent | 406f28dbe5f8fc70fed76a2fe0112983417ebf60 (diff) | |
download | glibc-fc4837e5d7548b94630054f517eeb13f2cfaf7a9.tar.gz glibc-fc4837e5d7548b94630054f517eeb13f2cfaf7a9.tar.xz glibc-fc4837e5d7548b94630054f517eeb13f2cfaf7a9.zip |
* 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.
Diffstat (limited to 'sysdeps')
-rw-r--r-- | sysdeps/posix/getaddrinfo.c | 27 |
1 files changed, 21 insertions, 6 deletions
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c index 8f37ec5c11..8cf9c6bdfe 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; |