fork/exec & close file descriptors

Jon Ribbens jon+usenet at unequivocal.co.uk
Tue Jun 2 12:37:15 EDT 2015


On 2015-06-02, Marko Rauhamaa <marko at pacujo.net> wrote:
> Skip Montanaro <skip.montanaro at gmail.com>:
>
>> On Tue, Jun 2, 2015 at 10:28 AM, Marko Rauhamaa <marko at pacujo.net> wrote:
>>>
>>> The only problem is that you don't know how high you need to go in
>>> general.
>>
>> Sure, but I didn't know anyway, so no matter what upper bound I choose
>> (or what function I choose/implement), it's just going to be a guess.
>> os.closerange just codifies the straightforward procedure.
>
> Under linux, the cleanest way seems to be going through the files under
> /proc/self/fd:
>
>     def close_fds(leave_open=[0, 1, 2]):
>         fds = os.listdir(b'/proc/self/fd')
>         for fdn in fds:
>             fd = int(fdn)
>             if fd not in leave_open:
>                 os.close(fd)
>
> No need for a upper bound.

Or use the more generic code that I already posted in this thread:

  def closeall(min=0, max=4096, keep=()):
      """Close all open file descriptors except for the given exceptions.

      Any file descriptors below or equal to `min`, or in the set `keep`
      will not be closed. Any file descriptors above `max` *might* not be
      closed.
      """
      # First try /proc/self/pid
      try:
          for fd in os.listdir("/proc/self/fd"):
              try:
                  fd = int(fd)
              except ValueError:
                  continue
              if fd >= min and fd not in keep:
                  os.close(int(fd))
          return
      except OSError as exc:
          if exc[0] != errno.ENOENT:
              raise
      # If /proc was not available, fall back to closing a lot of descriptors.
      for fd in range(min, max):
          if fd not in keep:
              try:
                  os.close(fd)
              except OSError as exc:
                  if exc[0] != errno.EBADF:
                      raise

This function could use os.closerange(), but if the documentation is
correct and it ignores *all* errors and not just EBADF, then it
sounds like os.closerange() should not in fact ever be used for any
purpose.



More information about the Python-list mailing list