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 -def setugid(user):
30 """Change process user and group ID 31 32 Argument is a numeric user id or a user name""" 33 try: 34 from pwd import getpwuid 35 passwd = getpwuid(int(user)) 36 except ValueError: 37 from pwd import getpwnam 38 passwd = getpwnam(user) 39 40 if hasattr(os, 'initgroups'): # python >= 2.7 41 os.initgroups(passwd.pw_name, passwd.pw_gid) 42 else: 43 import ctypes 44 if ctypes.CDLL(None).initgroups(passwd.pw_name, passwd.pw_gid) < 0: 45 err = ctypes.c_int.in_dll(ctypes.pythonapi,"errno").value 46 raise OSError(err, os.strerror(err), 'initgroups') 47 os.setgid(passwd.pw_gid) 48 os.setuid(passwd.pw_uid) 49 os.putenv('HOME', passwd.pw_dir)
50 51
52 -def daemonize(pidfile=None, uid=None, umask=077):
53 """daemonize a Unix process. Set paranoid umask by default. 54 55 Return 1 in the original process, 2 in the first fork, and None for the 56 second fork (eg daemon process). 57 """ 58 # http://www.faqs.org/faqs/unix-faq/programmer/faq/ 59 # 60 # fork so the parent can exit 61 if os.fork(): # launch child and... 62 return 1 63 # disconnect from tty and create a new session 64 os.setsid() 65 # fork again so the parent, (the session group leader), can exit. 66 # as a non-session group leader, we can never regain a controlling 67 # terminal. 68 if os.fork(): # launch child again. 69 return 2 70 # move to the root to avoit mount pb 71 os.chdir('/') 72 # set umask if specified 73 if umask is not None: 74 os.umask(umask) 75 # redirect standard descriptors 76 null = os.open('/dev/null', os.O_RDWR) 77 for i in range(3): 78 try: 79 os.dup2(null, i) 80 except OSError, e: 81 if e.errno != errno.EBADF: 82 raise 83 os.close(null) 84 # filter warnings 85 warnings.filterwarnings('ignore') 86 # write pid in a file 87 if pidfile: 88 # ensure the directory where the pid-file should be set exists (for 89 # instance /var/run/cubicweb may be deleted on computer restart) 90 piddir = os.path.dirname(pidfile) 91 if not os.path.exists(piddir): 92 os.makedirs(piddir) 93 f = file(pidfile, 'w') 94 f.write(str(os.getpid())) 95 f.close() 96 os.chmod(pidfile, 0644) 97 # change process uid 98 if uid: 99 setugid(uid) 100 return None
101