mercurial/cmdutil.py
changeset 10238 e22695b4472f
parent 10237 2f7a38f336f4
child 10239 8e4be44a676f
equal deleted inserted replaced
10237:2f7a38f336f4 10238:e22695b4472f
     5 # This software may be used and distributed according to the terms of the
     5 # This software may be used and distributed according to the terms of the
     6 # GNU General Public License version 2, incorporated herein by reference.
     6 # GNU General Public License version 2, incorporated herein by reference.
     7 
     7 
     8 from node import hex, nullid, nullrev, short
     8 from node import hex, nullid, nullrev, short
     9 from i18n import _
     9 from i18n import _
    10 import os, sys, errno, re, glob
    10 import os, sys, errno, re, glob, tempfile, time
    11 import mdiff, bdiff, util, templater, patch, error, encoding, templatekw
    11 import mdiff, bdiff, util, templater, patch, error, encoding, templatekw
    12 import match as _match
    12 import match as _match
    13 
    13 
    14 revrangesep = ':'
    14 revrangesep = ':'
    15 
    15 
   565 def service(opts, parentfn=None, initfn=None, runfn=None, logfile=None,
   565 def service(opts, parentfn=None, initfn=None, runfn=None, logfile=None,
   566     runargs=None, appendpid=False):
   566     runargs=None, appendpid=False):
   567     '''Run a command as a service.'''
   567     '''Run a command as a service.'''
   568 
   568 
   569     if opts['daemon'] and not opts['daemon_pipefds']:
   569     if opts['daemon'] and not opts['daemon_pipefds']:
   570         rfd, wfd = os.pipe()
   570         # Signal child process startup with file removal
   571         if not runargs:
   571         lockfd, lockpath = tempfile.mkstemp(prefix='hg-service-')
   572             runargs = sys.argv[:]
   572         os.close(lockfd)        
   573         runargs.append('--daemon-pipefds=%d,%d' % (rfd, wfd))
   573         try:
   574         # Don't pass --cwd to the child process, because we've already
   574             if not runargs:
   575         # changed directory.
   575                 runargs = sys.argv[:]
   576         for i in xrange(1,len(runargs)):
   576             runargs.append('--daemon-pipefds=%s' % lockpath)
   577             if runargs[i].startswith('--cwd='):
   577             # Don't pass --cwd to the child process, because we've already
   578                 del runargs[i]
   578             # changed directory.
   579                 break
   579             for i in xrange(1,len(runargs)):
   580             elif runargs[i].startswith('--cwd'):
   580                 if runargs[i].startswith('--cwd='):
   581                 del runargs[i:i+2]
   581                     del runargs[i]
   582                 break
   582                     break
   583         pid = util.spawndetached(runargs)
   583                 elif runargs[i].startswith('--cwd'):
   584         os.close(wfd)
   584                     del runargs[i:i+2]
   585         os.read(rfd, 1)
   585                     break
       
   586             pid = util.spawndetached(runargs)  
       
   587             while os.path.exists(lockpath):
       
   588                 time.sleep(0.1)
       
   589         finally:
       
   590             try:
       
   591                 os.unlink(lockpath)
       
   592             except OSError, e:
       
   593                 if e.errno != errno.ENOENT:
       
   594                     raise
   586         if parentfn:
   595         if parentfn:
   587             return parentfn(pid)
   596             return parentfn(pid)
   588         else:
   597         else:
   589             return
   598             return
   590 
   599 
   596         fp = open(opts['pid_file'], mode)
   605         fp = open(opts['pid_file'], mode)
   597         fp.write(str(os.getpid()) + '\n')
   606         fp.write(str(os.getpid()) + '\n')
   598         fp.close()
   607         fp.close()
   599 
   608 
   600     if opts['daemon_pipefds']:
   609     if opts['daemon_pipefds']:
   601         rfd, wfd = [int(x) for x in opts['daemon_pipefds'].split(',')]
   610         lockpath = opts['daemon_pipefds']
   602         os.close(rfd)
       
   603         try:
   611         try:
   604             os.setsid()
   612             os.setsid()
   605         except AttributeError:
   613         except AttributeError:
   606             pass
   614             pass
   607         os.write(wfd, 'y')
   615         os.unlink(lockpath)
   608         os.close(wfd)
       
   609         sys.stdout.flush()
   616         sys.stdout.flush()
   610         sys.stderr.flush()
   617         sys.stderr.flush()
   611 
   618 
   612         nullfd = os.open(util.nulldev, os.O_RDWR)
   619         nullfd = os.open(util.nulldev, os.O_RDWR)
   613         logfilefd = nullfd
   620         logfilefd = nullfd