diff --git a/borg/archiver.py b/borg/archiver.py index 02da0f1b9..74c1d1a41 100644 --- a/borg/archiver.py +++ b/borg/archiver.py @@ -22,7 +22,7 @@ get_cache_dir, prune_within, prune_split, \ Manifest, NoManifestError, remove_surrogates, update_excludes, format_archive, check_extension_modules, Statistics, \ dir_is_tagged, bigint_to_int, ChunkerParams, CompressionSpec, PrefixSpec, is_slow_msgpack, yes, sysinfo, \ - EXIT_SUCCESS, EXIT_WARNING, EXIT_ERROR, log_multi, PatternMatcher + EXIT_SUCCESS, EXIT_WARNING, EXIT_ERROR, log_multi, PatternMatcher, ErrorIgnoringTextIOWrapper from .logger import create_logger, setup_logging logger = create_logger() from .compress import Compressor, COMPR_BUFFER @@ -1592,8 +1592,8 @@ def setup_signal_handlers(): # pragma: no cover def main(): # pragma: no cover # Make sure stdout and stderr have errors='replace') to avoid unicode # issues when print()-ing unicode file names - sys.stdout = io.TextIOWrapper(sys.stdout.buffer, sys.stdout.encoding, 'replace', line_buffering=True) - sys.stderr = io.TextIOWrapper(sys.stderr.buffer, sys.stderr.encoding, 'replace', line_buffering=True) + sys.stdout = ErrorIgnoringTextIOWrapper(sys.stdout.buffer, sys.stdout.encoding, 'replace', line_buffering=True) + sys.stderr = ErrorIgnoringTextIOWrapper(sys.stderr.buffer, sys.stderr.encoding, 'replace', line_buffering=True) setup_signal_handlers() archiver = Archiver() msg = None diff --git a/borg/helpers.py b/borg/helpers.py index 56e336e0d..1a7bf8afc 100644 --- a/borg/helpers.py +++ b/borg/helpers.py @@ -12,6 +12,8 @@ import platform import time import unicodedata +import io +import errno import logging from .logger import create_logger @@ -1089,3 +1091,27 @@ def log_multi(*msgs, level=logging.INFO): lines.extend(msg.splitlines()) for line in lines: logger.log(level, line) + + +class ErrorIgnoringTextIOWrapper(io.TextIOWrapper): + def read(self, n): + if not self.closed: + try: + return super().read(n) + except BrokenPipeError: + try: + super().close() + except OSError: + pass + return '' + + def write(self, s): + if not self.closed: + try: + return super().write(s) + except BrokenPipeError: + try: + super().close() + except OSError: + pass + return len(s)