# HG changeset patch # User Patrick Mezard # Date 1239391225 -7200 # Node ID 2f7a38f336f42d7f82dbf91494a27ba8ae64faf3 # Parent 49a8625b8cac416ea1d874e251d366f5a31d0e5b serve: add and use portable spawnvp replacement There is no standard python command to really detach a process under Windows. Instead we use the low level API wrapped by subprocess module with all necessary options to avoid any kind of context inheritance. Unfortunately, this version still opens a new window for the child process. The following have been tried: - os.spawnv(os.P_NOWAIT): works but the child process is killed when parent console terminates. - os.spawnv(os.P_DETACH): works on python25, hang on python26 when writing to the hgweb output socket. - subprocess.CreateProcess() hack without shell mode: similar to os.spawnv(os.P_DETACH). Fix 1/3 for issue421 diff -r 49a8625b8cac -r 2f7a38f336f4 mercurial/cmdutil.py --- a/mercurial/cmdutil.py Tue Jan 12 15:12:53 2010 +0100 +++ b/mercurial/cmdutil.py Fri Apr 10 21:20:25 2009 +0200 @@ -580,8 +580,7 @@ elif runargs[i].startswith('--cwd'): del runargs[i:i+2] break - pid = os.spawnvp(os.P_NOWAIT | getattr(os, 'P_DETACH', 0), - runargs[0], runargs) + pid = util.spawndetached(runargs) os.close(wfd) os.read(rfd, 1) if parentfn: diff -r 49a8625b8cac -r 2f7a38f336f4 mercurial/posix.py --- a/mercurial/posix.py Tue Jan 12 15:12:53 2010 +0100 +++ b/mercurial/posix.py Fri Apr 10 21:20:25 2009 +0200 @@ -257,3 +257,8 @@ return grp.getgrgid(gid)[0] except KeyError: return str(gid) + +def spawndetached(args): + return os.spawnvp(os.P_NOWAIT | getattr(os, 'P_DETACH', 0), + args[0], args) + diff -r 49a8625b8cac -r 2f7a38f336f4 mercurial/windows.py --- a/mercurial/windows.py Tue Jan 12 15:12:53 2010 +0100 +++ b/mercurial/windows.py Fri Apr 10 21:20:25 2009 +0200 @@ -7,7 +7,7 @@ from i18n import _ import osutil, error -import errno, msvcrt, os, re, sys, random +import errno, msvcrt, os, re, sys, random, subprocess nulldev = 'NUL:' umask = 002 @@ -321,6 +321,37 @@ pass os.rename(src, dst) +def spawndetached(args): + # No standard library function really spawns a fully detached + # process under win32 because they allocate pipes or other objects + # to handle standard streams communications. Passing these objects + # to the child process requires handle inheritance to be enabled + # which makes really detached processes impossible. + class STARTUPINFO: + dwFlags = subprocess.STARTF_USESHOWWINDOW + hStdInput = None + hStdOutput = None + hStdError = None + wShowWindow = subprocess.SW_HIDE + + args = subprocess.list2cmdline(args) + # Not running the command in shell mode makes python26 hang when + # writing to hgweb output socket. + comspec = os.environ.get("COMSPEC", "cmd.exe") + args = comspec + " /c " + args + hp, ht, pid, tid = subprocess.CreateProcess( + None, args, + # no special security + None, None, + # Do not inherit handles + 0, + # DETACHED_PROCESS + 0x00000008, + os.environ, + os.getcwd(), + STARTUPINFO()) + return pid + try: # override functions with win32 versions if possible from win32 import *