diff --git a/pisi/atomicoperations.py b/pisi/atomicoperations.py index cc8962f6..7e245c76 100644 --- a/pisi/atomicoperations.py +++ b/pisi/atomicoperations.py @@ -106,6 +106,9 @@ class Install(AtomicOperation): self.ask_reinstall = ask_reinstall self.check_requirements() self.check_relations() + + ctx.disable_keyboard_interrupts() + self.check_reinstall() self.extract_install() self.store_pisi_files() @@ -120,6 +123,8 @@ class Install(AtomicOperation): txn.abort() raise e + ctx.enable_keyboard_interrupts() + ctx.ui.close() if self.upgrade: event = pisi.ui.upgraded diff --git a/pisi/comariface.py b/pisi/comariface.py index f0e492c7..21e4310c 100644 --- a/pisi/comariface.py +++ b/pisi/comariface.py @@ -65,6 +65,10 @@ def wait_for_result(com, package_name=None): except KeyboardInterrupt: raise except Exception, e: #FIXME: what exception could we catch here, replace with that. + # TODO: we return here but we can also set self.config_later? + if ctx.keyboard_interrupt_pending(): + return + # Comar postInstall does a "service comar restart" which cuts # our precious communication link, so we waitsss if package_name == "comar": diff --git a/pisi/context.py b/pisi/context.py index fa9cba6c..aae0ddbe 100644 --- a/pisi/context.py +++ b/pisi/context.py @@ -12,9 +12,13 @@ # global variables here +import signal + import pisi.constants +import pisi.signalhandler const = pisi.constants.Constants() +sig = pisi.signalhandler.SignalHandler() config = None @@ -74,3 +78,15 @@ def txn_proc(proc, txn = None): return retval else: return proc(txn) + +def disable_keyboard_interrupts(): + sig.disable_signal(signal.SIGINT) + +def enable_keyboard_interrupts(): + sig.enable_signal(signal.SIGINT) + +def keyboard_interrupt_disabled(): + return sig.signal_disabled(signal.SIGINT) + +def keyboard_interrupt_pending(): + return sig.signal_pending(signal.SIGINT) diff --git a/pisi/signalhandler.py b/pisi/signalhandler.py new file mode 100644 index 00000000..3e935b65 --- /dev/null +++ b/pisi/signalhandler.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2006, TUBITAK/UEKAE +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) +# any later version. +# +# Please read the COPYING file. +# + +import signal + +exception = { + signal.SIGINT:KeyboardInterrupt + } + +class SignalHandler: + + def __init__(self): + self.pending_signals = [] + self.disabled_signals = [] + + def signal_handler(self, sig, frame): + signal.signal(sig, signal.SIG_IGN) + if sig not in self.pending_signals: + self.pending_signals.append(sig) + + def clear_pending_signal(self, sig): + if sig in self.pending_signals: + self.pending_signals.remove(sig) + + def disable_signal(self, sig): + signal.signal(sig, self.signal_handler) + + if sig not in self.disabled_signals: + self.disabled_signals.append(sig) + + def enable_signal(self, sig): + signal.signal(sig, signal.SIG_DFL) + + if sig in self.disabled_signals: + self.disabled_signals.remove(sig) + + if sig in self.pending_signals: + self.clear_pending_signal(sig) + raise exception[sig] + + def signal_disabled(self, sig): + return sig in self.disabled_signals + + def signal_pending(self, sig): + return sig in self.pending_signals