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.
		
		
		
		
		
			
		
			
				
					
					
						
							86 lines
						
					
					
						
							2.3 KiB
						
					
					
				
			
		
		
	
	
							86 lines
						
					
					
						
							2.3 KiB
						
					
					
				| # -*- 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
 | |
| 
 |