Show More
@@ -36,12 +36,6 b' from __future__ import absolute_import' | |||||
36 |
|
36 | |||
37 | import itertools |
|
37 | import itertools | |
38 | import os |
|
38 | import os | |
39 | import subprocess |
|
|||
40 | import sys |
|
|||
41 |
|
||||
42 | from mercurial import ( |
|
|||
43 | pycompat, |
|
|||
44 | ) |
|
|||
45 |
|
39 | |||
46 | from mercurial.utils import ( |
|
40 | from mercurial.utils import ( | |
47 | procutil, |
|
41 | procutil, | |
@@ -54,51 +48,6 b' from mercurial.utils import (' | |||||
54 | testedwith = 'ships-with-hg-core' |
|
48 | testedwith = 'ships-with-hg-core' | |
55 |
|
49 | |||
56 | def uisetup(ui): |
|
50 | def uisetup(ui): | |
57 | if pycompat.iswindows: |
|
|||
58 | # no fork on Windows, but we can create a detached process |
|
|||
59 | # https://msdn.microsoft.com/en-us/library/windows/desktop/ms684863.aspx |
|
|||
60 | # No stdlib constant exists for this value |
|
|||
61 | DETACHED_PROCESS = 0x00000008 |
|
|||
62 | _creationflags = DETACHED_PROCESS | subprocess.CREATE_NEW_PROCESS_GROUP |
|
|||
63 |
|
||||
64 | def runshellcommand(script, env): |
|
|||
65 | # we can't use close_fds *and* redirect stdin. I'm not sure that we |
|
|||
66 | # need to because the detached process has no console connection. |
|
|||
67 | subprocess.Popen( |
|
|||
68 | procutil.tonativestr(script), |
|
|||
69 | shell=True, env=procutil.tonativeenv(env), close_fds=True, |
|
|||
70 | creationflags=_creationflags) |
|
|||
71 | else: |
|
|||
72 | def runshellcommand(script, env): |
|
|||
73 | # double-fork to completely detach from the parent process |
|
|||
74 | # based on http://code.activestate.com/recipes/278731 |
|
|||
75 | pid = os.fork() |
|
|||
76 | if pid: |
|
|||
77 | # parent |
|
|||
78 | return |
|
|||
79 | # subprocess.Popen() forks again, all we need to add is |
|
|||
80 | # flag the new process as a new session. |
|
|||
81 | if sys.version_info < (3, 2): |
|
|||
82 | newsession = {'preexec_fn': os.setsid} |
|
|||
83 | else: |
|
|||
84 | newsession = {'start_new_session': True} |
|
|||
85 | try: |
|
|||
86 | # connect std* to devnull to make sure the subprocess can't |
|
|||
87 | # muck up these stream for mercurial. |
|
|||
88 | # Connect all the streams to be more close to Windows behavior |
|
|||
89 | # and pager will wait for scripts to end if we don't do that |
|
|||
90 | nullrfd = open(os.devnull, 'r') |
|
|||
91 | nullwfd = open(os.devnull, 'w') |
|
|||
92 | subprocess.Popen( |
|
|||
93 | procutil.tonativestr(script), |
|
|||
94 | shell=True, stdin=nullrfd, |
|
|||
95 | stdout=nullwfd, stderr=nullwfd, |
|
|||
96 | env=procutil.tonativeenv(env), |
|
|||
97 | close_fds=True, **newsession) |
|
|||
98 | finally: |
|
|||
99 | # mission accomplished, this child needs to exit and not |
|
|||
100 | # continue the hg process here. |
|
|||
101 | os._exit(0) |
|
|||
102 |
|
51 | |||
103 | class logtoprocessui(ui.__class__): |
|
52 | class logtoprocessui(ui.__class__): | |
104 | def log(self, event, *msg, **opts): |
|
53 | def log(self, event, *msg, **opts): | |
@@ -133,7 +82,7 b' def uisetup(ui):' | |||||
133 | env = dict(itertools.chain(procutil.shellenviron().items(), |
|
82 | env = dict(itertools.chain(procutil.shellenviron().items(), | |
134 | msgpairs, optpairs), |
|
83 | msgpairs, optpairs), | |
135 | EVENT=event, HGPID=str(os.getpid())) |
|
84 | EVENT=event, HGPID=str(os.getpid())) | |
136 |
|
|
85 | procutil.runbgcommand(script, env, shell=True) | |
137 | return super(logtoprocessui, self).log(event, *msg, **opts) |
|
86 | return super(logtoprocessui, self).log(event, *msg, **opts) | |
138 |
|
87 | |||
139 | # Replace the class for this instance and all clones created from it: |
|
88 | # Replace the class for this instance and all clones created from it: |
General Comments 0
You need to be logged in to leave comments.
Login now