1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-07-28 00:21:52 +03:00

resolv: Enhance __resolv_conf_load to capture file change data

The data is captured after reading the file.  This allows callers
to check the change data against an earlier measurement.

Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
This commit is contained in:
Florian Weimer
2020-01-21 17:25:39 +01:00
parent a1a20f0292
commit dd0b4df329
3 changed files with 19 additions and 7 deletions

View File

@ -103,6 +103,7 @@
#include <inet/net-internal.h> #include <inet/net-internal.h>
#include <errno.h> #include <errno.h>
#include <resolv_conf.h> #include <resolv_conf.h>
#include <file_change_detection.h>
static uint32_t net_mask (struct in_addr); static uint32_t net_mask (struct in_addr);
@ -549,7 +550,8 @@ res_vinit_1 (FILE *fp, struct resolv_conf_parser *parser)
} }
struct resolv_conf * struct resolv_conf *
__resolv_conf_load (struct __res_state *preinit) __resolv_conf_load (struct __res_state *preinit,
struct file_change_detection *change)
{ {
/* Ensure that /etc/hosts.conf has been loaded (once). */ /* Ensure that /etc/hosts.conf has been loaded (once). */
_res_hconf_init (); _res_hconf_init ();
@ -577,7 +579,13 @@ __resolv_conf_load (struct __res_state *preinit)
resolv_conf_parser_init (&parser, preinit); resolv_conf_parser_init (&parser, preinit);
struct resolv_conf *conf = NULL; struct resolv_conf *conf = NULL;
if (res_vinit_1 (fp, &parser)) bool ok = res_vinit_1 (fp, &parser);
if (ok && change != NULL)
/* Update the file change information if the configuration was
loaded successfully. */
ok = file_change_detection_for_fp (change, fp);
if (ok)
{ {
parser.template.nameserver_list parser.template.nameserver_list
= nameserver_list_begin (&parser.nameserver_list); = nameserver_list_begin (&parser.nameserver_list);
@ -615,7 +623,7 @@ __res_vinit (res_state statp, int preinit)
if (preinit && has_preinit_values (statp)) if (preinit && has_preinit_values (statp))
/* For the preinit case, we cannot use the cached configuration /* For the preinit case, we cannot use the cached configuration
because some settings could be different. */ because some settings could be different. */
conf = __resolv_conf_load (statp); conf = __resolv_conf_load (statp, NULL);
else else
conf = __resolv_conf_get_current (); conf = __resolv_conf_get_current ();
if (conf == NULL) if (conf == NULL)

View File

@ -136,7 +136,7 @@ __resolv_conf_get_current (void)
{ {
/* Parse configuration while holding the lock. This avoids /* Parse configuration while holding the lock. This avoids
duplicate work. */ duplicate work. */
conf = __resolv_conf_load (NULL); conf = __resolv_conf_load (NULL, NULL);
if (conf != NULL) if (conf != NULL)
{ {
if (global_copy->conf_current != NULL) if (global_copy->conf_current != NULL)

View File

@ -63,12 +63,16 @@ struct resolv_conf
and the struct resolv_context facility. */ and the struct resolv_context facility. */
struct __res_state; struct __res_state;
struct file_change_detection;
/* Read /etc/resolv.conf and return a configuration object, or NULL if /* Read /etc/resolv.conf and return a configuration object, or NULL if
/etc/resolv.conf cannot be read due to memory allocation errors. /etc/resolv.conf cannot be read due to memory allocation errors.
If PREINIT is not NULL, some configuration values are taken from the If PREINIT is not NULL, some configuration values are taken from
struct __res_state object. */ the struct __res_state object. If CHANGE is not null, file change
struct resolv_conf *__resolv_conf_load (struct __res_state *preinit) detection data is written to *CHANGE, based on the state of the
file after reading it. */
struct resolv_conf *__resolv_conf_load (struct __res_state *preinit,
struct file_change_detection *change)
attribute_hidden __attribute__ ((warn_unused_result)); attribute_hidden __attribute__ ((warn_unused_result));
/* Return a configuration object for the current /etc/resolv.conf /* Return a configuration object for the current /etc/resolv.conf