Merge branch 'master' of git://dev.laptop.org/users/mstone/sugar-toolkit

This commit is contained in:
Tomeu Vizoso 2009-08-01 18:34:36 +02:00
commit acdc647f58

View File

@ -34,6 +34,9 @@ from sugar import env
from errno import EEXIST, ENOSPC from errno import EEXIST, ENOSPC
import os import os
import tempfile
import subprocess
import pwd
_SHELL_SERVICE = "org.laptop.Shell" _SHELL_SERVICE = "org.laptop.Shell"
_SHELL_PATH = "/org/laptop/Shell" _SHELL_PATH = "/org/laptop/Shell"
@ -45,10 +48,6 @@ _DS_PATH = "/org/laptop/sugar/DataStore"
_ACTIVITY_FACTORY_INTERFACE = "org.laptop.ActivityFactory" _ACTIVITY_FACTORY_INTERFACE = "org.laptop.ActivityFactory"
_RAINBOW_SERVICE_NAME = "org.laptop.security.Rainbow"
_RAINBOW_ACTIVITY_FACTORY_PATH = "/"
_RAINBOW_ACTIVITY_FACTORY_INTERFACE = "org.laptop.security.Rainbow"
# helper method to close all filedescriptors # helper method to close all filedescriptors
# borrowed from subprocess.py # borrowed from subprocess.py
try: try:
@ -253,40 +252,47 @@ class ActivityCreationHandler(gobject.GObject):
self._handle.object_id, self._handle.object_id,
self._handle.uri) self._handle.uri)
if not self._use_rainbow: envdir = None
# use gobject spawn functionality, so that zombies are if self._use_rainbow:
# automatically reaped by the gobject event loop. envdir = tempfile.mkdtemp()
def child_setup(): command = ['/usr/bin/sudo', '-E', '--',
# clone logfile.fileno() onto stdout/stderr '/usr/bin/rainbow-run',
os.dup2(log_file.fileno(), 1) '-v', '-v',
os.dup2(log_file.fileno(), 2) '-a', '/usr/bin/rainbow-sugarize',
# close all other fds '-s', '/var/spool/rainbow/2',
_close_fds() '-f', '1',
# we need to sanitize and str-ize the various bits which '-f', '2',
# dbus gives us. '-c', self._bundle.get_path(),
gobject.spawn_async([str(s) for s in command], '-u', pwd.getpwuid(os.getuid()).pw_name,
envp=['%s=%s' % (k, str(v)) '-i', environ['SUGAR_BUNDLE_ID'],
for k, v in environ.items()], '-e', envdir,
working_directory=str(self._bundle.get_path()), '--'
child_setup=child_setup, ] + command
flags=(gobject.SPAWN_SEARCH_PATH | for k, v in environ.items():
gobject.SPAWN_LEAVE_DESCRIPTORS_OPEN)) open(os.path.join(envdir, str(k)), 'w').write(str(v))
log_file.close() log_file.write(' '.join(command) + '\n\n')
else:
log_file.close() def handler(pid, condition, user_data):
system_bus = dbus.SystemBus() if envdir: subprocess.call(['/bin/rm', '-rf', envdir])
factory = system_bus.get_object(_RAINBOW_SERVICE_NAME, try:
_RAINBOW_ACTIVITY_FACTORY_PATH) log_file.write('Activity died: pid %s condition %s data %s\n' %
factory.CreateActivity( (pid, condition, user_data))
log_path, finally:
environ, log_file.close()
command,
environ['SUGAR_BUNDLE_PATH'], # try to reap zombies in case SIGCHLD has not been set to SIG_IGN
environ['SUGAR_BUNDLE_ID'], try :
timeout=30, os.waitpid(pid, 0)
reply_handler=self._create_reply_handler, except OSError:
error_handler=self._create_error_handler, # SIGCHLD = SIG_IGN, no zombies
dbus_interface=_RAINBOW_ACTIVITY_FACTORY_INTERFACE) pass
devnull = file("/dev/null", "r")
child = subprocess.Popen([str(s) for s in command], env=environ,
cwd=str(self._bundle.get_path()), close_fds=True,
stdin=devnull.fileno(), stdout=log_file.fileno(),
stderr=log_file.fileno())
gobject.child_watch_add(child.pid, handler, self._handle.activity_id)
def _no_reply_handler(self, *args): def _no_reply_handler(self, *args):
pass pass