Package logilab :: Package common :: Module daemon
[frames] | no frames]

Source Code for Module logilab.common.daemon

  1  # copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved. 
  2  # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr 
  3  # 
  4  # This file is part of logilab-common. 
  5  # 
  6  # logilab-common is free software: you can redistribute it and/or modify it under 
  7  # the terms of the GNU Lesser General Public License as published by the Free 
  8  # Software Foundation, either version 2.1 of the License, or (at your option) any 
  9  # later version. 
 10  # 
 11  # logilab-common is distributed in the hope that it will be useful, but WITHOUT 
 12  # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
 13  # FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more 
 14  # details. 
 15  # 
 16  # You should have received a copy of the GNU Lesser General Public License along 
 17  # with logilab-common.  If not, see <http://www.gnu.org/licenses/>. 
 18  """A daemonize function (for Unices)""" 
 19   
 20  __docformat__ = "restructuredtext en" 
 21   
 22  import os 
 23  import errno 
 24  import signal 
 25  import sys 
 26  import time 
 27  import warnings 
 28   
 29  from six.moves import range 
 30   
31 -def setugid(user):
32 """Change process user and group ID 33 34 Argument is a numeric user id or a user name""" 35 try: 36 from pwd import getpwuid 37 passwd = getpwuid(int(user)) 38 except ValueError: 39 from pwd import getpwnam 40 passwd = getpwnam(user) 41 42 if hasattr(os, 'initgroups'): # python >= 2.7 43 os.initgroups(passwd.pw_name, passwd.pw_gid) 44 else: 45 import ctypes 46 if ctypes.CDLL(None).initgroups(passwd.pw_name, passwd.pw_gid) < 0: 47 err = ctypes.c_int.in_dll(ctypes.pythonapi,"errno").value 48 raise OSError(err, os.strerror(err), 'initgroups') 49 os.setgid(passwd.pw_gid) 50 os.setuid(passwd.pw_uid) 51 os.environ['HOME'] = passwd.pw_dir
52 53
54 -def daemonize(pidfile=None, uid=None, umask=0o77):
55 """daemonize a Unix process. Set paranoid umask by default. 56 57 Return 1 in the original process, 2 in the first fork, and None for the 58 second fork (eg daemon process). 59 """ 60 # http://www.faqs.org/faqs/unix-faq/programmer/faq/ 61 # 62 # fork so the parent can exit 63 if os.fork(): # launch child and... 64 return 1 65 # disconnect from tty and create a new session 66 os.setsid() 67 # fork again so the parent, (the session group leader), can exit. 68 # as a non-session group leader, we can never regain a controlling 69 # terminal. 70 if os.fork(): # launch child again. 71 return 2 72 # move to the root to avoit mount pb 73 os.chdir('/') 74 # redirect standard descriptors 75 null = os.open('/dev/null', os.O_RDWR) 76 for i in range(3): 77 try: 78 os.dup2(null, i) 79 except OSError as e: 80 if e.errno != errno.EBADF: 81 raise 82 os.close(null) 83 # filter warnings 84 warnings.filterwarnings('ignore') 85 # write pid in a file 86 if pidfile: 87 # ensure the directory where the pid-file should be set exists (for 88 # instance /var/run/cubicweb may be deleted on computer restart) 89 piddir = os.path.dirname(pidfile) 90 if not os.path.exists(piddir): 91 os.makedirs(piddir) 92 f = file(pidfile, 'w') 93 f.write(str(os.getpid())) 94 f.close() 95 # set umask if specified 96 if umask is not None: 97 os.umask(umask) 98 # change process uid 99 if uid: 100 setugid(uid) 101 return None
102