Refactor commands.serve to allow other commands to run as services.
This introduces a new function, cmdutil.service.
--- a/mercurial/cmdutil.py Wed Apr 25 13:14:01 2007 -0700
+++ b/mercurial/cmdutil.py Fri Apr 27 21:30:55 2007 -0700
@@ -200,6 +200,50 @@
if not dry_run:
repo.copy(old, new, wlock=wlock)
+def service(opts, parentfn=None, initfn=None, runfn=None):
+ '''Run a command as a service.'''
+
+ if opts['daemon'] and not opts['daemon_pipefds']:
+ rfd, wfd = os.pipe()
+ args = sys.argv[:]
+ args.append('--daemon-pipefds=%d,%d' % (rfd, wfd))
+ pid = os.spawnvp(os.P_NOWAIT | getattr(os, 'P_DETACH', 0),
+ args[0], args)
+ os.close(wfd)
+ os.read(rfd, 1)
+ if parentfn:
+ return parentfn(pid)
+ else:
+ os._exit(0)
+
+ if initfn:
+ initfn()
+
+ if opts['pid_file']:
+ fp = open(opts['pid_file'], 'w')
+ fp.write(str(os.getpid()) + '\n')
+ fp.close()
+
+ if opts['daemon_pipefds']:
+ rfd, wfd = [int(x) for x in opts['daemon_pipefds'].split(',')]
+ os.close(rfd)
+ try:
+ os.setsid()
+ except AttributeError:
+ pass
+ os.write(wfd, 'y')
+ os.close(wfd)
+ sys.stdout.flush()
+ sys.stderr.flush()
+ fd = os.open(util.nulldev, os.O_RDWR)
+ if fd != 0: os.dup2(fd, 0)
+ if fd != 1: os.dup2(fd, 1)
+ if fd != 2: os.dup2(fd, 2)
+ if fd not in (0, 1, 2): os.close(fd)
+
+ if runfn:
+ return runfn()
+
class changeset_printer(object):
'''show changeset information when templating not requested.'''
--- a/mercurial/commands.py Wed Apr 25 13:14:01 2007 -0700
+++ b/mercurial/commands.py Fri Apr 27 21:30:55 2007 -0700
@@ -2375,44 +2375,27 @@
raise hg.RepoError(_("There is no Mercurial repository here"
" (.hg not found)"))
- if opts['daemon'] and not opts['daemon_pipefds']:
- rfd, wfd = os.pipe()
- args = sys.argv[:]
- args.append('--daemon-pipefds=%d,%d' % (rfd, wfd))
- pid = os.spawnvp(os.P_NOWAIT | getattr(os, 'P_DETACH', 0),
- args[0], args)
- os.close(wfd)
- os.read(rfd, 1)
- os._exit(0)
-
- httpd = hgweb.server.create_server(parentui, repo)
-
- if ui.verbose:
- if httpd.port != 80:
- ui.status(_('listening at http://%s:%d/\n') %
- (httpd.addr, httpd.port))
- else:
- ui.status(_('listening at http://%s/\n') % httpd.addr)
-
- if opts['pid_file']:
- fp = open(opts['pid_file'], 'w')
- fp.write(str(os.getpid()) + '\n')
- fp.close()
-
- if opts['daemon_pipefds']:
- rfd, wfd = [int(x) for x in opts['daemon_pipefds'].split(',')]
- os.close(rfd)
- os.write(wfd, 'y')
- os.close(wfd)
- sys.stdout.flush()
- sys.stderr.flush()
- fd = os.open(util.nulldev, os.O_RDWR)
- if fd != 0: os.dup2(fd, 0)
- if fd != 1: os.dup2(fd, 1)
- if fd != 2: os.dup2(fd, 2)
- if fd not in (0, 1, 2): os.close(fd)
-
- httpd.serve_forever()
+ class service:
+ def init(self):
+ try:
+ self.httpd = hgweb.server.create_server(parentui, repo)
+ except socket.error, inst:
+ raise util.Abort(_('cannot start server: ') + inst.args[1])
+
+ if not ui.verbose: return
+
+ if httpd.port != 80:
+ ui.status(_('listening at http://%s:%d/\n') %
+ (httpd.addr, httpd.port))
+ else:
+ ui.status(_('listening at http://%s/\n') % httpd.addr)
+
+ def run(self):
+ self.httpd.serve_forever()
+
+ service = service()
+
+ cmdutil.service(opts, initfn=service.init, runfn=service.run)
def status(ui, repo, *pats, **opts):
"""show changed files in the working directory