diff options
-rwxr-xr-x | portato.py | 22 | ||||
-rw-r--r-- | portato/constants.py | 8 | ||||
-rw-r--r-- | portato/plistener.py | 51 |
3 files changed, 53 insertions, 28 deletions
@@ -16,7 +16,9 @@ from __future__ import with_statement, absolute_import import sys, os, subprocess import gettext, locale -from optparse import OptionParser +from optparse import OptionParser, SUPPRESS_HELP + +import shm_wrapper as shm from portato import listener from portato.constants import VERSION, FRONTENDS, STD_FRONTEND, XSD_LOCATION, LOCALE_DIR, APP, SU_COMMAND @@ -47,8 +49,8 @@ def main (): parser.add_option("-e", "--ebuild", action = "store", dest = "ebuild", help = _("opens the ebuild viewer instead of launching Portato")) - parser.add_option("-p", "--pipe", action = "store", dest = "pipe", - help = _("file descriptor to use to communicate with the listener (internal use only)")) + parser.add_option("--shm", action = "store", nargs = 3, type="long", dest = "shm", + help = SUPPRESS_HELP) parser.add_option("-x", "--validate", action = "store", dest = "validate", metavar="PLUGIN", help = _("validates the given plugin xml instead of launching Portato")) @@ -95,15 +97,19 @@ def main (): return elif options.nolistener or os.getuid() == 0: # start GUI - if options.pipe: - listener.set_send(int(options.pipe)) + if options.shm: + listener.set_send(*options.shm) else: listener.set_send() run() else: # start us again in root modus and launch listener - read, write = os.pipe() + + mem = shm.create_memory(1024, permissions=0600) + sig = shm.create_semaphore(InitialValue = 0, permissions = 0600) + rw = shm.create_semaphore(InitialValue = 1, permissions = 0600) + additional = [] if options.check: additional.append("--check") @@ -114,9 +120,9 @@ def main (): env = os.environ.copy() env.update(DBUS_SESSION_BUS_ADDRESS="") cmd = SU_COMMAND.split() - subprocess.Popen(cmd+["%s --no-listener --pipe %d %s" % (sys.argv[0], write, " ".join(additional))], env = env, close_fds = False) + subprocess.Popen(cmd+["%s --no-listener --shm %ld %ld %ld %s" % (sys.argv[0], mem.key, sig.key, rw.key, " ".join(additional))], env = env, close_fds = False) - listener.set_recv(read) + listener.set_recv(mem, sig, rw) if __name__ == "__main__": main() diff --git a/portato/constants.py b/portato/constants.py index c76b737..66ddf8d 100644 --- a/portato/constants.py +++ b/portato/constants.py @@ -56,6 +56,10 @@ These should be set during the installation. import os from os.path import join as pjoin +# icons +ICON_DIR = "icons/" +APP_ICON = pjoin(ICON_DIR, "portato-icon.png") + # general APP = "portato" VERSION = "9999" @@ -71,10 +75,6 @@ STD_FRONTEND = "gtk" CONFIG_DIR = "/etc/portato/" CONFIG_LOCATION = pjoin(CONFIG_DIR, "portato.cfg") -# icons -ICON_DIR = "icons/" -APP_ICON = pjoin(ICON_DIR, "portato-icon.png") - # misc dirs DATA_DIR = "./" LOCALE_DIR = "i18n/" diff --git a/portato/plistener.py b/portato/plistener.py index a24a262..291a30c 100644 --- a/portato/plistener.py +++ b/portato/plistener.py @@ -12,7 +12,8 @@ from __future__ import absolute_import -import socket, os +import shm_wrapper as shm +import os from subprocess import Popen from gettext import lgettext as _ @@ -33,13 +34,20 @@ class PListener (object): @ivar _send: sender socket @type _send: int""" - def set_recv (self, pipe): - self._recv = pipe + def set_recv (self, mem, sig, rw): + self._mem = mem + self._sig = sig + self._rw = rw while True: try: - len = os.read(self._recv, 4) - string = os.read(self._recv, int(len)) + try: + self._sig.P() + self._rw.P() + len = self._mem.read(NumberOfBytes = 4) + string = self._mem.read(NumberOfBytes = int(len), offset = 4) + finally: + self._rw.V() data = string.split("\0") @@ -52,7 +60,9 @@ class PListener (object): except KeyboardInterrupt: break - os.close(self._recv) + self._mem.remove() + self._sig.remove() + self._rw.remove() def do_cmd (self, cmdlist): """Starts a command as the user. @@ -74,18 +84,28 @@ class PListener (object): n.set_urgency(int(urgency)) n.show() - def set_send (self, pipe = None): - if pipe is None: + def set_send (self, mem = None, sig = None, rw = None): + if mem is None or sig is None or rw is None: warning(_("Listener has not been started.")) - - self._send = pipe + self._mem = None + self._sig = None + self._rw = None + else: + self._mem = shm.SharedMemoryHandle(mem) + self._sig = shm.SemaphoreHandle(sig) + self._rw = shm.SemaphoreHandle(rw) def __send (self, string): - os.write(self._send, "%4d" % len(string)) - os.write(self._send, string) + self._rw.P() + self._sig.Z() + try: + self._mem.write("%4d%s" % (len(string), string)) + self._sig.V() + finally: + self._rw.V() def send_notify (self, base = "", descr = "", icon = "", urgency = None): - if self._send is None: + if self._sig is None: self.do_notify(base, descr, icon, urgency) else: string = "\0".join(["notify", base, descr, icon]) @@ -98,12 +118,11 @@ class PListener (object): self.__send(string) def send_cmd (self, cmdlist): - if self._send is None: + if self._sig is None: self.do_cmd(cmdlist) else: self.__send("\0".join(["cmd"] +cmdlist)) def close (self): - if self._send is not None: + if self._sig is not None: self.__send("close") - os.close(self._send) |