Repository navigation
Fix file descriptor cleanup on OpenBSD #571
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -24,12 +24,20 @@ | |
| // | ||
| // gives us | ||
| // | ||
| // int closefrom(int fd); | ||
| // void closefrom(int lowfd); | ||
| // 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(__OpenBSD__) | ||
|
|
||
| // https://man.openbsd.org/closefrom.2 | ||
| // int closefrom(int fd); | ||
|
|
||
| #include <unistd.h> | ||
| #define BOOST_PROCESS_V2_HAS_CLOSEFROM 1 | ||
|
|
||
| #elif defined(__sun) | ||
|
|
||
| /*https://docs.oracle.com/cd/E36784_01/html/E36874/closefrom-3c.html | ||
|
|
@@ -113,16 +121,25 @@ void close_all(const std::vector<int> & whitelist, error_code & ec) | |
| ec = BOOST_PROCESS_V2_NAMESPACE::detail::get_last_error(); | ||
| } | ||
|
|
||
| #elif defined(BOOST_PROCESS_V2_HAS_CLOSE_RANGE_AND_CLOSEFROM) | ||
| #elif defined(BOOST_PROCESS_V2_HAS_CLOSEFROM) || \ | ||
| 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) | ||
| /* FreeBSD and OpenBSD implementation - whitelist must be ordered. | ||
| * closefrom() differ, handle both implementation : reset errno and check EINTR. | ||
| */ | ||
| 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) | ||
| if (whitelist.front() != 0) { | ||
| #if defined(BOOST_PROCESS_V2_HAS_CLOSE_RANGE_AND_CLOSEFROM) | ||
| ::close_range(0, whitelist.front() - 1, 0); | ||
| #else | ||
| for (int fd = 0; fd < whitelist.front(); fd++) | ||
| while (::close(fd) == -1 && errno == EINTR); | ||
| #endif | ||
| } | ||
|
|
||
| for (std::size_t idx = 0u; | ||
| idx < (whitelist.size() - 1u); | ||
|
|
@@ -132,14 +149,29 @@ void close_all(const std::vector<int> & whitelist, error_code & ec) | |
| const auto next = whitelist[idx + 1]; | ||
| if ((mine + 1) != next && (mine != next)) | ||
| { | ||
| #if defined(BOOST_PROCESS_V2_HAS_CLOSE_RANGE_AND_CLOSEFROM) | ||
| ::close_range(mine + 1, next - 1, 0); | ||
| #else | ||
| for (int fd = mine + 1; fd < next; fd++) | ||
| while (::close(fd) == -1 && errno == EINTR); | ||
| #endif | ||
| } | ||
| } | ||
|
|
||
| ::closefrom(whitelist.back() + 1); | ||
| do | ||
| { | ||
| errno = 0; | ||
| ::closefrom(whitelist.back() + 1); | ||
| } while (errno == EINTR); | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is trade-off to handle both FreeBSD and OpenBSD implementation. Initially this was meant to be small; should we implement yet another close_all() ?
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That should be #if-defed, because resetting errno like that is very uncommon. |
||
| } | ||
| else | ||
| ::closefrom(0); | ||
| { | ||
| do | ||
| { | ||
| errno = 0; | ||
| ::closefrom(0); | ||
| } while (errno == EINTR); | ||
| } | ||
| } | ||
|
|
||
| #elif defined(BOOST_PROCESS_V2_HAS_CLOSE_RANGE) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just notice that FreeBSD closefrom differ from OpenBSD; see the comment below