Mercurial > hg
comparison mercurial/server.py @ 37215:73a60281a861
server: refactor 'daemon_postexec' instructions into a dictionary
author | Matt Harbison <matt_harbison@yahoo.com> |
---|---|
date | Fri, 30 Mar 2018 23:21:46 -0400 |
parents | f09a2eab11cf |
children | d2bd29dffc6c |
comparison
equal
deleted
inserted
replaced
37214:3bc609bcfe77 | 37215:73a60281a861 |
---|---|
28 | 28 |
29 def runservice(opts, parentfn=None, initfn=None, runfn=None, logfile=None, | 29 def runservice(opts, parentfn=None, initfn=None, runfn=None, logfile=None, |
30 runargs=None, appendpid=False): | 30 runargs=None, appendpid=False): |
31 '''Run a command as a service.''' | 31 '''Run a command as a service.''' |
32 | 32 |
33 postexecargs = {} | |
34 | |
35 if opts['daemon_postexec']: | |
36 for inst in opts['daemon_postexec']: | |
37 if inst.startswith('unlink:'): | |
38 postexecargs['unlink'] = inst[7:] | |
39 elif inst.startswith('chdir:'): | |
40 postexecargs['chdir'] = inst[6:] | |
41 elif inst != 'none': | |
42 raise error.Abort(_('invalid value for --daemon-postexec: %s') | |
43 % inst) | |
44 | |
33 # When daemonized on Windows, redirect stdout/stderr to the lockfile (which | 45 # When daemonized on Windows, redirect stdout/stderr to the lockfile (which |
34 # gets cleaned up after the child is up and running), so that the parent can | 46 # gets cleaned up after the child is up and running), so that the parent can |
35 # read and print the error if this child dies early. See 594dd384803c. On | 47 # read and print the error if this child dies early. See 594dd384803c. On |
36 # other platforms, the child can write to the parent's stdio directly, until | 48 # other platforms, the child can write to the parent's stdio directly, until |
37 # it is redirected prior to runfn(). | 49 # it is redirected prior to runfn(). |
38 if pycompat.iswindows and opts['daemon_postexec']: | 50 if pycompat.iswindows and opts['daemon_postexec']: |
39 for inst in opts['daemon_postexec']: | 51 if 'unlink' in postexecargs and os.path.exists(postexecargs['unlink']): |
40 if inst.startswith('unlink:'): | 52 procutil.stdout.flush() |
41 lockpath = inst[7:] | 53 procutil.stderr.flush() |
42 if os.path.exists(lockpath): | 54 |
43 procutil.stdout.flush() | 55 fd = os.open(postexecargs['unlink'], |
44 procutil.stderr.flush() | 56 os.O_WRONLY | os.O_APPEND | os.O_BINARY) |
45 | 57 try: |
46 fd = os.open(lockpath, | 58 os.dup2(fd, 1) |
47 os.O_WRONLY | os.O_APPEND | os.O_BINARY) | 59 os.dup2(fd, 2) |
48 try: | 60 finally: |
49 os.dup2(fd, 1) | 61 os.close(fd) |
50 os.dup2(fd, 2) | |
51 finally: | |
52 os.close(fd) | |
53 | 62 |
54 def writepid(pid): | 63 def writepid(pid): |
55 if opts['pid_file']: | 64 if opts['pid_file']: |
56 if appendpid: | 65 if appendpid: |
57 mode = 'ab' | 66 mode = 'ab' |
107 try: | 116 try: |
108 os.setsid() | 117 os.setsid() |
109 except AttributeError: | 118 except AttributeError: |
110 pass | 119 pass |
111 | 120 |
112 lockpath = None | 121 if 'chdir' in postexecargs: |
113 for inst in opts['daemon_postexec']: | 122 os.chdir(postexecargs['chdir']) |
114 if inst.startswith('unlink:'): | |
115 lockpath = inst[7:] | |
116 elif inst.startswith('chdir:'): | |
117 os.chdir(inst[6:]) | |
118 elif inst != 'none': | |
119 raise error.Abort(_('invalid value for --daemon-postexec: %s') | |
120 % inst) | |
121 procutil.hidewindow() | 123 procutil.hidewindow() |
122 procutil.stdout.flush() | 124 procutil.stdout.flush() |
123 procutil.stderr.flush() | 125 procutil.stderr.flush() |
124 | 126 |
125 nullfd = os.open(os.devnull, os.O_RDWR) | 127 nullfd = os.open(os.devnull, os.O_RDWR) |
135 if logfile and logfilefd not in (0, 1, 2): | 137 if logfile and logfilefd not in (0, 1, 2): |
136 os.close(logfilefd) | 138 os.close(logfilefd) |
137 | 139 |
138 # Only unlink after redirecting stdout/stderr, so Windows doesn't | 140 # Only unlink after redirecting stdout/stderr, so Windows doesn't |
139 # complain about a sharing violation. | 141 # complain about a sharing violation. |
140 if lockpath: | 142 if 'unlink' in postexecargs: |
141 os.unlink(lockpath) | 143 os.unlink(postexecargs['unlink']) |
142 | 144 |
143 if runfn: | 145 if runfn: |
144 return runfn() | 146 return runfn() |
145 | 147 |
146 _cmdservicemap = { | 148 _cmdservicemap = { |