-
Notifications
You must be signed in to change notification settings - Fork 121
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
fb48747
commit 062ac9b
Showing
11 changed files
with
275 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
// Copyright (c) 2022 Klemens D. Morgenstern | ||
// | ||
// Distributed under the Boost Software License, Version 1.0. (See accompanying | ||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||
#ifndef BOOST_PROCESS_V2_POSIX_DETAIL_CLOSE_HANDLES_HPP | ||
#define BOOST_PROCESS_V2_POSIX_DETAIL_CLOSE_HANDLES_HPP | ||
|
||
#include <boost/process/v2/detail/config.hpp> | ||
#include <vector> | ||
|
||
BOOST_PROCESS_V2_BEGIN_NAMESPACE | ||
|
||
namespace posix | ||
{ | ||
|
||
namespace detail | ||
{ | ||
|
||
// whitelist must be ordered | ||
BOOST_PROCESS_V2_DECL void close_all(const std::vector<int> & whitelist, | ||
error_code & ec); | ||
|
||
} | ||
|
||
} | ||
|
||
BOOST_PROCESS_V2_END_NAMESPACE | ||
|
||
#endif //BOOST_PROCESS_V2_POSIX_DETAIL_CLOSE_HANDLES_HPP |
197 changes: 197 additions & 0 deletions
197
include/boost/process/v2/posix/detail/close_handles.ipp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,197 @@ | ||
// | ||
// boost/process/v2/poxix/detail/close_handles.hpp | ||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
// | ||
// Copyright (c) 2022 Klemens D. Morgenstern (klemens dot morgenstern at gmx dot net) | ||
// | ||
// Distributed under the Boost Software License, Version 1.0. (See accompanying | ||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||
// | ||
|
||
#ifndef BOOST_PROCESS_V2_POSIX_DETAIL_CLOSE_HANDLES_IPP | ||
#define BOOST_PROCESS_V2_POSIX_DETAIL_CLOSE_HANDLES_IPP | ||
|
||
#include <boost/process/v2/detail/config.hpp> | ||
#include <boost/process/v2/detail/last_error.hpp> | ||
#include <boost/process/v2/posix/detail/close_handles.hpp> | ||
// linux has close_range since 5.19 | ||
|
||
|
||
#if defined(__NetBSD__) | ||
|| defined(__FreeBSD__) | ||
|| defined(__APPLE__) | ||
|| defined(__MACH__) | ||
|
||
// https://www.freebsd.org/cgi/man.cgi?query=close_range&apropos=0&sektion=0&manpath=FreeBSD+13.1-RELEASE+and+Ports&arch=default&format=html | ||
// https://man.netbsd.org/closefrom.3 | ||
// __FreeBSD__ | ||
// | ||
// gives us | ||
// | ||
// int closefrom(int fd); | ||
// int close_range(u_int lowfd, u_int highfd, int flags); | ||
|
||
#include <unistd.h> | ||
#define BOOST_PROCESS_V2_HAS_CLOSE_RANGE_AND_CLOSEFROM 1 | ||
|
||
#elif defined(__sun) | ||
|
||
/*https://docs.oracle.com/cd/E36784_01/html/E36874/closefrom-3c.html | ||
int fdwalk(int (*func)(void *, int), void *cd); | ||
*/ | ||
|
||
#include <stdlib.h> | ||
#define BOOST_PROCESS_V2_HAS_PDFORK 1 | ||
|
||
#elif defined(__linux__) | ||
|
||
#include <linux/version.h> | ||
|
||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,11,0) | ||
|
||
// https://man7.org/linux/man-pages/man2/close_range.2.html | ||
#include <linux/close_range.h> | ||
#define BOOST_PROCESS_V2_HAS_CLOSE_RANGE 1 | ||
#else | ||
|
||
#include <dirent.h> | ||
|
||
#endif | ||
|
||
#else | ||
|
||
#include <dirent.h> | ||
|
||
#endif | ||
|
||
BOOST_PROCESS_V2_BEGIN_NAMESPACE | ||
|
||
namespace posix | ||
{ | ||
|
||
namespace detail | ||
{ | ||
|
||
#if defined(BOOST_PROCESS_V2_HAS_PDFORK) | ||
|
||
void close_all(const std::vector<int> & whitelist, error_code & ec) | ||
{ | ||
fdwalk(+[](void * p, int fd) | ||
{ | ||
const auto & wl = *static_cast<const std::vector<int>*>(p); | ||
if (std::find(wl.begin(), wl.end(), fd) == wl.end()) | ||
return ::close(fd); | ||
else | ||
return 0; | ||
}, const_cast<void*>(static_cast<const void*>(&whitelist)) ); | ||
ec = BOOST_PROCESS_V2_NAMESPACE::detail::get_last_error(); | ||
} | ||
|
||
#elif defined(BOOST_PROCESS_V2_HAS_CLOSE_RANGE_AND_CLOSEFROM) | ||
|
||
// freeBSD impl - whitelist must be ordered | ||
void close_all(const std::vector<int> & whitelist, error_code & ec) | ||
{ | ||
//the most common scenario is whitelist = {0,1,2} | ||
if (!whitelist.empty()) | ||
{ | ||
if (whitelist.front() != 0) | ||
::close_range(0, whitelist.front() - 1, CLOSE_RANGE_UNSHARE); | ||
|
||
for (std::size_t idx = 0u; | ||
idx < (whitelist.size() - 1u); | ||
idx++) | ||
{ | ||
const auto mine = whitelist[idx]; | ||
const auto next = whitelist[idx]; | ||
if ((mine + 1) != next && (mine != next)) | ||
{ | ||
::close_range(mine + 1, next - 1, CLOSE_RANGE_UNSHARE); | ||
} | ||
} | ||
|
||
::closefrom(whitelist.back() + 1); | ||
} | ||
else | ||
::closefrom(0); | ||
} | ||
|
||
#elif defined(BOOST_PROCESS_V2_HAS_CLOSE_RANGE) | ||
|
||
|
||
// linux impl - whitelist must be ordered | ||
void close_all(const std::vector<int> & whitelist, error_code & ec) | ||
{ | ||
// https://patchwork.kernel.org/project/linux-fsdevel/cover/[email protected]/ | ||
//the most common scenario is whitelist = {0,1,2} | ||
if (!whitelist.empty()) | ||
{ | ||
if (whitelist.front() != 0) | ||
::close_range(0, whitelist.front() - 1, CLOSE_RANGE_UNSHARE); | ||
|
||
for (std::size_t idx = 0u; | ||
idx < (whitelist.size() - 1u); | ||
idx++) | ||
{ | ||
const auto mine = whitelist[idx]; | ||
const auto next = whitelist[idx]; | ||
if ((mine + 1) != next && (mine != next)) | ||
{ | ||
::close_range(mine + 1, next - 1, CLOSE_RANGE_UNSHARE); | ||
} | ||
} | ||
|
||
::close_range(whitelist.back() + 1, std::numeric_limits<int>::max(), CLOSE_RANGE_UNSHARE); | ||
} | ||
else | ||
::close_range(0, std::numeric_limits<int>::max(), CLOSE_RANGE_UNSHARE); | ||
} | ||
|
||
#else | ||
|
||
// default one | ||
void close_all(const std::vector<int> & whitelist, error_code & ec) | ||
{ | ||
std::unique_ptr<DIR, void(*)(DIR*)> dir{::opendir("/dev/fd"), +[](DIR* p){::closedir(p);}}; | ||
if (dir.get() == nullptr) | ||
{ | ||
ec = BOOST_PROCESS_V2_NAMESPACE::detail::get_last_error(); | ||
return ; | ||
} | ||
|
||
auto dir_fd = ::dirfd(dir.get()); | ||
if (dir_fd == -1) | ||
{ | ||
ec = BOOST_PROCESS_V2_NAMESPACE::detail::get_last_error(); | ||
return ; | ||
} | ||
|
||
struct ::dirent * ent_p; | ||
|
||
while ((ent_p = ::readdir(dir.get())) != nullptr) | ||
{ | ||
if (ent_p->d_name[0] == '.') | ||
continue; | ||
|
||
const auto conv = std::atoi(ent_p->d_name); | ||
if (conv == 0 && (ent_p->d_name[0] != '0' && ent_p->d_name[1] != '\0')) | ||
continue; | ||
|
||
if (conv == dir_fd | ||
|| (std::find(whitelist.begin(), whitelist.end(), conv) != whitelist.end())) | ||
continue; | ||
|
||
::close(conv); | ||
} | ||
} | ||
|
||
#endif | ||
|
||
} | ||
|
||
} | ||
|
||
BOOST_PROCESS_V2_END_NAMESPACE | ||
|
||
#endif //BOOST_PROCESS_V2_POSIX_DETAIL_CLOSE_HANDLES_IPP |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters