"Fossies" - the Fresh Open Source Software Archive

Member "nss-pam-ldapd-0.9.12/pynslcd/mypidfile.py" (15 Nov 2021, 2801 Bytes) of package /linux/privat/nss-pam-ldapd-0.9.12.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. For more information about "mypidfile.py" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 0.9.11_vs_0.9.12.

    1 
    2 # mypidfile.py - functions for properly locking a PIDFile
    3 #
    4 # Copyright (C) 2010-2021 Arthur de Jong
    5 #
    6 # This library is free software; you can redistribute it and/or
    7 # modify it under the terms of the GNU Lesser General Public
    8 # License as published by the Free Software Foundation; either
    9 # version 2.1 of the License, or (at your option) any later version.
   10 #
   11 # This library is distributed in the hope that it will be useful,
   12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
   13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   14 # Lesser General Public License for more details.
   15 #
   16 # You should have received a copy of the GNU Lesser General Public
   17 # License along with this library; if not, write to the Free Software
   18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
   19 # 02110-1301 USA
   20 
   21 import errno
   22 import fcntl
   23 import os
   24 
   25 import cfg
   26 
   27 
   28 class MyPIDLockFile(object):
   29     """A PIDFile for use with the daemon module.
   30 
   31     This class that locks the PIDFile with fcntl.lockf().
   32     """
   33 
   34     def __init__(self, path):
   35         self.path = path
   36 
   37     def __enter__(self):
   38         """Lock the PID file and write the process ID to the file."""
   39         # create the directory for the pidfile if needed
   40         piddir = os.path.dirname(self.path)
   41         if not os.path.isdir(piddir):
   42             os.mkdir(piddir)
   43             if cfg.uid is not None:
   44                 u, gid = cfg.get_usergid()
   45                 os.chown(piddir, u.u.pw_uid, gid)
   46         fd = os.open(self.path, os.O_RDWR | os.O_CREAT, 0o644)
   47         try:
   48             fcntl.lockf(fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
   49             pidfile = os.fdopen(fd, 'w')
   50         except Exception:
   51             os.close(fd)
   52             raise
   53         pidfile.write('%d\n' % os.getpid())
   54         pidfile.truncate()
   55         pidfile.flush()
   56         self.pidfile = pidfile
   57         return self
   58 
   59     def __exit__(self, exc_type, exc_value, traceback):
   60         """Release the lock (close the lockfile)."""
   61         fcntl.lockf(self.pidfile.fileno(), fcntl.LOCK_UN)
   62         self.pidfile.close()
   63         del self.pidfile
   64 
   65     def is_locked(self):
   66         """Check whether the file is already present and locked."""
   67         try:
   68             fd = os.open(self.path, os.O_RDWR, 0o644)
   69             # Python doesn't seem to have F_TEST so we'll just try to lock
   70             fcntl.lockf(fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
   71             # if we're here we must have aquired the lock
   72             fcntl.lockf(fd, fcntl.LOCK_UN)
   73             return False
   74         except (IOError, OSError) as e:
   75             if e.errno == errno.ENOENT:
   76                 return False
   77             if e.errno in (errno.EACCES, errno.EAGAIN):
   78                 return True
   79             raise
   80         finally:
   81             if 'fd' in locals():
   82                 os.close(fd)