Source code for gaffer.pidfile

# -*- coding: utf-8 -
#
# This file is part of gaffer. See the NOTICE for more information.

import errno
import os
import tempfile


[docs]class Pidfile(object): """ Manage a PID file. If a specific name is provided it and '"%s.oldpid" % name' will be used. Otherwise we create a temp file using os.mkstemp. """ def __init__(self, fname): self.fname = fname self.pid = None
[docs] def create(self, pid): oldpid = self.validate() if oldpid: if oldpid == os.getpid(): return raise RuntimeError("Already running on PID %s " \ "(or pid file '%s' is stale)" % (os.getpid(), self.fname)) self.pid = pid # Write pidfile fdir = os.path.dirname(self.fname) if fdir and not os.path.isdir(fdir): raise RuntimeError("%s doesn't exist. Can't create pidfile." \ % fdir) fd, fname = tempfile.mkstemp(dir=fdir) pid_str = "%s\n" % self.pid os.write(fd, pid_str.encode('utf-8')) if self.fname: os.rename(fname, self.fname) else: self.fname = fname os.close(fd) # set permissions to -rw-r--r-- os.chmod(self.fname, 420)
[docs] def rename(self, path): self.unlink() self.fname = path self.create(self.pid)
[docs] def validate(self): """ Validate pidfile and make it stale if needed""" if not self.fname: return try: with open(self.fname, "r") as f: wpid = int(f.read() or 0) if wpid <= 0: return try: os.kill(wpid, 0) return wpid except OSError as e: if e.args[0] == errno.ESRCH: return raise except IOError as e: if e.args[0] == errno.ENOENT: return raise