summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xportato.py22
-rw-r--r--portato/constants.py8
-rw-r--r--portato/plistener.py51
3 files changed, 53 insertions, 28 deletions
diff --git a/portato.py b/portato.py
index 93fc88e..3bf9ab6 100755
--- a/portato.py
+++ b/portato.py
@@ -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)