##// END OF EJS Templates
server: refactor 'daemon_postexec' instructions into a dictionary
Matt Harbison -
r37232:73a60281 default
parent child Browse files
Show More
@@ -30,26 +30,35 b' def runservice(opts, parentfn=None, init'
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):
43 procutil.stdout.flush()
44 procutil.stderr.flush()
45
54
46 fd = os.open(lockpath,
55 fd = os.open(postexecargs['unlink'],
47 os.O_WRONLY | os.O_APPEND | os.O_BINARY)
56 os.O_WRONLY | os.O_APPEND | os.O_BINARY)
48 try:
57 try:
49 os.dup2(fd, 1)
58 os.dup2(fd, 1)
50 os.dup2(fd, 2)
59 os.dup2(fd, 2)
51 finally:
60 finally:
52 os.close(fd)
61 os.close(fd)
53
62
54 def writepid(pid):
63 def writepid(pid):
55 if opts['pid_file']:
64 if opts['pid_file']:
@@ -109,15 +118,8 b' def runservice(opts, parentfn=None, init'
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()
@@ -137,8 +139,8 b' def runservice(opts, parentfn=None, init'
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()
General Comments 0
You need to be logged in to leave comments. Login now