diff options
author | Tomeu Vizoso <tomeu@sugarlabs.org> | 2009-08-01 16:34:36 (GMT) |
---|---|---|
committer | Tomeu Vizoso <tomeu@sugarlabs.org> | 2009-08-01 16:34:36 (GMT) |
commit | acdc647f58600c6f0c406a61264e6bbb3a288203 (patch) | |
tree | cc9f84e4c414cf65e0dbe267d331eb26d614b5fd | |
parent | 8f271e2604fb3cef112e522b55257caad0b54a1f (diff) | |
parent | a65c8d2148ba5028437114049027e594238f2ed8 (diff) |
Merge branch 'master' of git://dev.laptop.org/users/mstone/sugar-toolkit
-rw-r--r-- | src/sugar/activity/activityfactory.py | 82 |
1 files changed, 44 insertions, 38 deletions
diff --git a/src/sugar/activity/activityfactory.py b/src/sugar/activity/activityfactory.py index e218a7c..c31ae4b 100644 --- a/src/sugar/activity/activityfactory.py +++ b/src/sugar/activity/activityfactory.py @@ -34,6 +34,9 @@ from sugar import env from errno import EEXIST, ENOSPC import os +import tempfile +import subprocess +import pwd _SHELL_SERVICE = "org.laptop.Shell" _SHELL_PATH = "/org/laptop/Shell" @@ -45,10 +48,6 @@ _DS_PATH = "/org/laptop/sugar/DataStore" _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 # borrowed from subprocess.py try: @@ -253,40 +252,47 @@ class ActivityCreationHandler(gobject.GObject): self._handle.object_id, self._handle.uri) - if not self._use_rainbow: - # use gobject spawn functionality, so that zombies are - # automatically reaped by the gobject event loop. - def child_setup(): - # clone logfile.fileno() onto stdout/stderr - os.dup2(log_file.fileno(), 1) - os.dup2(log_file.fileno(), 2) - # close all other fds - _close_fds() - # we need to sanitize and str-ize the various bits which - # dbus gives us. - gobject.spawn_async([str(s) for s in command], - envp=['%s=%s' % (k, str(v)) - for k, v in environ.items()], - working_directory=str(self._bundle.get_path()), - child_setup=child_setup, - flags=(gobject.SPAWN_SEARCH_PATH | - gobject.SPAWN_LEAVE_DESCRIPTORS_OPEN)) - log_file.close() - else: - log_file.close() - system_bus = dbus.SystemBus() - factory = system_bus.get_object(_RAINBOW_SERVICE_NAME, - _RAINBOW_ACTIVITY_FACTORY_PATH) - factory.CreateActivity( - log_path, - environ, - command, - environ['SUGAR_BUNDLE_PATH'], - environ['SUGAR_BUNDLE_ID'], - timeout=30, - reply_handler=self._create_reply_handler, - error_handler=self._create_error_handler, - dbus_interface=_RAINBOW_ACTIVITY_FACTORY_INTERFACE) + envdir = None + if self._use_rainbow: + envdir = tempfile.mkdtemp() + command = ['/usr/bin/sudo', '-E', '--', + '/usr/bin/rainbow-run', + '-v', '-v', + '-a', '/usr/bin/rainbow-sugarize', + '-s', '/var/spool/rainbow/2', + '-f', '1', + '-f', '2', + '-c', self._bundle.get_path(), + '-u', pwd.getpwuid(os.getuid()).pw_name, + '-i', environ['SUGAR_BUNDLE_ID'], + '-e', envdir, + '--' + ] + command + for k, v in environ.items(): + open(os.path.join(envdir, str(k)), 'w').write(str(v)) + log_file.write(' '.join(command) + '\n\n') + + def handler(pid, condition, user_data): + if envdir: subprocess.call(['/bin/rm', '-rf', envdir]) + try: + log_file.write('Activity died: pid %s condition %s data %s\n' % + (pid, condition, user_data)) + finally: + log_file.close() + + # try to reap zombies in case SIGCHLD has not been set to SIG_IGN + try : + os.waitpid(pid, 0) + except OSError: + # SIGCHLD = SIG_IGN, no zombies + 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): pass |