title: Python : http.server.HTTPServer : How to close ALL opened files?
body: <p>So basically, I am making an HTTP webhooks server in Python 3 and wanted to add a restart function because shell access is very limited on the server it will be running on.</p>
  
  <p>I found this snippet somewhere on Stack Overflow earlier:</p>
  
  <pre><code>def restart_program():
      """Restarts the current program, with file objects and descriptors
         cleanup
      """
  
      try:
          p = psutil.Process(os.getpid())
          fds = p.open_files() + p.connections()
          print (fds)
          for handler in fds:
              os.close(handler.fd)
      except Exception as e:
          logging.error(e)
  
      python = sys.executable
      os.execl(python, python, *sys.argv)
  </code></pre>
  
  <p>For the most part, it works, but I wanted to make sure so I ran a few tests with <code>lsof</code> and found that every time I restarted the server, two more lines (files) were added to the list of open files:</p>
  
  <pre><code>python3 13923 darwin    5u  systm 0x18cd0c0bebdcbfd7        0t0            [ctl com.apple.netsrc id 9 unit 36]
  python3 13923 darwin    6u   unix 0x18cd0c0beb8fc95f        0t0            -&gt;0x18cd0c0beb8fbcdf
  </code></pre>
  
  <p>(the adresses varying each restart)</p>
  
  <p>These are only present when I initiate <code>httpd = ThreadingSimpleServer((host, port), Handler)</code>. But even after I call <code>httpd.server_close()</code> these open files persist and psutil doesn't seem to find them.</p>
  
  <p>This isn't really required feature. If this proves to be too much overhead I can drop it, but right now I am only interested in why my code doesn't work and a solution for my own sanity.</p>
  
  <p>Thanks in advance!</p>
  
  <p><strong>UPDATE</strong>:</p>
  
  <p>Changing <code>p.connections()</code> to <code>p.connections(kind='all')</code> got me the <code>unix</code> type fd. Still not sure how to close the <code>systm</code> type fd. Turns out the <code>unix</code> fd had to do with DNS...</p>
  
  <p><strong>UPDATE</strong>:</p>
  
  <p>Well, it looks like I found a solution, however messy it may be.</p>
  
  <pre><code>class MyFileHandler(object):
      """docstring for MyFileHandler."""
      def __init__(self, fd):
          super(MyFileHandler, self).__init__()
          self.fd = fd
  
  def get_open_systm_files(pid=os.getpid()):
      proc = subprocess.Popen(['lsof', '-p', str(pid)], stdout=subprocess.PIPE)
      return [MyFileHandler(int(str(l).split(' ')[6][:-1])) for l in proc.stdout.readlines() if b'systm' in l]
  
  def restart_program():
      """Restarts the current program, with file objects and descriptors
         cleanup
      """
  
      try:
          p = psutil.Process(os.getpid())
          fds = p.open_files() + p.connections()
          print (fds)
          for handler in fds:
              os.close(handler.fd)
      except Exception as e:
          logging.error(e)
  
      python = sys.executable
      os.execl(python, python, *sys.argv)
  </code></pre>
  
  <p>It's not pretty, but it works.</p>
  
  <p>If anyone could shed some light on what actually is/was going on I would very much like to know.</p>