"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.

    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)