hgext/inotify/server.py
changeset 9514 7c01599dd340
parent 9351 206f7f4c5c2a
child 9854 95e1867f765b
equal deleted inserted replaced
9513:ae88c721f916 9514:7c01599dd340
     5 #
     5 #
     6 # This software may be used and distributed according to the terms of the
     6 # This software may be used and distributed according to the terms of the
     7 # GNU General Public License version 2, incorporated herein by reference.
     7 # GNU General Public License version 2, incorporated herein by reference.
     8 
     8 
     9 from mercurial.i18n import _
     9 from mercurial.i18n import _
    10 from mercurial import osutil, util
    10 from mercurial import cmdutil, osutil, util
    11 import common
    11 import common
    12 import errno, os, select, socket, stat, struct, sys, tempfile, time
    12 import errno, os, select, socket, stat, struct, sys, tempfile, time
    13 
    13 
    14 try:
    14 try:
    15     import linux as inotify
    15     import linux as inotify
   821         self.ui.note(_('finished setup\n'))
   821         self.ui.note(_('finished setup\n'))
   822         if os.getenv('TIME_STARTUP'):
   822         if os.getenv('TIME_STARTUP'):
   823             sys.exit(0)
   823             sys.exit(0)
   824         pollable.run()
   824         pollable.run()
   825 
   825 
   826 def start(ui, dirstate, root):
   826 def start(ui, dirstate, root, opts):
   827     def closefds(ignore):
   827     timeout = opts.get('timeout')
   828         # (from python bug #1177468)
   828     if timeout:
   829         # close all inherited file descriptors
   829         timeout = float(timeout) * 1e3
   830         # Python 2.4.1 and later use /dev/urandom to seed the random module's RNG
   830 
   831         # a file descriptor is kept internally as os._urandomfd (created on demand
   831     class service(object):
   832         # the first time os.urandom() is called), and should not be closed
   832         def init(self):
   833         try:
   833             try:
   834             os.urandom(4)
   834                 self.master = master(ui, dirstate, root, timeout)
   835             urandom_fd = getattr(os, '_urandomfd', None)
   835             except AlreadyStartedException, inst:
   836         except AttributeError:
   836                 raise util.Abort(str(inst))
   837             urandom_fd = None
   837 
   838         ignore.append(urandom_fd)
   838         def run(self):
   839         for fd in range(3, 256):
   839             try:
   840             if fd in ignore:
   840                 self.master.run()
   841                 continue
   841             finally:
   842             try:
   842                 self.master.shutdown()
   843                 os.close(fd)
   843 
   844             except OSError:
   844     runargs = None
   845                 pass
   845     if 'inserve' not in sys.argv:
   846 
   846         runargs = [sys.argv[0], 'inserve', '-R', root]
   847     m = master(ui, dirstate, root)
   847 
   848     sys.stdout.flush()
   848     service = service()
   849     sys.stderr.flush()
   849     logfile = ui.config('inotify', 'log')
   850 
   850     cmdutil.service(opts, initfn=service.init, runfn=service.run,
   851     pid = os.fork()
   851                     logfile=logfile, runargs=runargs)
   852     if pid:
       
   853         return pid
       
   854 
       
   855     closefds(pollable.instances.keys())
       
   856     os.setsid()
       
   857 
       
   858     fd = os.open('/dev/null', os.O_RDONLY)
       
   859     os.dup2(fd, 0)
       
   860     if fd > 0:
       
   861         os.close(fd)
       
   862 
       
   863     fd = os.open(ui.config('inotify', 'log', '/dev/null'),
       
   864                  os.O_RDWR | os.O_CREAT | os.O_TRUNC)
       
   865     os.dup2(fd, 1)
       
   866     os.dup2(fd, 2)
       
   867     if fd > 2:
       
   868         os.close(fd)
       
   869 
       
   870     try:
       
   871         m.run()
       
   872     finally:
       
   873         m.shutdown()
       
   874         os._exit(0)