You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
			
				
					87 lines
				
				2.3 KiB
			
		
		
			
		
	
	
					87 lines
				
				2.3 KiB
			| 
								 
											8 years ago
										 
									 | 
							
								# -*- coding: utf-8 -
							 | 
						||
| 
								 | 
							
								#
							 | 
						||
| 
								 | 
							
								# This file is part of gunicorn released under the MIT license.
							 | 
						||
| 
								 | 
							
								# See the NOTICE for more information.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import errno
							 | 
						||
| 
								 | 
							
								import os
							 | 
						||
| 
								 | 
							
								import tempfile
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								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
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def create(self, pid):
							 | 
						||
| 
								 | 
							
								        oldpid = self.validate()
							 | 
						||
| 
								 | 
							
								        if oldpid:
							 | 
						||
| 
								 | 
							
								            if oldpid == os.getpid():
							 | 
						||
| 
								 | 
							
								                return
							 | 
						||
| 
								 | 
							
								            msg = "Already running on PID %s (or pid file '%s' is stale)"
							 | 
						||
| 
								 | 
							
								            raise RuntimeError(msg % (oldpid, 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)
							 | 
						||
| 
								 | 
							
								        os.write(fd, ("%s\n" % self.pid).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)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def rename(self, path):
							 | 
						||
| 
								 | 
							
								        self.unlink()
							 | 
						||
| 
								 | 
							
								        self.fname = path
							 | 
						||
| 
								 | 
							
								        self.create(self.pid)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def unlink(self):
							 | 
						||
| 
								 | 
							
								        """ delete pidfile"""
							 | 
						||
| 
								 | 
							
								        try:
							 | 
						||
| 
								 | 
							
								            with open(self.fname, "r") as f:
							 | 
						||
| 
								 | 
							
								                pid1 = int(f.read() or 0)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if pid1 == self.pid:
							 | 
						||
| 
								 | 
							
								                os.unlink(self.fname)
							 | 
						||
| 
								 | 
							
								        except:
							 | 
						||
| 
								 | 
							
								            pass
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def validate(self):
							 | 
						||
| 
								 | 
							
								        """ Validate pidfile and make it stale if needed"""
							 | 
						||
| 
								 | 
							
								        if not self.fname:
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								        try:
							 | 
						||
| 
								 | 
							
								            with open(self.fname, "r") as f:
							 | 
						||
| 
								 | 
							
								                try:
							 | 
						||
| 
								 | 
							
								                    wpid = int(f.read())
							 | 
						||
| 
								 | 
							
								                except ValueError:
							 | 
						||
| 
								 | 
							
								                    return
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                try:
							 | 
						||
| 
								 | 
							
								                    os.kill(wpid, 0)
							 | 
						||
| 
								 | 
							
								                    return wpid
							 | 
						||
| 
								 | 
							
								                except OSError as e:
							 | 
						||
| 
								 | 
							
								                    if e.args[0] == errno.EPERM:
							 | 
						||
| 
								 | 
							
								                        return wpid
							 | 
						||
| 
								 | 
							
								                    if e.args[0] == errno.ESRCH:
							 | 
						||
| 
								 | 
							
								                        return
							 | 
						||
| 
								 | 
							
								                    raise
							 | 
						||
| 
								 | 
							
								        except IOError as e:
							 | 
						||
| 
								 | 
							
								            if e.args[0] == errno.ENOENT:
							 | 
						||
| 
								 | 
							
								                return
							 | 
						||
| 
								 | 
							
								            raise
							 |