def __session_child_watch_handler(self, pid, status): if not os.WIFEXITED(status): exit_code = util.EXIT_CODE_FATAL if os.WIFSIGNALED(status): signal_num = os.WTERMSIG(status) mprint("sabayon-session exited with SIGNAL %s", signal_num) else: mprint("sabayon-session exited for an unknown reason") else: exit_code = os.WEXITSTATUS(status) # Here we cannot throw an exception for the error cases, # since we are a callback running out of the Glib main # loop. So we have to set a flag and let the code # *outside* the main loop pick it up. if exit_code == util.EXIT_CODE_NORMAL: mprint("sabayon-session exited normally") success = True elif exit_code == util.EXIT_CODE_RECOVERABLE: errors.errors_log_recoverable_error( debuglog.DEBUG_LOG_DOMAIN_ADMIN_TOOL, "sabayon-session exited with RECOVERABLE exit status" ) # FIXME: throw a warning dialog else: errors.errors_log_fatal_error( debuglog.DEBUG_LOG_DOMAIN_ADMIN_TOOL, "sabayon-session exited with a FATAL ERROR (exit code %s)" % exit_code, ) gtk.main_quit() # so that the toplevel 'sabayon' will exit the main loop and show the fatal error protosession.clobber_user_processes(self.username) protosession.reset_shell_and_homedir(self.username, self.temp_homedir) self.temp_homedir = None if self.temp_xauth_path: os.remove(self.temp_xauth_path) self.temp_xauth_path = None self.__copy_from_user(self.user_profile_path, self.profile_path) self.user_profile_path = None self.session_pid = 0 self.session_child_watch = 0 # gobject.source_remove (self.session_stderr_watch_id) # self.session_stderr_watch_id = 0 # self.session_stderr.close () # self.session_stderr = None self.emit("finished") return False
def start(self): self.user_profile_path = self.__copy_to_user(self.profile_path) protosession.clobber_user_processes(self.username) self.temp_homedir = protosession.setup_shell_and_homedir(self.username) display_number = protosession.find_free_display() self.temp_xauth_path = self.__copy_xauthority() def child_setup_fn(self): os.setgid(self.pw.pw_gid) os.setuid(self.pw.pw_uid) os.setsid() os.umask(022) # FIXME: get_readable_log_config_filename() doesn't work here. # Create a temporary copy of the log config file and use *that*. argv = SESSION_TOOL_ARGV + [ ("--admin-log-config=%s" % util.get_admin_log_config_filename()), ("--readable-log-config=%s" % util.get_readable_log_config_filename()), self.profile_name, self.user_profile_path, str(display_number), ] envp = self.build_envp_for_child() cwd = self.temp_homedir # FIXME: do we need any special processing if this throws an exception? # We'll catch it in the toplevel and exit with a fatal error code, anyway. (pid, oink, oink, oink) = gobject.spawn_async( argv, envp, cwd, gobject.SPAWN_DO_NOT_REAP_CHILD, child_setup_fn, self, None, None, None ) # stdin, stdout, stderr self.session_pid = pid # self.session_stderr = os.fdopen (stderr_fd) # self.session_stderr_watch_id = gobject.io_add_watch (stderr_fd, # gobject.IO_IN | gobject.IO_HUP, # self.session_stderr_io_cb, self) self.session_child_watch = gobject.child_watch_add(self.session_pid, self.__session_child_watch_handler)