From a210cae724313604f8cbd49cc6deab1be5239083 Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Mon, 30 Jun 2014 12:03:43 -0700 Subject: [PATCH] Switch to upstream NetBSD nsap_addr.c. These symbols should be public (and Firefox uses them), and we'd also probably rather have the upstream thread-safe implementation. Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1030899 Change-Id: I2a5888fbb3198546848398f576fd2195ff3fe00c --- libc/Android.mk | 2 + .../lib/libc/include/resolv_mt.h | 49 +++++++ .../lib/libc}/inet/nsap_addr.c | 29 ++-- .../lib/libc/resolv/mtctxres.c | 130 ++++++++++++++++++ 4 files changed, 200 insertions(+), 10 deletions(-) create mode 100644 libc/upstream-netbsd/lib/libc/include/resolv_mt.h rename libc/{dns => upstream-netbsd/lib/libc}/inet/nsap_addr.c (81%) create mode 100644 libc/upstream-netbsd/lib/libc/resolv/mtctxres.c diff --git a/libc/Android.mk b/libc/Android.mk index c1a3dff4a..330bb6d7e 100644 --- a/libc/Android.mk +++ b/libc/Android.mk @@ -271,10 +271,12 @@ libc_upstream_netbsd_src_files := \ upstream-netbsd/lib/libc/gen/psignal.c \ upstream-netbsd/lib/libc/gen/utime.c \ upstream-netbsd/lib/libc/gen/utmp.c \ + upstream-netbsd/lib/libc/inet/nsap_addr.c \ upstream-netbsd/lib/libc/regex/regcomp.c \ upstream-netbsd/lib/libc/regex/regerror.c \ upstream-netbsd/lib/libc/regex/regexec.c \ upstream-netbsd/lib/libc/regex/regfree.c \ + upstream-netbsd/lib/libc/resolv/mtctxres.c \ upstream-netbsd/lib/libc/stdlib/bsearch.c \ upstream-netbsd/lib/libc/stdlib/div.c \ upstream-netbsd/lib/libc/stdlib/drand48.c \ diff --git a/libc/upstream-netbsd/lib/libc/include/resolv_mt.h b/libc/upstream-netbsd/lib/libc/include/resolv_mt.h new file mode 100644 index 000000000..73a8dcc18 --- /dev/null +++ b/libc/upstream-netbsd/lib/libc/include/resolv_mt.h @@ -0,0 +1,49 @@ +/* $NetBSD: resolv_mt.h,v 1.1.1.3 2009/04/12 16:35:44 christos Exp $ */ + +#ifndef _RESOLV_MT_H +#define _RESOLV_MT_H + +#include +#include +#include +#include + +/* Access functions for the libresolv private interface */ + +int __res_enable_mt(void); +int __res_disable_mt(void); + +/* Per-thread context */ + +typedef struct { +int no_hosts_fallback_private; +int retry_save; +int retry_private; +char inet_nsap_ntoa_tmpbuf[255*3]; +char sym_ntos_unname[20]; +char sym_ntop_unname[20]; +char p_option_nbuf[40]; +char p_time_nbuf[40]; +char precsize_ntoa_retbuf[sizeof "90000000.00"]; +char loc_ntoa_tmpbuf[sizeof +"1000 60 60.000 N 1000 60 60.000 W -12345678.00m 90000000.00m 90000000.00m 90000000.00m"]; +char p_secstodate_output[15]; +} mtctxres_t; + +/* Thread-specific data (TSD) */ + +mtctxres_t *___mtctxres(void); +#define mtctxres (___mtctxres()) + +/* Various static data that should be TSD */ + +#define sym_ntos_unname (mtctxres->sym_ntos_unname) +#define sym_ntop_unname (mtctxres->sym_ntop_unname) +#define inet_nsap_ntoa_tmpbuf (mtctxres->inet_nsap_ntoa_tmpbuf) +#define p_option_nbuf (mtctxres->p_option_nbuf) +#define p_time_nbuf (mtctxres->p_time_nbuf) +#define precsize_ntoa_retbuf (mtctxres->precsize_ntoa_retbuf) +#define loc_ntoa_tmpbuf (mtctxres->loc_ntoa_tmpbuf) +#define p_secstodate_output (mtctxres->p_secstodate_output) + +#endif /* _RESOLV_MT_H */ diff --git a/libc/dns/inet/nsap_addr.c b/libc/upstream-netbsd/lib/libc/inet/nsap_addr.c similarity index 81% rename from libc/dns/inet/nsap_addr.c rename to libc/upstream-netbsd/lib/libc/inet/nsap_addr.c index 4deabac54..8633205a9 100644 --- a/libc/dns/inet/nsap_addr.c +++ b/libc/upstream-netbsd/lib/libc/inet/nsap_addr.c @@ -1,4 +1,4 @@ -/* $NetBSD: nsap_addr.c,v 1.2 2004/05/20 23:12:33 christos Exp $ */ +/* $NetBSD: nsap_addr.c,v 1.6 2009/04/12 17:07:17 christos Exp $ */ /* * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") @@ -20,12 +20,15 @@ #include #if defined(LIBC_SCCS) && !defined(lint) #if 0 -static const char rcsid[] = "Id: nsap_addr.c,v 1.2.206.1 2004/03/09 08:33:33 marka Exp"; +static const char rcsid[] = "Id: nsap_addr.c,v 1.5 2005/07/28 06:51:48 marka Exp"; #else -__RCSID("$NetBSD: nsap_addr.c,v 1.2 2004/05/20 23:12:33 christos Exp $"); +__RCSID("$NetBSD: nsap_addr.c,v 1.6 2009/04/12 17:07:17 christos Exp $"); #endif #endif /* LIBC_SCCS and not lint */ +#include "port_before.h" + +#include "namespace.h" #include #include #include @@ -36,10 +39,14 @@ __RCSID("$NetBSD: nsap_addr.c,v 1.2 2004/05/20 23:12:33 christos Exp $"); #include #include -#ifdef ANDROID_CHANGES -#include "resolv_private.h" -#else #include +#include + +#include "port_after.h" + +#ifdef __weak_alias +__weak_alias(inet_nsap_addr,_inet_nsap_addr) +__weak_alias(inet_nsap_ntoa,_inet_nsap_ntoa) #endif static char @@ -52,8 +59,8 @@ inet_nsap_addr(const char *ascii, u_char *binary, int maxlen) { u_char c, nib; u_int len = 0; - assert(ascii != NULL); - assert(binary != NULL); + _DIAGASSERT(ascii != NULL); + _DIAGASSERT(binary != NULL); if (ascii[0] != '0' || (ascii[1] != 'x' && ascii[1] != 'X')) return (0); @@ -90,10 +97,10 @@ char * inet_nsap_ntoa(int binlen, const u_char *binary, char *ascii) { int nib; int i; - static char tmpbuf[2+255*3]; + char *tmpbuf = inet_nsap_ntoa_tmpbuf; char *start; - assert(binary != NULL); + _DIAGASSERT(binary != NULL); if (ascii) start = ascii; @@ -119,3 +126,5 @@ inet_nsap_ntoa(int binlen, const u_char *binary, char *ascii) { *ascii = '\0'; return (start); } + +/*! \file */ diff --git a/libc/upstream-netbsd/lib/libc/resolv/mtctxres.c b/libc/upstream-netbsd/lib/libc/resolv/mtctxres.c new file mode 100644 index 000000000..6e3281a75 --- /dev/null +++ b/libc/upstream-netbsd/lib/libc/resolv/mtctxres.c @@ -0,0 +1,130 @@ +/* $NetBSD: mtctxres.c,v 1.4 2007/03/30 20:40:52 ghen Exp $ */ + +#include +#ifdef DO_PTHREADS +#include +#endif +#include +#include +#include +#include +#include +#include + +#ifdef DO_PTHREADS +static pthread_key_t key; +static int mt_key_initialized = 0; + +static int __res_init_ctx(void); +static void __res_destroy_ctx(void *); + +#if defined(sun) && !defined(__GNUC__) +#pragma init (_mtctxres_init) +#endif +#endif + +static mtctxres_t sharedctx; + +#ifdef DO_PTHREADS +/* + * Initialize the TSD key. By doing this at library load time, we're + * implicitly running without interference from other threads, so there's + * no need for locking. + */ +static void +_mtctxres_init(void) { + int pthread_keycreate_ret; + + pthread_keycreate_ret = pthread_key_create(&key, __res_destroy_ctx); + if (pthread_keycreate_ret == 0) + mt_key_initialized = 1; +} +#endif + +/* + * To support binaries that used the private MT-safe interface in + * Solaris 8, we still need to provide the __res_enable_mt() + * and __res_disable_mt() entry points. They're do-nothing routines. + */ +int +__res_enable_mt(void) { + return (-1); +} + +int +__res_disable_mt(void) { + return (0); +} + +#ifdef DO_PTHREADS +static int +__res_init_ctx(void) { + + mtctxres_t *mt; + int ret; + + + if (pthread_getspecific(key) != 0) { + /* Already exists */ + return (0); + } + + if ((mt = malloc(sizeof (mtctxres_t))) == 0) { + errno = ENOMEM; + return (-1); + } + + memset(mt, 0, sizeof (mtctxres_t)); + + if ((ret = pthread_setspecific(key, mt)) != 0) { + free(mt); + errno = ret; + return (-1); + } + + return (0); +} + +static void +__res_destroy_ctx(void *value) { + + mtctxres_t *mt = (mtctxres_t *)value; + + if (mt != 0) + free(mt); +} +#endif + +mtctxres_t * +___mtctxres(void) { +#ifdef DO_PTHREADS + mtctxres_t *mt; + + /* + * This if clause should only be executed if we are linking + * statically. When linked dynamically _mtctxres_init() should + * be called at binding time due the #pragma above. + */ + if (!mt_key_initialized) { + static pthread_mutex_t keylock = PTHREAD_MUTEX_INITIALIZER; + if (pthread_mutex_lock(&keylock) == 0) { + _mtctxres_init(); + (void) pthread_mutex_unlock(&keylock); + } + } + + /* + * If we have already been called in this thread return the existing + * context. Otherwise recreat a new context and return it. If + * that fails return a global context. + */ + if (mt_key_initialized) { + if (((mt = pthread_getspecific(key)) != 0) || + (__res_init_ctx() == 0 && + (mt = pthread_getspecific(key)) != 0)) { + return (mt); + } + } +#endif + return (&sharedctx); +}