From b5d2b3c51297058fd68a920414ca2dae52f8a70a Mon Sep 17 00:00:00 2001 From: avirgovi Date: Fri, 25 Feb 2022 09:33:24 +0100 Subject: [PATCH] create chmod aware of XDG_RUNTIME_DIR closes https://github.com/spesmilo/electrum/pull/7681 related https://github.com/spesmilo/electrum/issues/6334 Co-authored-by: avirgovi Co-authored-by: SomberNight --- electrum/gui/qt/main_window.py | 4 ++-- electrum/simple_config.py | 4 ++-- electrum/storage.py | 4 ++-- electrum/util.py | 15 ++++++++++++++- 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/electrum/gui/qt/main_window.py b/electrum/gui/qt/main_window.py index 40015a676..bb36b7a31 100644 --- a/electrum/gui/qt/main_window.py +++ b/electrum/gui/qt/main_window.py @@ -60,7 +60,7 @@ from electrum.util import (format_time, get_asyncio_loop, bh2u, bfh, InvalidPassword, UserFacingException, get_new_wallet_name, send_exception_to_crash_reporter, - AddTransactionException, BITCOIN_BIP21_URI_SCHEME) + AddTransactionException, BITCOIN_BIP21_URI_SCHEME, os_chmod) from electrum.invoices import PR_PAID, Invoice from electrum.transaction import (Transaction, PartialTxInput, PartialTransaction, PartialTxOutput) @@ -2299,7 +2299,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger, QtEventListener): def do_export_privkeys(self, fileName, pklist, is_csv): with open(fileName, "w+") as f: - os.chmod(fileName, 0o600) + os_chmod(fileName, 0o600) if is_csv: transaction = csv.writer(f) transaction.writerow(["address", "private_key"]) diff --git a/electrum/simple_config.py b/electrum/simple_config.py index d9adb1cc5..10f0215b6 100644 --- a/electrum/simple_config.py +++ b/electrum/simple_config.py @@ -14,7 +14,7 @@ from aiorpcx import NetAddress from . import util from . import constants from .util import base_units, base_unit_name_to_decimal_point, decimal_point_to_base_unit_name, UnknownBaseUnit, DECIMAL_POINT_DEFAULT -from .util import format_satoshis, format_fee_satoshis +from .util import format_satoshis, format_fee_satoshis, os_chmod from .util import user_dir, make_dir, NoDynamicFeeEstimates, quantize_feerate from .i18n import _ from .logging import get_logger, Logger @@ -271,7 +271,7 @@ class SimpleConfig(Logger): try: with open(path, "w", encoding='utf-8') as f: f.write(s) - os.chmod(path, stat.S_IREAD | stat.S_IWRITE) + os_chmod(path, stat.S_IREAD | stat.S_IWRITE) except FileNotFoundError: # datadir probably deleted while running... if os.path.exists(self.path): # or maybe not? diff --git a/electrum/storage.py b/electrum/storage.py index 1f17a92a0..fbf7cbe70 100644 --- a/electrum/storage.py +++ b/electrum/storage.py @@ -32,7 +32,7 @@ from enum import IntEnum from . import ecc from .util import (profiler, InvalidPassword, WalletFileException, bfh, standardize_path, - test_read_write_permissions) + test_read_write_permissions, os_chmod) from .wallet_db import WalletDB from .logging import Logger @@ -95,7 +95,7 @@ class WalletStorage(Logger): if not self.file_exists(): assert not os.path.exists(self.path) os.replace(temp_path, self.path) - os.chmod(self.path, mode) + os_chmod(self.path, mode) self._file_exists = True self.logger.info(f"saved {self.path}") diff --git a/electrum/util.py b/electrum/util.py index 8340d5dd1..b0859710c 100644 --- a/electrum/util.py +++ b/electrum/util.py @@ -1183,6 +1183,7 @@ def read_json_file(path): raise FileImportFailed(e) return data + def write_json_file(path, data): try: with open(path, 'w+', encoding='utf-8') as f: @@ -1192,13 +1193,25 @@ def write_json_file(path, data): raise FileExportFailed(e) +def os_chmod(path, mode): + """os.chmod aware of tmpfs""" + try: + os.chmod(path, mode) + except OSError as e: + xdg_runtime_dir = os.environ.get("XDG_RUNTIME_DIR", None) + if xdg_runtime_dir and is_subpath(path, xdg_runtime_dir): + _logger.info(f"Tried to chmod in tmpfs. Skipping... {e!r}") + else: + raise + + def make_dir(path, allow_symlink=True): """Make directory if it does not yet exist.""" if not os.path.exists(path): if not allow_symlink and os.path.islink(path): raise Exception('Dangling link: ' + path) os.mkdir(path) - os.chmod(path, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR) + os_chmod(path, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR) def is_subpath(long_path: str, short_path: str) -> bool: