64aa729edd
Lots of things here were unused. First, we don't need to calculate the js_dir when not running from the source tree, which makes the branch mostly empty, meaning we can merge the two branches.
180 lines
5.6 KiB
Plaintext
Executable File
180 lines
5.6 KiB
Plaintext
Executable File
#!@PYTHON@
|
|
# -*- mode: Python; indent-tabs-mode: nil; -*-
|
|
|
|
import optparse
|
|
import os
|
|
import re
|
|
import signal
|
|
import subprocess
|
|
import sys
|
|
import termios
|
|
|
|
def show_version(option, opt_str, value, parser):
|
|
print "GNOME Shell @VERSION@"
|
|
sys.exit()
|
|
|
|
def get_running_session_environs():
|
|
wanted_environment = ['DBUS_SESSION_BUS_ADDRESS', 'DISPLAY', 'XDG_DATA_DIRS',
|
|
'XAUTHORITY', 'XDG_SESSION_COOKIE', 'ORBIT_SOCKETDIR',
|
|
'SESSION_MANAGER']
|
|
num_re = re.compile('^[0-9]+$')
|
|
myuid = os.getuid()
|
|
if not os.path.isdir('/proc'):
|
|
return {}
|
|
for filename in os.listdir('/proc'):
|
|
if not num_re.match(filename):
|
|
continue
|
|
piddir = '/proc/' + filename
|
|
try:
|
|
stat = os.stat(piddir)
|
|
except OSError, e:
|
|
continue
|
|
if not stat.st_uid == myuid:
|
|
continue
|
|
try:
|
|
f = open(piddir + "/cmdline")
|
|
command = f.read()
|
|
f.close()
|
|
except IOError, e:
|
|
continue
|
|
# /proc/cmdline is separated and terminated by NULs
|
|
command = command.split("\x00")[0]
|
|
command = os.path.basename(command)
|
|
if command != 'gnome-session':
|
|
continue
|
|
try:
|
|
f = open(os.path.join(piddir, 'environ'))
|
|
except OSError, e:
|
|
continue
|
|
environ_data = f.read()
|
|
f.close()
|
|
# There's a trailing null at the last one, so remove the
|
|
# empty string
|
|
environs = environ_data.split('\0')[:-1]
|
|
# Rumor has it the presence of just FOO (instead of FOO=bar)
|
|
# represents a deleted environment variable
|
|
environs = filter(lambda x: '=' in x, environs)
|
|
# Turn it into a dictionary
|
|
environs = dict(map(lambda x: x.split('=', 1), environs))
|
|
result = {}
|
|
for key in wanted_environment:
|
|
if key in environs:
|
|
result[key] = environs[key]
|
|
return result
|
|
|
|
def start_shell():
|
|
self_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
|
|
running_from_source_tree = os.path.exists(os.path.join(self_dir, 'gnome-shell-jhbuild.in'))
|
|
|
|
# Set up environment
|
|
env = dict(os.environ)
|
|
if running_from_source_tree:
|
|
top_dir = os.path.dirname(self_dir)
|
|
|
|
typelib_dir = os.path.join(top_dir, "src")
|
|
if 'GI_TYPELIB_PATH' in os.environ:
|
|
typelib_dir += ':%s' % (os.environ['GI_TYPELIB_PATH'],)
|
|
|
|
env.update({'GNOME_SHELL_JS' : os.path.join(top_dir, "js"),
|
|
'GNOME_SHELL_BINDIR' : self_dir,
|
|
'GI_TYPELIB_PATH' : typelib_dir,
|
|
'GNOME_SHELL_DATADIR' : os.path.join(top_dir, "data"),
|
|
'GSETTINGS_SCHEMA_DIR' : os.path.join(top_dir, "data") })
|
|
|
|
args = []
|
|
if options.debug:
|
|
debug_command = options.debug_command.split()
|
|
if running_from_source_tree:
|
|
args += [os.path.join(top_dir, 'libtool'), '--mode=execute']
|
|
args += debug_command
|
|
|
|
args.append(os.path.join(self_dir, 'gnome-shell-real'))
|
|
if options.replace:
|
|
args.append('--replace')
|
|
if options.sync:
|
|
args.append('--sync')
|
|
return subprocess.Popen(args, env=env)
|
|
|
|
def run_shell():
|
|
if options.debug:
|
|
# Record initial terminal state so we can reset it to that
|
|
# later, in case we kill gdb at a bad time
|
|
termattrs = termios.tcgetattr(0);
|
|
|
|
normal_exit = False
|
|
|
|
if options.verbose:
|
|
print "Starting shell"
|
|
|
|
shell = None
|
|
try:
|
|
shell = start_shell()
|
|
|
|
# Wait for shell to exit
|
|
if options.verbose:
|
|
print "Waiting for shell to exit"
|
|
shell.wait()
|
|
|
|
except KeyboardInterrupt, e:
|
|
try:
|
|
os.kill(shell.pid, signal.SIGKILL)
|
|
except:
|
|
pass
|
|
shell.wait()
|
|
finally:
|
|
if shell is None:
|
|
print "Failed to start shell"
|
|
elif shell.returncode == 0:
|
|
normal_exit = True
|
|
if options.verbose:
|
|
print "Shell exited normally"
|
|
elif shell.returncode < 0:
|
|
# Python has no mapping for strsignal; not worth using
|
|
# ctypes for this.
|
|
print "Shell killed with signal %d" % - shell.returncode
|
|
else:
|
|
# Normal reason here would be losing connection the X server
|
|
if options.verbose:
|
|
print "Shell exited with return code %d" % shell.returncode
|
|
|
|
if options.debug:
|
|
termios.tcsetattr(0, termios.TCSANOW, termattrs);
|
|
|
|
return normal_exit
|
|
|
|
# Main program
|
|
|
|
parser = optparse.OptionParser()
|
|
parser.add_option("-r", "--replace", action="store_true",
|
|
help="Replace the running metacity/gnome-panel")
|
|
parser.add_option("-g", "--debug", action="store_true",
|
|
help="Run under a debugger")
|
|
parser.add_option("", "--debug-command", metavar="COMMAND",
|
|
help="Command to use for debugging (defaults to 'gdb --args')")
|
|
parser.add_option("-v", "--verbose", action="store_true")
|
|
parser.add_option("", "--sync", action="store_true")
|
|
parser.add_option("", "--version", action="callback", callback=show_version,
|
|
help="Display version and exit")
|
|
|
|
options, args = parser.parse_args()
|
|
|
|
if args:
|
|
parser.print_usage()
|
|
sys.exit(1)
|
|
|
|
# Handle ssh logins
|
|
if 'DISPLAY' not in os.environ:
|
|
running_env = get_running_session_environs()
|
|
os.environ.update(running_env)
|
|
|
|
if options.debug_command:
|
|
options.debug = True
|
|
elif options.debug:
|
|
options.debug_command = "gdb --args"
|
|
|
|
normal_exit = run_shell()
|
|
if normal_exit:
|
|
sys.exit(0)
|
|
else:
|
|
sys.exit(1)
|