\ 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.
| 8 | |
| 9 | |
| 10 | class Pidfile: |
| 11 | """\ |
| 12 | Manage a PID file. If a specific name is provided |
| 13 | it and '"%s.oldpid" % name' will be used. Otherwise |
| 14 | we create a temp file using os.mkstemp. |
| 15 | """ |
| 16 | |
| 17 | def __init__(self, fname): |
| 18 | self.fname = fname |
| 19 | self.pid = None |
| 20 | |
| 21 | def create(self, pid): |
| 22 | oldpid = self.validate() |
| 23 | if oldpid: |
| 24 | if oldpid == os.getpid(): |
| 25 | return |
| 26 | msg = "Already running on PID %s (or pid file '%s' is stale)" |
| 27 | raise RuntimeError(msg % (oldpid, self.fname)) |
| 28 | |
| 29 | self.pid = pid |
| 30 | |
| 31 | # Write pidfile |
| 32 | fdir = os.path.dirname(self.fname) |
| 33 | if fdir and not os.path.isdir(fdir): |
| 34 | raise RuntimeError("%s doesn't exist. Can't create pidfile." % fdir) |
| 35 | fd, fname = tempfile.mkstemp(dir=fdir) |
| 36 | try: |
| 37 | os.write(fd, ("%s\n" % self.pid).encode('utf-8')) |
| 38 | if self.fname: |
| 39 | os.rename(fname, self.fname) |
| 40 | else: |
| 41 | self.fname = fname |
| 42 | finally: |
| 43 | os.close(fd) |
| 44 | |
| 45 | # set permissions to -rw-r--r-- |
| 46 | os.chmod(self.fname, 420) |
| 47 | |
| 48 | def rename(self, path): |
| 49 | self.unlink() |
| 50 | self.fname = path |
| 51 | self.create(self.pid) |
| 52 | |
| 53 | def unlink(self): |
| 54 | """ delete pidfile""" |
| 55 | try: |
| 56 | with open(self.fname) as f: |
| 57 | pid1 = int(f.read() or 0) |
| 58 | |
| 59 | if pid1 == self.pid: |
| 60 | os.unlink(self.fname) |
| 61 | except Exception: |
| 62 | pass |
| 63 | |
| 64 | def validate(self): |
| 65 | """ Validate pidfile and make it stale if needed""" |
| 66 | if not self.fname: |
| 67 | return |