From 7d4c43f8ffdcea20dd0dbacc1dc7dc495d92b6c2 Mon Sep 17 00:00:00 2001 From: Fuxino Date: Thu, 8 Oct 2026 17:58:32 +0200 Subject: [PATCH] Always remove temp files and close their descriptors The inputs temp file was left behind when no inputs existed, and both temp files if rsync failed to start. The descriptors returned by mkstemp were also never closed. Remove the temp files when run() exits in any way, and write them through the mkstemp descriptors. --- simple_backup/simple_backup.py | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/simple_backup/simple_backup.py b/simple_backup/simple_backup.py index 1691e49..8afe4ea 100755 --- a/simple_backup/simple_backup.py +++ b/simple_backup/simple_backup.py @@ -494,6 +494,20 @@ class Backup: def run(self) -> int: """Perform the backup""" + try: + return self._run() + finally: + self._remove_temp_files() + + def _remove_temp_files(self) -> None: + for path in [self._inputs_path, self._exclude_path]: + if path != '': + try: + os.remove(path) + except FileNotFoundError: + pass + + def _run(self) -> int: logger.info('Starting backup...') _notify('Starting backup...') @@ -501,10 +515,10 @@ class Backup: self.define_backup_dir() self.find_last_backup() - _, self._inputs_path = mkstemp(prefix='tmp_inputs', text=True) + fd, self._inputs_path = mkstemp(prefix='tmp_inputs', text=True) count = 0 - with open(self._inputs_path, 'w', encoding='utf-8') as fp: + with os.fdopen(fd, 'w', encoding='utf-8') as fp: for i in self.inputs: if not os.path.exists(i): logger.warning('Input %s not found. Skipping', i) @@ -522,9 +536,9 @@ class Backup: return 1 - _, self._exclude_path = mkstemp(prefix='tmp_exclude', text=True) + fd, self._exclude_path = mkstemp(prefix='tmp_exclude', text=True) - with open(self._exclude_path, 'w', encoding='utf-8') as fp: + with os.fdopen(fd, 'w', encoding='utf-8') as fp: if self.exclude is not None: for e in self.exclude: fp.write(e) @@ -591,9 +605,6 @@ class Backup: else: logger.warning('Backup not completed successfully. Old backups will not be removed') - os.remove(self._inputs_path) - os.remove(self._exclude_path) - if self._remote: assert self._ssh is not None