subprocess.cpp raw

   1  // Copyright (c) 2025-present The Limenka Knots developers
   2  // Distributed under the MIT software license, see the accompanying
   3  // file COPYING or http://www.opensource.org/licenses/mit-license.php.
   4  
   5  #include <limenka-build-config.h> // IWYU pragma: keep
   6  
   7  #if !((defined _MSC_VER) || (defined __MINGW32__))
   8  
   9  #if HAVE_CLOSE_RANGE_LINUX
  10      #ifndef _GNU_SOURCE
  11          #define _GNU_SOURCE
  12      #endif
  13      #include <linux/close_range.h>
  14  #endif
  15  
  16  #include <limits.h>
  17  #include <sys/types.h>
  18  #include <sys/time.h>
  19  #include <sys/resource.h>
  20  #include <unistd.h>
  21  
  22  namespace subprocess {
  23  namespace detail {
  24  
  25  void subprocess_close_all_fds(const int except_fd)
  26  {
  27  #if HAVE_CLOSE_RANGE_GENERIC || HAVE_CLOSE_RANGE_LINUX
  28      if (except_fd < 3) {
  29          if (!close_range(3, UINT_MAX, 0)) return;
  30      } else if (except_fd == 3) {
  31          if (!close_range(4, UINT_MAX, 0)) return;
  32      } else {
  33          if (!(close_range(3, except_fd - 1, 0) || close_range(except_fd + 1, UINT_MAX, 0))) return;
  34      }
  35  #endif
  36  
  37      unsigned int max_fd;
  38  
  39      struct rlimit limit_fds;
  40      if (getrlimit(RLIMIT_NOFILE, &limit_fds) == 0 && limit_fds.rlim_cur < INT_MAX) {
  41          max_fd = limit_fds.rlim_cur;
  42      } else {
  43          max_fd = INT_MAX;
  44      }
  45  
  46      for (int fd = max_fd; fd > 2; --fd) {
  47          if (fd == except_fd) continue;
  48          close(fd);
  49      }
  50  }
  51  
  52  }  // namespace detail
  53  }  // namespace subprocess
  54  
  55  #endif // !((defined _MSC_VER) || (defined __MINGW32__))
  56