Neat project!

Attached is a patch for your consideration.  It adds an optional
argument to the "xpra server" sub-command to run a specified command
(presumably an X client application); when this application exits, the
server is terminated (unless --no-automatic-stop was specified).

Sample usages:  (Note:  a -- is required before the command if it
contains any options starting with a -.)
     xpra start :20 -- xterm -fn 10x20
     xpra --no-automatic-stop start :20 xterm

Thanks,
Robert
#
# old_revision [c30240948380b44f3ef60a25cbb4d14fef5b2b8a]
#
# patch "xpra/scripts/main.py"
#  from [ab87ff74958e2549a9e817957a7fe6ed8463a558]
#    to [1c67d19d3645cf0a699478735fcba6e6def9fcd5]
# 
# patch "xpra/scripts/server.py"
#  from [e8923cc866750d4196572ea0648f089c02ae69c9]
#    to [f5cac2559f6bfad9dffde16ee6ff51d01b1b8507]
#
============================================================
--- xpra/scripts/main.py	ab87ff74958e2549a9e817957a7fe6ed8463a558
+++ xpra/scripts/main.py	1c67d19d3645cf0a699478735fcba6e6def9fcd5
@@ -19,7 +19,7 @@ def main(script_file, cmdline):
 def main(script_file, cmdline):
     parser = OptionParser(version="xpra v%s" % xpra.__version__,
                           usage=("\n"
-                                 + "\t%prog start DISPLAY\n"
+                                 + "\t%prog start DISPLAY [ [--no-automatic-stop] -- command]\n"
                                  + "\t%prog attach DISPLAY\n"
                                  + "\t%prog stop DISPLAY\n"
                                  + "\t%prog list\n"
@@ -27,6 +27,9 @@ def main(script_file, cmdline):
     parser.add_option("--no-daemon", action="store_false",
                       dest="daemon", default=True,
                       help="Don't daemonize when running as a server")
+    parser.add_option("--no-automatic-stop", action="store_false",
+                      dest="automatic_stop", default=True,
+                      help="Don't terminate server when client on start command exits")
     parser.add_option("--remote-xpra", action="store",
                       dest="remote_xpra", default=None, metavar="CMD",
                       help="How to run 'xpra' on the remote host")
============================================================
--- xpra/scripts/server.py	e8923cc866750d4196572ea0648f089c02ae69c9
+++ xpra/scripts/server.py	f5cac2559f6bfad9dffde16ee6ff51d01b1b8507
@@ -6,6 +6,7 @@ import time
 import atexit
 import signal
 import time
+import posix
 
 from wimpiggy.prop import prop_set, prop_get
 
@@ -31,6 +32,18 @@ def deadly_signal(signum, frame):
     #kill(os.getpid(), signum)
     os._exit(128 + signum)
 
+required_children = [];
+def child_signal(signum, frame):
+    while 1:
+        try:
+            pid,status=posix.waitpid(-1,posix.WNOHANG)
+        except OSError:
+            break
+        if pid == 0:
+            break
+        if pid in required_children:
+            os.exit(0)
+
 def save_pid(pid):
     prop_set(gtk.gdk.get_default_root_window(),
              "_XPRA_SERVER_PID", "u32", pid)
@@ -99,9 +112,10 @@ def run_server(parser, opts, mode, xpra_
                          % TIMEOUT)
 
 def run_server(parser, opts, mode, xpra_file, extra_args):
-    if len(extra_args) != 1:
-        parser.error("need exactly 1 extra argument")
+    if len(extra_args) < 1:
+        parser.error("need at least 1 extra argument")
     display_name = extra_args[0]
+    extra_args.pop(0)
 
     atexit.register(run_cleanups)
     signal.signal(signal.SIGINT, deadly_signal)
@@ -211,6 +225,18 @@ def run_server(parser, opts, mode, xpra_
     if xvfb_pid is not None:
         save_pid(xvfb_pid)
 
+    if len(extra_args) > 0:
+        if opts.automatic_stop:
+           signal.signal(signal.SIGCHLD, child_signal)
+        pid = os.fork()
+        if 0 == pid:
+            print "executing: "+" ".join(extra_args)
+            os.execvp(extra_args[0], extra_args)
+            print "execvp failed"
+            os._exit(9)
+        if opts.automatic_stop:
+           required_children.append(pid)
+
     app = XpraServer(sockpath, upgrading)
     def cleanup_socket(self):
         print "removing socket"
_______________________________________________
Parti-discuss mailing list
[email protected]
http://lists.partiwm.org/cgi-bin/mailman/listinfo/parti-discuss

Reply via email to