a2cf7d
From: Florian Weimer <fweimer@redhat.com>
a2cf7d
Date: Tue, 21 Jan 2020 16:25:39 +0000 (+0100)
a2cf7d
Subject: resolv: Enhance __resolv_conf_load to capture file change data
a2cf7d
X-Git-Url: https://sourceware.org/git/?p=glibc.git;a=commitdiff_plain;h=dd0b4df329ff7ff2a656404db271c8ee8379ff9d
a2cf7d
a2cf7d
resolv: Enhance __resolv_conf_load to capture file change data
a2cf7d
a2cf7d
The data is captured after reading the file.  This allows callers
a2cf7d
to check the change data against an earlier measurement.
a2cf7d
a2cf7d
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
a2cf7d
---
a2cf7d
a2cf7d
diff --git a/resolv/res_init.c b/resolv/res_init.c
a2cf7d
index 09345718cd..98d84f264d 100644
a2cf7d
--- a/resolv/res_init.c
a2cf7d
+++ b/resolv/res_init.c
a2cf7d
@@ -103,6 +103,7 @@
a2cf7d
 #include <inet/net-internal.h>
a2cf7d
 #include <errno.h>
a2cf7d
 #include <resolv_conf.h>
a2cf7d
+#include <file_change_detection.h>
a2cf7d
 
a2cf7d
 static uint32_t net_mask (struct in_addr);
a2cf7d
 
a2cf7d
@@ -549,7 +550,8 @@ res_vinit_1 (FILE *fp, struct resolv_conf_parser *parser)
a2cf7d
 }
a2cf7d
 
a2cf7d
 struct resolv_conf *
a2cf7d
-__resolv_conf_load (struct __res_state *preinit)
a2cf7d
+__resolv_conf_load (struct __res_state *preinit,
a2cf7d
+                    struct file_change_detection *change)
a2cf7d
 {
a2cf7d
   /* Ensure that /etc/hosts.conf has been loaded (once).  */
a2cf7d
   _res_hconf_init ();
a2cf7d
@@ -577,7 +579,13 @@ __resolv_conf_load (struct __res_state *preinit)
a2cf7d
   resolv_conf_parser_init (&parser, preinit);
a2cf7d
 
a2cf7d
   struct resolv_conf *conf = NULL;
a2cf7d
-  if (res_vinit_1 (fp, &parser))
a2cf7d
+  bool ok = res_vinit_1 (fp, &parser);
a2cf7d
+  if (ok && change != NULL)
a2cf7d
+    /* Update the file change information if the configuration was
a2cf7d
+       loaded successfully.  */
a2cf7d
+    ok = file_change_detection_for_fp (change, fp);
a2cf7d
+
a2cf7d
+  if (ok)
a2cf7d
     {
a2cf7d
       parser.template.nameserver_list
a2cf7d
         = nameserver_list_begin (&parser.nameserver_list);
a2cf7d
@@ -615,7 +623,7 @@ __res_vinit (res_state statp, int preinit)
a2cf7d
   if (preinit && has_preinit_values (statp))
a2cf7d
     /* For the preinit case, we cannot use the cached configuration
a2cf7d
        because some settings could be different.  */
a2cf7d
-    conf = __resolv_conf_load (statp);
a2cf7d
+    conf = __resolv_conf_load (statp, NULL);
a2cf7d
   else
a2cf7d
     conf = __resolv_conf_get_current ();
a2cf7d
   if (conf == NULL)
a2cf7d
diff --git a/resolv/resolv_conf.c b/resolv/resolv_conf.c
a2cf7d
index d954ba9a5a..bdd2ebb909 100644
a2cf7d
--- a/resolv/resolv_conf.c
a2cf7d
+++ b/resolv/resolv_conf.c
a2cf7d
@@ -136,7 +136,7 @@ __resolv_conf_get_current (void)
a2cf7d
     {
a2cf7d
       /* Parse configuration while holding the lock.  This avoids
a2cf7d
          duplicate work.  */
a2cf7d
-      conf = __resolv_conf_load (NULL);
a2cf7d
+      conf = __resolv_conf_load (NULL, NULL);
a2cf7d
       if (conf != NULL)
a2cf7d
         {
a2cf7d
           if (global_copy->conf_current != NULL)
a2cf7d
diff --git a/resolv/resolv_conf.h b/resolv/resolv_conf.h
a2cf7d
index 01cbff9111..101e14bfe5 100644
a2cf7d
--- a/resolv/resolv_conf.h
a2cf7d
+++ b/resolv/resolv_conf.h
a2cf7d
@@ -63,12 +63,16 @@ struct resolv_conf
a2cf7d
    and the struct resolv_context facility.  */
a2cf7d
 
a2cf7d
 struct __res_state;
a2cf7d
+struct file_change_detection;
a2cf7d
 
a2cf7d
 /* Read /etc/resolv.conf and return a configuration object, or NULL if
a2cf7d
    /etc/resolv.conf cannot be read due to memory allocation errors.
a2cf7d
-   If PREINIT is not NULL, some configuration values are taken from the
a2cf7d
-   struct __res_state object.  */
a2cf7d
-struct resolv_conf *__resolv_conf_load (struct __res_state *preinit)
a2cf7d
+   If PREINIT is not NULL, some configuration values are taken from
a2cf7d
+   the struct __res_state object.  If CHANGE is not null, file change
a2cf7d
+   detection data is written to *CHANGE, based on the state of the
a2cf7d
+   file after reading it.  */
a2cf7d
+struct resolv_conf *__resolv_conf_load (struct __res_state *preinit,
a2cf7d
+                                        struct file_change_detection *change)
a2cf7d
   attribute_hidden __attribute__ ((warn_unused_result));
a2cf7d
 
a2cf7d
 /* Return a configuration object for the current /etc/resolv.conf