summaryrefslogtreecommitdiffstats
path: root/freebsd/lib/libc/resolv/res_state.c
diff options
context:
space:
mode:
Diffstat (limited to 'freebsd/lib/libc/resolv/res_state.c')
-rw-r--r--freebsd/lib/libc/resolv/res_state.c39
1 files changed, 37 insertions, 2 deletions
diff --git a/freebsd/lib/libc/resolv/res_state.c b/freebsd/lib/libc/resolv/res_state.c
index a89b9b5e..1cfe1700 100644
--- a/freebsd/lib/libc/resolv/res_state.c
+++ b/freebsd/lib/libc/resolv/res_state.c
@@ -28,6 +28,8 @@
*/
#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <resolv.h>
@@ -37,6 +39,8 @@
#include "reentrant.h"
#include "un-namespace.h"
+#include "res_private.h"
+
#undef _res
struct __res_state _res;
@@ -61,6 +65,37 @@ res_keycreate(void)
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;
+ struct __res_state_ext *ext;
+
+ if ((statp->options & RES_INIT) == 0) {
+ return (statp);
+ }
+
+ ext = statp->_u._ext.ext;
+ if (ext == NULL || ext->reload_period == 0) {
+ return (statp);
+ }
+
+ if (clock_gettime(CLOCK_MONOTONIC_FAST, &now) != 0 ||
+ (now.tv_sec - ext->conf_stat) < ext->reload_period) {
+ return (statp);
+ }
+
+ ext->conf_stat = now.tv_sec;
+ if (stat(_PATH_RESCONF, &sb) == 0 &&
+ (sb.st_mtim.tv_sec != ext->conf_mtim.tv_sec ||
+ sb.st_mtim.tv_nsec != ext->conf_mtim.tv_nsec)) {
+ statp->options &= ~RES_INIT;
+ }
+
+ return (statp);
+}
+
res_state
__res_state(void)
{
@@ -68,7 +103,7 @@ __res_state(void)
#ifndef __rtems__
if (thr_main() != 0)
- return (&_res);
+ return res_check_reload(&_res);
#endif /* __rtems__ */
if (thr_once(&res_init_once, res_keycreate) != 0 ||
@@ -77,7 +112,7 @@ __res_state(void)
statp = thr_getspecific(res_key);
if (statp != NULL)
- return (statp);
+ return res_check_reload(statp);
statp = calloc(1, sizeof(*statp));
if (statp == NULL)
return (&_res);