From 1928392b4e84fc0fb922aa56f11aaf74ef42d0c2 Mon Sep 17 00:00:00 2001 From: Faik Uygur Date: Tue, 24 Oct 2006 13:53:58 +0000 Subject: [PATCH] * These errors would become much more seen when people start to play with the package-manager's cancel button. I have seen it a lot while playing with it. And when this happens there is no way to explain this to users. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit faik@iago pisi $ sudo ./pisi-cli it /home/faik/hdparm-6.7-5-4.pisi Password: Kurulum sırası: hdparm hdparm paketi, versiyon 6.7, sürüm 5, inşa 4 kuruluyor disabled Aynı versiyona sahip paketi yeniden yerleştireyim mi? (evet/hayır)e Sistem Hatası: Program Sonlandırıldı. Dosya '/var/lib/pisi/package/hdparm-6.7-5/files.xml' bulunamadı. Patch prevents these errors by blocking keyboard interrupts between critical paths. When the critical path is passed if any interrupts were caught while in this path the interrupt is raised. --- pisi/atomicoperations.py | 5 ++++ pisi/comariface.py | 4 +++ pisi/context.py | 16 ++++++++++++ pisi/signalhandler.py | 54 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 79 insertions(+) create mode 100644 pisi/signalhandler.py 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