|
@@ -3,8 +3,10 @@ from binascii import hexlify
|
|
|
from datetime import datetime
|
|
|
from operator import attrgetter
|
|
|
import functools
|
|
|
+import inspect
|
|
|
import io
|
|
|
import os
|
|
|
+import signal
|
|
|
import stat
|
|
|
import sys
|
|
|
import textwrap
|
|
@@ -14,7 +16,7 @@ from attic.archive import Archive, ArchiveChecker
|
|
|
from attic.repository import Repository
|
|
|
from attic.cache import Cache
|
|
|
from attic.key import key_creator
|
|
|
-from attic.helpers import Error, location_validator, format_time, \
|
|
|
+from attic.helpers import Error, location_validator, format_time, format_file_size, \
|
|
|
format_file_mode, ExcludePattern, exclude_path, adjust_patterns, to_localtime, timestamp, \
|
|
|
get_cache_dir, get_keys_dir, format_timedelta, prune_within, prune_split, \
|
|
|
Manifest, remove_surrogates, update_excludes, format_archive, check_extension_modules, Statistics, \
|
|
@@ -807,11 +809,45 @@ Type "Yes I am sure" if you understand this and want to continue.\n""")
|
|
|
return args.func(args)
|
|
|
|
|
|
|
|
|
+def sig_info_handler(signum, stack):
|
|
|
+ """search the stack for infos about the currently processed file and print them"""
|
|
|
+ for frame in inspect.getouterframes(stack):
|
|
|
+ func, loc = frame[3], frame[0].f_locals
|
|
|
+ if func in ('process_file', '_process', ): # attic create
|
|
|
+ path = loc['path']
|
|
|
+ try:
|
|
|
+ pos = loc['fd'].tell()
|
|
|
+ total = loc['st'].st_size
|
|
|
+ except Exception:
|
|
|
+ pos, total = 0, 0
|
|
|
+ print("{0} {1}/{2}".format(path, format_file_size(pos), format_file_size(total)))
|
|
|
+ break
|
|
|
+ if func in ('extract_item', ): # attic extract
|
|
|
+ path = loc['item'][b'path']
|
|
|
+ try:
|
|
|
+ pos = loc['fd'].tell()
|
|
|
+ except Exception:
|
|
|
+ pos = 0
|
|
|
+ print("{0} {1}/???".format(path, format_file_size(pos)))
|
|
|
+ break
|
|
|
+
|
|
|
+
|
|
|
+def setup_signal_handlers():
|
|
|
+ sigs = []
|
|
|
+ if hasattr(signal, 'SIGUSR1'):
|
|
|
+ sigs.append(signal.SIGUSR1) # kill -USR1 pid
|
|
|
+ if hasattr(signal, 'SIGINFO'):
|
|
|
+ sigs.append(signal.SIGINFO) # kill -INFO pid (or ctrl-t)
|
|
|
+ for sig in sigs:
|
|
|
+ signal.signal(sig, sig_info_handler)
|
|
|
+
|
|
|
+
|
|
|
def main():
|
|
|
# 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)
|
|
|
+ setup_signal_handlers()
|
|
|
archiver = Archiver()
|
|
|
try:
|
|
|
exit_code = archiver.run(sys.argv[1:])
|