prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  gunicorn.pidfile.validate crashes gunicorn when PID exists but is from a different user
  ```
  Traceback (most recent call last):
    File "/opt/python2.7/bin/gunicorn", line 11, in <module>
      sys.exit(run())
    File "/opt/python2.7/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 74, in run
      WSGIApplication("%(prog)s [OPTIONS] [APP_MODULE]").run()
    File "/opt/python2.7/lib/python2.7/site-packages/gunicorn/app/base.py", line 189, in run
      super(Application, self).run()
    File "/opt/python2.7/lib/python2.7/site-packages/gunicorn/app/base.py", line 72, in run
      Arbiter(self).run()
    File "/opt/python2.7/lib/python2.7/site-packages/gunicorn/arbiter.py", line 171, in run
      self.start()
    File "/opt/python2.7/lib/python2.7/site-packages/gunicorn/arbiter.py", line 125, in start
      self.pidfile.create(self.pid)
    File "/opt/python2.7/lib/python2.7/site-packages/gunicorn/pidfile.py", line 23, in create
      oldpid = self.validate()
    File "/opt/python2.7/lib/python2.7/site-packages/gunicorn/pidfile.py", line 75, in validate
      os.kill(wpid, 0)
  OSError: [Errno 1] Operation not permitted
  ```
  
  This happens because the process identified by the pid-file exists, but belongs to a different user than the one starting gunicorn.
  
  (This is with gunicorn 19.3.0)
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `gunicorn/pidfile.py`
  Content:
  ```
  1 # -*- coding: utf-8 -
  2 #
  3 # This file is part of gunicorn released under the MIT license.
  4 # See the NOTICE for more information.
  5 
  6 import errno
  7 import os
  8 import tempfile
  9 
  10 
  11 class Pidfile(object):
  12     """\
  13     Manage a PID file. If a specific name is provided
  14     it and '"%s.oldpid" % name' will be used. Otherwise
  15     we create a temp file using os.mkstemp.
  16     """
  17 
  18     def __init__(self, fname):
  19         self.fname = fname
  20         self.pid = None
  21 
  22     def create(self, pid):
  23         oldpid = self.validate()
  24         if oldpid:
  25             if oldpid == os.getpid():
  26                 return
  27             msg = "Already running on PID %s (or pid file '%s' is stale)"
  28             raise RuntimeError(msg % (oldpid, self.fname))
  29 
  30         self.pid = pid
  31 
  32         # Write pidfile
  33         fdir = os.path.dirname(self.fname)
  34         if fdir and not os.path.isdir(fdir):
  35             raise RuntimeError("%s doesn't exist. Can't create pidfile." % fdir)
  36         fd, fname = tempfile.mkstemp(dir=fdir)
  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         os.close(fd)
  43 
  44         # set permissions to -rw-r--r--
  45         os.chmod(self.fname, 420)
  46 
  47     def rename(self, path):
  48         self.unlink()
  49         self.fname = path
  50         self.create(self.pid)
  51 
  52     def unlink(self):
  53         """ delete pidfile"""
  54         try:
  55             with open(self.fname, "r") as f:
  56                 pid1 = int(f.read() or 0)
  57 
  58             if pid1 == self.pid:
  59                 os.unlink(self.fname)
  60         except:
  61             pass
  62 
  63     def validate(self):
  64         """ Validate pidfile and make it stale if needed"""
  65         if not self.fname:
  66             return
  67         try:
  68             with open(self.fname, "r") as f:
  69                 try:
  70                     wpid = int(f.read())
  71                 except ValueError:
  72                     return
  73 
  74                 try:
  75                     os.kill(wpid, 0)
  76                     return wpid
  77                 except OSError as e:
  78                     if e.args[0] == errno.ESRCH:
  79                         return
  80                     raise
  81         except IOError as e:
  82             if e.args[0] == errno.ENOENT:
  83                 return
  84             raise
  85
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/gunicorn/pidfile.py b/gunicorn/pidfile.py
  --- a/gunicorn/pidfile.py
  +++ b/gunicorn/pidfile.py
  @@ -75,6 +75,8 @@
                       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
  
verification_info: {"golden_diff": "diff --git a/gunicorn/pidfile.py b/gunicorn/pidfile.py\n--- a/gunicorn/pidfile.py\n+++ b/gunicorn/pidfile.py\n@@ -75,6 +75,8 @@\n                     os.kill(wpid, 0)\n                     return wpid\n                 except OSError as e:\n+                    if e.args[0] == errno.EPERM:\n+                        return wpid\n                     if e.args[0] == errno.ESRCH:\n                         return\n                     raise\n", "issue": "gunicorn.pidfile.validate crashes gunicorn when PID exists but is from a different user\n```\nTraceback (most recent call last):\n  File \"/opt/python2.7/bin/gunicorn\", line 11, in <module>\n    sys.exit(run())\n  File \"/opt/python2.7/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py\", line 74, in run\n    WSGIApplication(\"%(prog)s [OPTIONS] [APP_MODULE]\").run()\n  File \"/opt/python2.7/lib/python2.7/site-packages/gunicorn/app/base.py\", line 189, in run\n    super(Application, self).run()\n  File \"/opt/python2.7/lib/python2.7/site-packages/gunicorn/app/base.py\", line 72, in run\n    Arbiter(self).run()\n  File \"/opt/python2.7/lib/python2.7/site-packages/gunicorn/arbiter.py\", line 171, in run\n    self.start()\n  File \"/opt/python2.7/lib/python2.7/site-packages/gunicorn/arbiter.py\", line 125, in start\n    self.pidfile.create(self.pid)\n  File \"/opt/python2.7/lib/python2.7/site-packages/gunicorn/pidfile.py\", line 23, in create\n    oldpid = self.validate()\n  File \"/opt/python2.7/lib/python2.7/site-packages/gunicorn/pidfile.py\", line 75, in validate\n    os.kill(wpid, 0)\nOSError: [Errno 1] Operation not permitted\n```\n\nThis happens because the process identified by the pid-file exists, but belongs to a different user than the one starting gunicorn.\n\n(This is with gunicorn 19.3.0)\n\n", "before_files": [{"content": "# -*- coding: utf-8 -\n#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\nimport errno\nimport os\nimport tempfile\n\n\nclass Pidfile(object):\n    \"\"\"\\\n    Manage a PID file. If a specific name is provided\n    it and '\"%s.oldpid\" % name' will be used. Otherwise\n    we create a temp file using os.mkstemp.\n    \"\"\"\n\n    def __init__(self, fname):\n        self.fname = fname\n        self.pid = None\n\n    def create(self, pid):\n        oldpid = self.validate()\n        if oldpid:\n            if oldpid == os.getpid():\n                return\n            msg = \"Already running on PID %s (or pid file '%s' is stale)\"\n            raise RuntimeError(msg % (oldpid, self.fname))\n\n        self.pid = pid\n\n        # Write pidfile\n        fdir = os.path.dirname(self.fname)\n        if fdir and not os.path.isdir(fdir):\n            raise RuntimeError(\"%s doesn't exist. Can't create pidfile.\" % fdir)\n        fd, fname = tempfile.mkstemp(dir=fdir)\n        os.write(fd, (\"%s\\n\" % self.pid).encode('utf-8'))\n        if self.fname:\n            os.rename(fname, self.fname)\n        else:\n            self.fname = fname\n        os.close(fd)\n\n        # set permissions to -rw-r--r--\n        os.chmod(self.fname, 420)\n\n    def rename(self, path):\n        self.unlink()\n        self.fname = path\n        self.create(self.pid)\n\n    def unlink(self):\n        \"\"\" delete pidfile\"\"\"\n        try:\n            with open(self.fname, \"r\") as f:\n                pid1 = int(f.read() or 0)\n\n            if pid1 == self.pid:\n                os.unlink(self.fname)\n        except:\n            pass\n\n    def validate(self):\n        \"\"\" Validate pidfile and make it stale if needed\"\"\"\n        if not self.fname:\n            return\n        try:\n            with open(self.fname, \"r\") as f:\n                try:\n                    wpid = int(f.read())\n                except ValueError:\n                    return\n\n                try:\n                    os.kill(wpid, 0)\n                    return wpid\n                except OSError as e:\n                    if e.args[0] == errno.ESRCH:\n                        return\n                    raise\n        except IOError as e:\n            if e.args[0] == errno.ENOENT:\n                return\n            raise\n", "path": "gunicorn/pidfile.py"}], "after_files": [{"content": "# -*- coding: utf-8 -\n#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\nimport errno\nimport os\nimport tempfile\n\n\nclass Pidfile(object):\n    \"\"\"\\\n    Manage a PID file. If a specific name is provided\n    it and '\"%s.oldpid\" % name' will be used. Otherwise\n    we create a temp file using os.mkstemp.\n    \"\"\"\n\n    def __init__(self, fname):\n        self.fname = fname\n        self.pid = None\n\n    def create(self, pid):\n        oldpid = self.validate()\n        if oldpid:\n            if oldpid == os.getpid():\n                return\n            msg = \"Already running on PID %s (or pid file '%s' is stale)\"\n            raise RuntimeError(msg % (oldpid, self.fname))\n\n        self.pid = pid\n\n        # Write pidfile\n        fdir = os.path.dirname(self.fname)\n        if fdir and not os.path.isdir(fdir):\n            raise RuntimeError(\"%s doesn't exist. Can't create pidfile.\" % fdir)\n        fd, fname = tempfile.mkstemp(dir=fdir)\n        os.write(fd, (\"%s\\n\" % self.pid).encode('utf-8'))\n        if self.fname:\n            os.rename(fname, self.fname)\n        else:\n            self.fname = fname\n        os.close(fd)\n\n        # set permissions to -rw-r--r--\n        os.chmod(self.fname, 420)\n\n    def rename(self, path):\n        self.unlink()\n        self.fname = path\n        self.create(self.pid)\n\n    def unlink(self):\n        \"\"\" delete pidfile\"\"\"\n        try:\n            with open(self.fname, \"r\") as f:\n                pid1 = int(f.read() or 0)\n\n            if pid1 == self.pid:\n                os.unlink(self.fname)\n        except:\n            pass\n\n    def validate(self):\n        \"\"\" Validate pidfile and make it stale if needed\"\"\"\n        if not self.fname:\n            return\n        try:\n            with open(self.fname, \"r\") as f:\n                try:\n                    wpid = int(f.read())\n                except ValueError:\n                    return\n\n                try:\n                    os.kill(wpid, 0)\n                    return wpid\n                except OSError as e:\n                    if e.args[0] == errno.EPERM:\n                        return wpid\n                    if e.args[0] == errno.ESRCH:\n                        return\n                    raise\n        except IOError as e:\n            if e.args[0] == errno.ENOENT:\n                return\n            raise\n", "path": "gunicorn/pidfile.py"}]}