File indexing completed on 2025-01-18 09:50:11
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_PROCESS_V2_POSIX_DETAIL_CLOSE_HANDLES_IPP
0012 #define BOOST_PROCESS_V2_POSIX_DETAIL_CLOSE_HANDLES_IPP
0013
0014 #include <boost/process/v2/detail/config.hpp>
0015 #include <boost/process/v2/detail/last_error.hpp>
0016 #include <boost/process/v2/posix/detail/close_handles.hpp>
0017
0018
0019
0020 #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031 #include <unistd.h>
0032 #define BOOST_PROCESS_V2_HAS_CLOSE_RANGE_AND_CLOSEFROM 1
0033
0034 #elif defined(__sun)
0035
0036
0037
0038
0039
0040
0041 #include <stdlib.h>
0042 #define BOOST_PROCESS_V2_HAS_PDFORK 1
0043
0044 #elif defined(__linux__)
0045
0046 #include <linux/version.h>
0047
0048 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5,11,0)
0049
0050
0051 #include <linux/close_range.h>
0052 #define BOOST_PROCESS_V2_HAS_CLOSE_RANGE 1
0053 #else
0054
0055 #include <dirent.h>
0056
0057 #endif
0058
0059 #else
0060
0061 #include <dirent.h>
0062
0063 #endif
0064
0065 BOOST_PROCESS_V2_BEGIN_NAMESPACE
0066
0067 namespace posix
0068 {
0069
0070 namespace detail
0071 {
0072
0073 #if defined(BOOST_PROCESS_V2_HAS_PDFORK)
0074
0075 void close_all(const std::vector<int> & whitelist, error_code & ec)
0076 {
0077 fdwalk(+[](void * p, int fd)
0078 {
0079 const auto & wl = *static_cast<const std::vector<int>*>(p);
0080 if (std::find(wl.begin(), wl.end(), fd) == wl.end())
0081 return ::close(fd);
0082 else
0083 return 0;
0084 }, const_cast<void*>(static_cast<const void*>(&whitelist)) );
0085 ec = BOOST_PROCESS_V2_NAMESPACE::detail::get_last_error();
0086 }
0087
0088 #elif defined(BOOST_PROCESS_V2_HAS_CLOSE_RANGE_AND_CLOSEFROM)
0089
0090
0091 void close_all(const std::vector<int> & whitelist, error_code & ec)
0092 {
0093
0094 if (!whitelist.empty())
0095 {
0096 if (whitelist.front() != 0)
0097 ::close_range(0, whitelist.front() - 1, 0);
0098
0099 for (std::size_t idx = 0u;
0100 idx < (whitelist.size() - 1u);
0101 idx++)
0102 {
0103 const auto mine = whitelist[idx];
0104 const auto next = whitelist[idx];
0105 if ((mine + 1) != next && (mine != next))
0106 {
0107 ::close_range(mine + 1, next - 1, 0);
0108 }
0109 }
0110
0111 ::closefrom(whitelist.back() + 1);
0112 }
0113 else
0114 ::closefrom(0);
0115 }
0116
0117 #elif defined(BOOST_PROCESS_V2_HAS_CLOSE_RANGE)
0118
0119
0120
0121 void close_all(const std::vector<int> & whitelist, error_code & ec)
0122 {
0123
0124
0125 if (!whitelist.empty())
0126 {
0127 if (whitelist.front() != 0)
0128 ::close_range(0, whitelist.front() - 1, CLOSE_RANGE_UNSHARE);
0129
0130 for (std::size_t idx = 0u;
0131 idx < (whitelist.size() - 1u);
0132 idx++)
0133 {
0134 const auto mine = whitelist[idx];
0135 const auto next = whitelist[idx];
0136 if ((mine + 1) != next && (mine != next))
0137 {
0138 ::close_range(mine + 1, next - 1, CLOSE_RANGE_UNSHARE);
0139 }
0140 }
0141
0142 ::close_range(whitelist.back() + 1, std::numeric_limits<int>::max(), CLOSE_RANGE_UNSHARE);
0143 }
0144 else
0145 ::close_range(0, std::numeric_limits<int>::max(), CLOSE_RANGE_UNSHARE);
0146 }
0147
0148 #else
0149
0150
0151 void close_all(const std::vector<int> & whitelist, error_code & ec)
0152 {
0153 std::unique_ptr<DIR, void(*)(DIR*)> dir{::opendir("/dev/fd"), +[](DIR* p){::closedir(p);}};
0154 if (dir.get() == nullptr)
0155 {
0156 ec = BOOST_PROCESS_V2_NAMESPACE::detail::get_last_error();
0157 return ;
0158 }
0159
0160 auto dir_fd = ::dirfd(dir.get());
0161 if (dir_fd == -1)
0162 {
0163 ec = BOOST_PROCESS_V2_NAMESPACE::detail::get_last_error();
0164 return ;
0165 }
0166
0167 struct ::dirent * ent_p;
0168
0169 while ((ent_p = ::readdir(dir.get())) != nullptr)
0170 {
0171 if (ent_p->d_name[0] == '.')
0172 continue;
0173
0174 const auto conv = std::atoi(ent_p->d_name);
0175 if (conv == 0 && (ent_p->d_name[0] != '0' && ent_p->d_name[1] != '\0'))
0176 continue;
0177
0178 if (conv == dir_fd
0179 || (std::find(whitelist.begin(), whitelist.end(), conv) != whitelist.end()))
0180 continue;
0181
0182 ::close(conv);
0183 }
0184 }
0185
0186 #endif
0187
0188 }
0189
0190 }
0191
0192 BOOST_PROCESS_V2_END_NAMESPACE
0193
0194 #endif