summaryrefslogtreecommitdiff
path: root/pynslcd/mypidfile.py
diff options
context:
space:
mode:
authorArthur de Jong <arthur@arthurdejong.org>2010-12-29 22:50:31 +0000
committerArthur de Jong <arthur@arthurdejong.org>2010-12-29 22:50:31 +0000
commite985efa83458e1cc9c2bcb12e3cc10b6526c3399 (patch)
tree8311cb525c9d452d62d88280e6cca854496f9c42 /pynslcd/mypidfile.py
parent4e9224817ee303404b804a1a51f2f9c9a49164e4 (diff)
parented6bc27721075adf0215ad8b856fcdcf7b98b9b7 (diff)
merge changes from trunk
git-svn-id: http://arthurdejong.org/svn/nss-pam-ldapd/nss-pam-ldapd-solaris@1349 ef36b2f9-881f-0410-afb5-c4e39611909c
Diffstat (limited to 'pynslcd/mypidfile.py')
-rw-r--r--pynslcd/mypidfile.py70
1 files changed, 70 insertions, 0 deletions
diff --git a/pynslcd/mypidfile.py b/pynslcd/mypidfile.py
new file mode 100644
index 0000000..4781089
--- /dev/null
+++ b/pynslcd/mypidfile.py
@@ -0,0 +1,70 @@
+
+# mypidfile.py - functions for properly locking a PIDFile
+#
+# Copyright (C) 2010 Arthur de Jong
+#
+# This library 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.
+#
+# This library 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 this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 USA
+
+import fcntl
+import errno
+import os
+
+
+class MyPIDLockFile(object):
+ """Implementation of a PIDFile fit for use with the daemon module
+ that locks the PIDFile with fcntl.lockf()."""
+
+ def __init__(self, path):
+ self.path = path
+
+ def __enter__(self):
+ """Lock the PID file and write the process ID to the file."""
+ fd = os.open(self.path, os.O_RDWR | os.O_CREAT, 0644)
+ try:
+ fcntl.lockf(fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
+ pidfile = os.fdopen(fd, 'w')
+ except:
+ os.close(fd)
+ raise
+ pidfile.write('%d\n' % os.getpid())
+ pidfile.flush()
+ self.pidfile = pidfile
+ return self
+
+ def __exit__(self, exc_type, exc_value, traceback):
+ """Release the lock (close the lockfile)."""
+ fcntl.lockf(self.pidfile.fileno(), fcntl.LOCK_UN)
+ self.pidfile.close()
+ del self.pidfile
+
+ def is_locked(self):
+ """Check whether the file is already present and locked."""
+ try:
+ fd = os.open(self.path, os.O_RDWR, 0644)
+ # Python doesn't seem to have F_TEST so we'll just try to lock
+ fcntl.lockf(fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
+ # if we're here we must have aquired the lock
+ fcntl.lockf(fd, fcntl.LOCK_UN)
+ return False
+ except (IOError, OSError), e:
+ if e.errno == errno.ENOENT:
+ return False
+ if e.errno in (errno.EACCES, errno.EAGAIN):
+ return True
+ raise
+ finally:
+ if 'fd' in locals():
+ os.close(fd)