| Index: third_party/logilab/common/daemon.py
|
| diff --git a/third_party/logilab/common/daemon.py b/third_party/logilab/common/daemon.py
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..c8342a85306841e181066991eb0ff4bfca4642d0
|
| --- /dev/null
|
| +++ b/third_party/logilab/common/daemon.py
|
| @@ -0,0 +1,100 @@
|
| +# 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.putenv('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
|
|
|