Changeset View
Changeset View
Standalone View
Standalone View
head/lib/libc/resolv/res_state.c
Show All 20 Lines | |||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||||
* SUCH DAMAGE. | * SUCH DAMAGE. | ||||
* | * | ||||
* $FreeBSD$ | * $FreeBSD$ | ||||
*/ | */ | ||||
#include <sys/types.h> | #include <sys/types.h> | ||||
#include <sys/stat.h> | |||||
#include <sys/time.h> | |||||
#include <netinet/in.h> | #include <netinet/in.h> | ||||
#include <arpa/nameser.h> | #include <arpa/nameser.h> | ||||
#include <resolv.h> | #include <resolv.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include "namespace.h" | #include "namespace.h" | ||||
#include "reentrant.h" | #include "reentrant.h" | ||||
#include "un-namespace.h" | #include "un-namespace.h" | ||||
Show All 17 Lines | |||||
} | } | ||||
static void | static void | ||||
res_keycreate(void) | res_keycreate(void) | ||||
{ | { | ||||
res_thr_keycreated = thr_keycreate(&res_key, free_res) == 0; | res_thr_keycreated = thr_keycreate(&res_key, free_res) == 0; | ||||
} | } | ||||
static res_state | |||||
res_check_reload(res_state statp) | |||||
{ | |||||
struct timespec now; | |||||
struct stat sb; | |||||
if ((statp->options & RES_INIT) == 0 || statp->reload_period == 0) { | |||||
return (statp); | |||||
} | |||||
if (clock_gettime(CLOCK_MONOTONIC_FAST, &now) != 0 || | |||||
(now.tv_sec - statp->conf_stat) < statp->reload_period) { | |||||
return (statp); | |||||
} | |||||
statp->conf_stat = now.tv_sec; | |||||
if (stat(_PATH_RESCONF, &sb) == 0 && | |||||
(sb.st_mtim.tv_sec != statp->conf_mtim.tv_sec || | |||||
sb.st_mtim.tv_nsec != statp->conf_mtim.tv_nsec)) { | |||||
statp->options &= ~RES_INIT; | |||||
} | |||||
return (statp); | |||||
} | |||||
res_state | res_state | ||||
__res_state(void) | __res_state(void) | ||||
{ | { | ||||
res_state statp; | res_state statp; | ||||
if (thr_main() != 0) | if (thr_main() != 0) | ||||
return (&_res); | return res_check_reload(&_res); | ||||
if (thr_once(&res_init_once, res_keycreate) != 0 || | if (thr_once(&res_init_once, res_keycreate) != 0 || | ||||
!res_thr_keycreated) | !res_thr_keycreated) | ||||
return (&_res); | return (&_res); | ||||
statp = thr_getspecific(res_key); | statp = thr_getspecific(res_key); | ||||
if (statp != NULL) | if (statp != NULL) | ||||
return (statp); | return res_check_reload(statp); | ||||
statp = calloc(1, sizeof(*statp)); | statp = calloc(1, sizeof(*statp)); | ||||
if (statp == NULL) | if (statp == NULL) | ||||
return (&_res); | return (&_res); | ||||
#ifdef __BIND_RES_TEXT | #ifdef __BIND_RES_TEXT | ||||
statp->options = RES_TIMEOUT; /* Motorola, et al. */ | statp->options = RES_TIMEOUT; /* Motorola, et al. */ | ||||
#endif | #endif | ||||
if (thr_setspecific(res_key, statp) == 0) | if (thr_setspecific(res_key, statp) == 0) | ||||
return (statp); | return (statp); | ||||
free(statp); | free(statp); | ||||
return (&_res); | return (&_res); | ||||
} | } |