From 4474eb68e2dc4e26a32e8b4b0fdbdd2dbf16506a Mon Sep 17 00:00:00 2001 From: Giacomo Vercesi Date: Thu, 29 Aug 2024 13:20:57 +0200 Subject: [PATCH] fetch_debuginfo: download files atomically Instead of directly writing the destination file, use the combination of a `.tmp` suffix and `os.replace` to guarantee that the destination file is written whole and not partially. --- .../revng/internal/cli/_commands/fetch_debuginfo/common.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/python/revng/internal/cli/_commands/fetch_debuginfo/common.py b/python/revng/internal/cli/_commands/fetch_debuginfo/common.py index c2e2d7813..9f05ac7b5 100644 --- a/python/revng/internal/cli/_commands/fetch_debuginfo/common.py +++ b/python/revng/internal/cli/_commands/fetch_debuginfo/common.py @@ -2,6 +2,7 @@ # This file is distributed under the MIT License. See LICENSE.md for details. # +import os import sys import requests @@ -29,10 +30,12 @@ def download_file(url, local_filename): try: with requests.get(url, stream=True) as request: if request.status_code == 200: - with open(local_filename, "wb") as debug_file: + download_name = local_filename + ".tmp" + with open(download_name, "wb") as debug_file: for chunk in request.iter_content(chunk_size=64 * 1024): debug_file.write(chunk) log("Downloaded") + os.replace(download_name, local_filename) return True elif request.status_code == 404: log("URL was not found")