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 |