From: Sascha Silbe <sascha@silbe.org>
Subject: [PATCH] sugar-emulator: kill X server on exit (#1440)
If sugar aborts abnormally, the X server might keep running, so we should kill
it off after sugar returns.
Signed-off-by: Sascha Silbe <sascha@silbe.org>
---
src/jarabe/util/emulator.py | 71 ++++++++++++++++++++++++-------------------
1 files changed, 40 insertions(+), 31 deletions(-)
diff --git a/src/jarabe/util/emulator.py b/src/jarabe/util/emulator.py
index d2dacb5..f1f4504 100644
a
|
b
|
|
16 | 16 | |
17 | 17 | import os |
18 | 18 | import random |
| 19 | import signal |
19 | 20 | import subprocess |
20 | 21 | import time |
21 | 22 | from optparse import OptionParser |
… |
… |
import gobject |
25 | 26 | |
26 | 27 | from sugar import env |
27 | 28 | |
| 29 | |
28 | 30 | default_dimensions = (800, 600) |
29 | 31 | def _run_xephyr(display, dpi, dimensions, fullscreen): |
30 | 32 | cmd = [ 'Xephyr' ] |
… |
… |
def _run_xephyr(display, dpi, dimensions, fullscreen): |
56 | 58 | cmd.append('-dpi') |
57 | 59 | cmd.append('%d' % dpi) |
58 | 60 | |
59 | | result = gobject.spawn_async(cmd, flags=gobject.SPAWN_SEARCH_PATH) |
60 | | pid = result[0] |
| 61 | pipe = subprocess.Popen(cmd) |
61 | 62 | |
62 | 63 | os.environ['DISPLAY'] = ":%d" % (display) |
63 | | os.environ['SUGAR_EMULATOR_PID'] = str(pid) |
| 64 | os.environ['SUGAR_EMULATOR_PID'] = str(pipe.pid) |
| 65 | return pipe |
| 66 | |
64 | 67 | |
65 | | def _check_xephyr(display): |
| 68 | def _check_server(display): |
66 | 69 | result = subprocess.call(['xdpyinfo', '-display', ':%d' % display], |
67 | 70 | stdout=open(os.devnull, "w"), |
68 | 71 | stderr=open(os.devnull, "w")) |
69 | 72 | return result == 0 |
70 | 73 | |
| 74 | |
| 75 | def _kill_pipe(pipe): |
| 76 | """Terminate and wait for child process.""" |
| 77 | try: |
| 78 | os.kill(pipe.pid, signal.SIGTERM) |
| 79 | except OSError: |
| 80 | pass |
| 81 | |
| 82 | pipe.wait() |
| 83 | |
| 84 | |
71 | 85 | def _start_xephyr(dpi, dimensions, fullscreen): |
72 | | # FIXME evil workaround until F10 Xephyr is fixed |
73 | | if os.path.exists('/etc/fedora-release'): |
74 | | if open('/etc/fedora-release').read().startswith('Fedora release 10'): |
75 | | display = random.randint(100, 500) |
76 | | _run_xephyr(display, dpi, dimensions, fullscreen) |
77 | | return display |
78 | | |
79 | | for display in range(100, 110): |
80 | | if not _check_xephyr(display): |
81 | | _run_xephyr(display, dpi, dimensions, fullscreen) |
82 | | |
83 | | tries = 10 |
84 | | while tries > 0: |
85 | | if _check_xephyr(display): |
86 | | return display |
87 | | else: |
88 | | tries -= 1 |
89 | | time.sleep(0.1) |
90 | | |
91 | | def _start_window_manager(display): |
| 86 | for display in range(30, 40): |
| 87 | if not _check_server(display): |
| 88 | pipe = _run_xephyr(display, dpi, dimensions, fullscreen) |
| 89 | |
| 90 | for i_ in range(10): |
| 91 | if _check_server(display): |
| 92 | return pipe |
| 93 | |
| 94 | time.sleep(0.1) |
| 95 | |
| 96 | _kill_pipe(pipe) |
| 97 | |
| 98 | |
| 99 | def _start_window_manager(): |
92 | 100 | cmd = ['metacity'] |
93 | 101 | |
94 | | cmd.extend(['--no-force-fullscreen', '-d', ':%d' % display]) |
| 102 | cmd.extend(['--no-force-fullscreen']) |
95 | 103 | |
96 | 104 | gobject.spawn_async(cmd, flags=gobject.SPAWN_SEARCH_PATH) |
97 | 105 | |
… |
… |
def main(): |
146 | 154 | |
147 | 155 | _setup_env() |
148 | 156 | |
149 | | display = _start_xephyr(options.dpi, options.dimensions, options.fullscreen) |
| 157 | server = _start_xephyr(options.dpi, options.dimensions, options.fullscreen) |
150 | 158 | |
151 | 159 | if options.scaling: |
152 | 160 | os.environ['SUGAR_SCALING'] = options.scaling |
153 | 161 | |
154 | | command = ['dbus-launch', 'dbus-launch', '--exit-with-session'] |
| 162 | command = ['dbus-launch', '--exit-with-session'] |
155 | 163 | |
156 | 164 | if not args: |
157 | | command.extend(['sugar', '-d', ':%d' % display]) |
| 165 | command.append('sugar') |
158 | 166 | else: |
159 | | _start_window_manager(display) |
| 167 | _start_window_manager() |
160 | 168 | |
161 | 169 | if args[0].endswith('.py'): |
162 | 170 | command.append('python') |
163 | 171 | |
164 | 172 | command.append(args[0]) |
165 | | |
166 | | os.execlp(*command) |
| 173 | |
| 174 | subprocess.call(command) |
| 175 | _kill_pipe(server) |