summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRené 'Necoro' Neumann <necoro@necoro.net>2008-07-25 09:18:56 +0200
committerRené 'Necoro' Neumann <necoro@necoro.net>2008-07-25 09:18:56 +0200
commit22c6d6d182b5480dc6833e455bb3e2188d66af2a (patch)
treeb7852e11b17d300814f4b2b8c6e4ce845b426dd1
parent8b71eed2f8ef0714aba080ded2fcb96630b77d69 (diff)
downloadportato-22c6d6d182b5480dc6833e455bb3e2188d66af2a.tar.gz
portato-22c6d6d182b5480dc6833e455bb3e2188d66af2a.tar.bz2
portato-22c6d6d182b5480dc6833e455bb3e2188d66af2a.zip
Fixing subprocess/listener handling
-rwxr-xr-xportato.py41
-rw-r--r--portato/gui/__init__.py19
-rw-r--r--portato/plistener.py5
3 files changed, 40 insertions, 25 deletions
diff --git a/portato.py b/portato.py
index 421901a..cc973be 100755
--- a/portato.py
+++ b/portato.py
@@ -14,8 +14,9 @@
from __future__ import with_statement, absolute_import
-import signal
-import sys, os, subprocess
+import sys, os
+import subprocess, threading
+import atexit
import gettext, locale
from optparse import OptionParser, SUPPRESS_HELP
@@ -23,11 +24,6 @@ from portato import get_listener
from portato.helper import debug, info
from portato.constants import VERSION, LOCALE_DIR, APP, SU_COMMAND
-def sigchld_aborter (signal, frame):
- """Aborts the current process when the child dies."""
- debug("Child process died. Trying to abort.")
- raise KeyboardInterrupt
-
def main ():
# set gettext stuff
locale.setlocale(locale.LC_ALL, '')
@@ -49,6 +45,9 @@ def main ():
# run parser
(options, args) = parser.parse_args()
+ # close listener at exit
+ atexit.register(get_listener().close)
+
if options.nofork or os.getuid() == 0: # start GUI
from portato.gui import run
info("%s v. %s", _("Starting Portato"), VERSION)
@@ -58,7 +57,10 @@ def main ():
else:
get_listener().set_send()
- run()
+ try:
+ run()
+ except KeyboardInterrupt:
+ debug("Got KeyboardInterrupt.")
else: # start us again in root modus and launch listener
@@ -68,17 +70,28 @@ def main ():
sig = shm.create_semaphore(InitialValue = 0, permissions = 0600)
rw = shm.create_semaphore(InitialValue = 1, permissions = 0600)
+ # start listener
+ lt = threading.Thread(target=get_listener().set_recv, args = (mem, sig, rw))
+ lt.setDaemon(False)
+ lt.start()
+
# set DBUS_SESSION_BUS_ADDRESS to "" to make dbus work as root ;)
env = os.environ.copy()
env.update(DBUS_SESSION_BUS_ADDRESS="")
cmd = SU_COMMAND.split()
- subprocess.Popen(cmd+["%s --no-fork --shm %ld %ld %ld" % (sys.argv[0], mem.key, sig.key, rw.key)], env = env)
-
- # set handler to abort the listener if needed
- signal.signal(signal.SIGCHLD, sigchld_aborter)
- # stast listener
- get_listener().set_recv(mem, sig, rw)
+ sp = subprocess.Popen(cmd+["%s --no-fork --shm %ld %ld %ld" % (sys.argv[0], mem.key, sig.key, rw.key)], env = env)
+
+ # wait for process to finish
+ try:
+ sp.wait()
+ debug("Subprocess finished")
+ except KeyboardInterrupt:
+ debug("Got KeyboardInterrupt.")
+
+ if lt.isAlive():
+ debug("Listener is still running. Close it.")
+ get_listener().close()
if __name__ == "__main__":
main()
diff --git a/portato/gui/__init__.py b/portato/gui/__init__.py
index 20bcba6..0df890c 100644
--- a/portato/gui/__init__.py
+++ b/portato/gui/__init__.py
@@ -17,15 +17,12 @@ from .exception_handling import register_ex_handler
def run ():
from .windows.splash import SplashScreen
- try:
- s = SplashScreen(_("Loading Backend"))
- register_ex_handler()
- s.show()
- from .windows.main import MainWindow
- m = MainWindow(s)
- s.hide()
- m.main()
- except KeyboardInterrupt:
- pass
+ s = SplashScreen(_("Loading Backend"))
- get_listener().close()
+ register_ex_handler()
+ s.show()
+
+ from .windows.main import MainWindow
+ m = MainWindow(s)
+ s.hide()
+ m.main()
diff --git a/portato/plistener.py b/portato/plistener.py
index a45a17e..fde54fc 100644
--- a/portato/plistener.py
+++ b/portato/plistener.py
@@ -48,6 +48,7 @@ class PListener (object):
self._rw.V()
data = string.split("\0")
+ debug("Listner received: %s", data)
if data[0] == "notify":
self.do_notify(*data[1:])
@@ -63,6 +64,10 @@ class PListener (object):
self._sig.remove()
self._rw.remove()
+ self._mem = None
+ self._sig = None
+ self._rw = None
+
def do_cmd (self, cmdlist):
"""Starts a command as the user.