gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnurl] 127/282: altsvc: make saving the cache an atomic operation


From: gnunet
Subject: [gnurl] 127/282: altsvc: make saving the cache an atomic operation
Date: Wed, 01 Apr 2020 14:29:52 +0200

This is an automated email from the git hooks/post-receive script.

ng0 pushed a commit to branch master
in repository gnurl.

commit 14916a82e23c22e1f3d3ebbd90421eb747480e99
Author: Daniel Stenberg <address@hidden>
AuthorDate: Mon Feb 17 23:01:48 2020 +0100

    altsvc: make saving the cache an atomic operation
    
    ... by writing the file to temp name then rename to the final when done.
    
    Assisted-by: Jay Satiro
    Fixes #4936
    Closes #4942
---
 lib/altsvc.c          | 45 +++++++++++++++++++++++++++++++++------------
 lib/altsvc.h          |  9 +++++----
 lib/url.c             |  2 +-
 tests/unit/unit1654.c |  4 ++--
 4 files changed, 41 insertions(+), 19 deletions(-)

diff --git a/lib/altsvc.c b/lib/altsvc.c
index c05562985..8066302ae 100644
--- a/lib/altsvc.c
+++ b/lib/altsvc.c
@@ -34,6 +34,8 @@
 #include "parsedate.h"
 #include "sendf.h"
 #include "warnless.h"
+#include "rand.h"
+#include "rename.h"
 
 /* The last 3 #include files should be in this order */
 #include "curl_printf.h"
@@ -317,12 +319,15 @@ void Curl_altsvc_cleanup(struct altsvcinfo *altsvc)
 /*
  * Curl_altsvc_save() writes the altsvc cache to a file.
  */
-CURLcode Curl_altsvc_save(struct altsvcinfo *altsvc, const char *file)
+CURLcode Curl_altsvc_save(struct Curl_easy *data,
+                          struct altsvcinfo *altsvc, const char *file)
 {
   struct curl_llist_element *e;
   struct curl_llist_element *n;
   CURLcode result = CURLE_OK;
   FILE *out;
+  char *tempstore;
+  unsigned char randsuffix[9];
 
   if(!altsvc)
     /* no cache activated */
@@ -335,20 +340,36 @@ CURLcode Curl_altsvc_save(struct altsvcinfo *altsvc, 
const char *file)
   if((altsvc->flags & CURLALTSVC_READONLYFILE) || !file || !file[0])
     /* marked as read-only, no file or zero length file name */
     return CURLE_OK;
-  out = fopen(file, FOPEN_WRITETEXT);
+
+  if(Curl_rand_hex(data, randsuffix, sizeof(randsuffix)))
+    return CURLE_FAILED_INIT;
+
+  tempstore = aprintf("%s.%s.tmp", file, randsuffix);
+  if(!tempstore)
+    return CURLE_OUT_OF_MEMORY;
+
+  out = fopen(tempstore, FOPEN_WRITETEXT);
   if(!out)
-    return CURLE_WRITE_ERROR;
-  fputs("# Your alt-svc cache. https://curl.haxx.se/docs/alt-svc.html\n";
-        "# This file was generated by libcurl! Edit at your own risk.\n",
-        out);
-  for(e = altsvc->list.head; e; e = n) {
-    struct altsvc *as = e->ptr;
-    n = e->next;
-    result = altsvc_out(as, out);
+    result = CURLE_WRITE_ERROR;
+  else {
+    fputs("# Your alt-svc cache. https://curl.haxx.se/docs/alt-svc.html\n";
+          "# This file was generated by libcurl! Edit at your own risk.\n",
+          out);
+    for(e = altsvc->list.head; e; e = n) {
+      struct altsvc *as = e->ptr;
+      n = e->next;
+      result = altsvc_out(as, out);
+      if(result)
+        break;
+    }
+    fclose(out);
+    if(!result && Curl_rename(tempstore, file))
+      result = CURLE_WRITE_ERROR;
+
     if(result)
-      break;
+      unlink(tempstore);
   }
-  fclose(out);
+  free(tempstore);
   return result;
 }
 
diff --git a/lib/altsvc.h b/lib/altsvc.h
index 99d0499af..248e71eef 100644
--- a/lib/altsvc.h
+++ b/lib/altsvc.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2019, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 2019 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -59,7 +59,8 @@ struct altsvcinfo {
 const char *Curl_alpnid2str(enum alpnid id);
 struct altsvcinfo *Curl_altsvc_init(void);
 CURLcode Curl_altsvc_load(struct altsvcinfo *asi, const char *file);
-CURLcode Curl_altsvc_save(struct altsvcinfo *asi, const char *file);
+CURLcode Curl_altsvc_save(struct Curl_easy *data,
+                          struct altsvcinfo *asi, const char *file);
 CURLcode Curl_altsvc_ctrl(struct altsvcinfo *asi, const long ctrl);
 void Curl_altsvc_cleanup(struct altsvcinfo *altsvc);
 CURLcode Curl_altsvc_parse(struct Curl_easy *data,
@@ -70,9 +71,9 @@ bool Curl_altsvc_lookup(struct altsvcinfo *asi,
                         enum alpnid srcalpnid, const char *srchost,
                         int srcport,
                         struct altsvc **dstentry,
-                        int versions); /* one or more CURLALTSVC_H* bits */
+                        const int versions); /* CURLALTSVC_H* bits */
 #else
 /* disabled */
-#define Curl_altsvc_save(a,b)
+#define Curl_altsvc_save(a,b,c)
 #endif /* CURL_DISABLE_HTTP || USE_ALTSVC */
 #endif /* HEADER_CURL_ALTSVC_H */
diff --git a/lib/url.c b/lib/url.c
index f3b26dafa..d6adf7177 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -380,7 +380,7 @@ CURLcode Curl_close(struct Curl_easy **datap)
   Curl_safefree(data->state.ulbuf);
   Curl_flush_cookies(data, TRUE);
 #ifdef USE_ALTSVC
-  Curl_altsvc_save(data->asi, data->set.str[STRING_ALTSVC]);
+  Curl_altsvc_save(data, data->asi, data->set.str[STRING_ALTSVC]);
   Curl_altsvc_cleanup(data->asi);
   data->asi = NULL;
 #endif
diff --git a/tests/unit/unit1654.c b/tests/unit/unit1654.c
index a800d9c3a..d05d0b214 100644
--- a/tests/unit/unit1654.c
+++ b/tests/unit/unit1654.c
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 2019, Daniel Stenberg, <address@hidden>, et al.
+ * Copyright (C) 2019 - 2020, Daniel Stenberg, <address@hidden>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -124,7 +124,7 @@ UNITTEST_START
   }
   fail_unless(asi->num == 10, "wrong number of entries");
 
-  Curl_altsvc_save(asi, outname);
+  Curl_altsvc_save(curl, asi, outname);
 
   curl_easy_cleanup(curl);
   fail:

-- 
To stop receiving notification emails like this one, please contact
address@hidden.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]