2009-08-31 15:52:18 +00:00
|
|
|
#!@PYTHON@
|
2010-05-11 20:43:38 +00:00
|
|
|
# -*- mode: Python; indent-tabs-mode: nil; -*-
|
2009-02-23 19:52:49 +00:00
|
|
|
|
|
|
|
import optparse
|
|
|
|
import os
|
|
|
|
import re
|
|
|
|
import signal
|
|
|
|
import subprocess
|
|
|
|
import sys
|
2009-04-13 15:58:05 +00:00
|
|
|
import termios
|
2009-02-23 19:52:49 +00:00
|
|
|
|
2010-03-17 17:02:24 +00:00
|
|
|
def show_version(option, opt_str, value, parser):
|
|
|
|
print "GNOME Shell @VERSION@"
|
|
|
|
sys.exit()
|
|
|
|
|
2010-02-25 18:35:32 +00:00
|
|
|
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:
|
2010-04-24 13:41:03 +00:00
|
|
|
f = open(piddir + "/cmdline")
|
|
|
|
command = f.read()
|
|
|
|
f.close()
|
|
|
|
except IOError, e:
|
2010-02-25 18:35:32 +00:00
|
|
|
continue
|
2010-04-24 13:41:03 +00:00
|
|
|
# /proc/cmdline is separated and terminated by NULs
|
|
|
|
command = command.split("\x00")[0]
|
|
|
|
command = os.path.basename(command)
|
|
|
|
if command != 'gnome-session':
|
2010-02-25 18:35:32 +00:00
|
|
|
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
|
|
|
|
|
2012-04-12 17:43:08 +00:00
|
|
|
def start_shell():
|
2011-02-25 16:20:27 +00:00
|
|
|
self_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
|
2012-04-26 20:28:16 +00:00
|
|
|
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:
|
2011-02-25 16:20:27 +00:00
|
|
|
top_dir = os.path.dirname(self_dir)
|
2012-04-26 20:28:16 +00:00
|
|
|
|
2012-04-26 20:25:19 +00:00
|
|
|
typelib_dir = os.path.join(top_dir, "src")
|
|
|
|
if 'GI_TYPELIB_PATH' in os.environ:
|
|
|
|
typelib_dir += ':%s' % (os.environ['GI_TYPELIB_PATH'],)
|
2009-03-11 13:59:02 +00:00
|
|
|
|
2012-12-23 04:37:06 +00:00
|
|
|
env.update({'GI_TYPELIB_PATH' : typelib_dir,
|
|
|
|
'GNOME_SHELL_JS' : os.path.join(top_dir, "js"),
|
2012-04-26 20:28:16 +00:00
|
|
|
'GNOME_SHELL_DATADIR' : os.path.join(top_dir, "data"),
|
|
|
|
'GSETTINGS_SCHEMA_DIR' : os.path.join(top_dir, "data") })
|
2010-05-11 22:08:50 +00:00
|
|
|
|
2011-02-25 16:20:27 +00:00
|
|
|
args = []
|
2009-02-23 19:52:49 +00:00
|
|
|
if options.debug:
|
|
|
|
debug_command = options.debug_command.split()
|
2011-02-25 16:20:27 +00:00
|
|
|
if running_from_source_tree:
|
|
|
|
args += [os.path.join(top_dir, 'libtool'), '--mode=execute']
|
|
|
|
args += debug_command
|
2011-02-17 22:07:13 +00:00
|
|
|
|
2011-02-25 16:20:27 +00:00
|
|
|
args.append(os.path.join(self_dir, 'gnome-shell-real'))
|
2009-08-27 18:07:46 +00:00
|
|
|
if options.replace:
|
|
|
|
args.append('--replace')
|
2009-02-23 19:52:49 +00:00
|
|
|
if options.sync:
|
|
|
|
args.append('--sync')
|
2012-12-06 15:58:53 +00:00
|
|
|
args += params
|
2009-02-23 19:52:49 +00:00
|
|
|
return subprocess.Popen(args, env=env)
|
|
|
|
|
2012-04-12 17:43:08 +00:00
|
|
|
def run_shell():
|
2010-05-11 20:43:38 +00:00
|
|
|
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"
|
|
|
|
|
2012-04-26 20:17:34 +00:00
|
|
|
shell = None
|
2010-05-11 20:43:38 +00:00
|
|
|
try:
|
2012-04-12 17:43:08 +00:00
|
|
|
shell = start_shell()
|
2010-05-11 20:43:38 +00:00
|
|
|
|
|
|
|
# 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
|
|
|
|
|
2009-02-23 19:52:49 +00:00
|
|
|
# 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")
|
2010-03-17 17:02:24 +00:00
|
|
|
parser.add_option("", "--version", action="callback", callback=show_version,
|
|
|
|
help="Display version and exit")
|
2009-02-23 19:52:49 +00:00
|
|
|
|
2012-12-06 15:58:53 +00:00
|
|
|
options, params = parser.parse_args()
|
2009-02-23 19:52:49 +00:00
|
|
|
|
2010-04-29 14:30:58 +00:00
|
|
|
# Handle ssh logins
|
|
|
|
if 'DISPLAY' not in os.environ:
|
|
|
|
running_env = get_running_session_environs()
|
|
|
|
os.environ.update(running_env)
|
|
|
|
|
2009-02-23 19:52:49 +00:00
|
|
|
if options.debug_command:
|
|
|
|
options.debug = True
|
|
|
|
elif options.debug:
|
|
|
|
options.debug_command = "gdb --args"
|
|
|
|
|
2012-04-12 17:51:40 +00:00
|
|
|
normal_exit = run_shell()
|
2011-03-11 00:17:14 +00:00
|
|
|
if normal_exit:
|
|
|
|
sys.exit(0)
|
|
|
|
else:
|
|
|
|
sys.exit(1)
|