diff --git a/tools/python/xen/xm/create.py b/tools/python/xen/xm/create.py index c19c7ff515..d993fc32ab 100644 --- a/tools/python/xen/xm/create.py +++ b/tools/python/xen/xm/create.py @@ -844,14 +844,58 @@ def choose_vnc_display(): vncpid = None +def daemonize(prog, args): + """Runs a program as a daemon with the list of arguments. Returns the PID + of the daemonized program, or returns 0 on error. + """ + r, w = os.pipe() + pid = os.fork() + + if pid == 0: + os.close(r) + w = os.fdopen(w, 'w') + os.setsid() + try: + pid2 = os.fork() + except: + pid2 = None + if pid2 == 0: + os.chdir("/") + for fd in range(0, 256): + try: + os.close(fd) + except: + pass + os.open("/dev/null", os.O_RDWR) + os.dup2(0, 1) + os.dup2(0, 2) + os.execvp(prog, args) + os._exit(1) + else: + w.write(str(pid2 or 0)) + w.close() + os._exit(0) + + os.close(w) + r = os.fdopen(r) + daemon_pid = int(r.read()) + r.close() + os.waitpid(pid, 0) + return daemon_pid + def spawn_vnc(display): + """Spawns a vncviewer that listens on the specified display. On success, + returns the port that the vncviewer is listening on and sets the global + vncpid. On failure, returns 0. Note that vncviewer is daemonized. + """ vncargs = (["vncviewer", "-log", "*:stdout:0", "-listen", "%d" % (VNC_BASE_PORT + display) ]) - global vncpid - vncpid = os.spawnvp(os.P_NOWAIT, "vncviewer", vncargs) - + global vncpid + vncpid = daemonize("vncviewer", vncargs) + if vncpid == 0: + return 0 return VNC_BASE_PORT + display - + def preprocess_vnc(vals): """If vnc was specified, spawn a vncviewer in listen mode and pass its address to the domain on the kernel command line.