| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 |
- # copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
- # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
- #
- # This file is part of logilab-common.
- #
- # logilab-common is free software: you can redistribute it and/or modify it under
- # the terms of the GNU Lesser General Public License as published by the Free
- # Software Foundation, either version 2.1 of the License, or (at your option) any
- # later version.
- #
- # logilab-common is distributed in the hope that it will be useful, but WITHOUT
- # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- # details.
- #
- # You should have received a copy of the GNU Lesser General Public License along
- # with logilab-common. If not, see <http://www.gnu.org/licenses/>.
- """A daemonize function (for Unices)"""
- __docformat__ = "restructuredtext en"
- import os
- import errno
- import signal
- import sys
- import time
- import warnings
- def setugid(user):
- """Change process user and group ID
- Argument is a numeric user id or a user name"""
- try:
- from pwd import getpwuid
- passwd = getpwuid(int(user))
- except ValueError:
- from pwd import getpwnam
- passwd = getpwnam(user)
- if hasattr(os, 'initgroups'): # python >= 2.7
- os.initgroups(passwd.pw_name, passwd.pw_gid)
- else:
- import ctypes
- if ctypes.CDLL(None).initgroups(passwd.pw_name, passwd.pw_gid) < 0:
- err = ctypes.c_int.in_dll(ctypes.pythonapi,"errno").value
- raise OSError(err, os.strerror(err), 'initgroups')
- os.setgid(passwd.pw_gid)
- os.setuid(passwd.pw_uid)
- os.environ['HOME'] = passwd.pw_dir
- def daemonize(pidfile=None, uid=None, umask=077):
- """daemonize a Unix process. Set paranoid umask by default.
- Return 1 in the original process, 2 in the first fork, and None for the
- second fork (eg daemon process).
- """
- # http://www.faqs.org/faqs/unix-faq/programmer/faq/
- #
- # fork so the parent can exit
- if os.fork(): # launch child and...
- return 1
- # disconnect from tty and create a new session
- os.setsid()
- # fork again so the parent, (the session group leader), can exit.
- # as a non-session group leader, we can never regain a controlling
- # terminal.
- if os.fork(): # launch child again.
- return 2
- # move to the root to avoit mount pb
- os.chdir('/')
- # set umask if specified
- if umask is not None:
- os.umask(umask)
- # redirect standard descriptors
- null = os.open('/dev/null', os.O_RDWR)
- for i in range(3):
- try:
- os.dup2(null, i)
- except OSError, e:
- if e.errno != errno.EBADF:
- raise
- os.close(null)
- # filter warnings
- warnings.filterwarnings('ignore')
- # write pid in a file
- if pidfile:
- # ensure the directory where the pid-file should be set exists (for
- # instance /var/run/cubicweb may be deleted on computer restart)
- piddir = os.path.dirname(pidfile)
- if not os.path.exists(piddir):
- os.makedirs(piddir)
- f = file(pidfile, 'w')
- f.write(str(os.getpid()))
- f.close()
- os.chmod(pidfile, 0644)
- # change process uid
- if uid:
- setugid(uid)
- return None
|