2
0
mirror of https://github.com/boostorg/process.git synced 2026-01-29 19:52:13 +00:00

Compare commits

...

34 Commits

Author SHA1 Message Date
Klemens Morgenstern
e6ad7035e9 fixes the exit-code error on osx builds. 2024-11-08 21:14:57 +08:00
Klemens Morgenstern
58586e420c added deprecation notice for v1. 2024-10-30 09:05:20 +08:00
Samuel Venable
7e5dd4075f bp2::ext::env() Fixes (#415)
* Implement OpenBSD Executable PatH
* Static Cast Device and iNode
* Add Name Spaces to Exe Checker
* Strings to File System Paths

---------

Co-authored-by: freebsd <freebsd@freebsd.lan>
2024-10-30 09:05:20 +08:00
Samuel Venable
3ad68a3f2a [OpenBSD] Add Missing Semicolons (#414)
* [OpenBSD] Add Missing Semicolons
2024-10-30 09:05:20 +08:00
Samuel Venable
8a8ca8b7ab OpenBSD fix & Solaris fixes
[DragonFly BSD] Use Proper CWD From PID Code
2024-10-30 09:05:20 +08:00
Klemens Morgenstern
817128108a changed error macros to require a ; at the end. 2024-10-30 09:05:20 +08:00
Klemens Morgenstern
941e93b587 removed definition of NOMINMAX 2024-10-30 08:09:28 +08:00
Klemens Morgenstern
e827d14542 reduced asio related macro usage. 2024-10-30 08:09:28 +08:00
Klemens Morgenstern
f218a6a6c1 added pthread to test linking for freebsd on v1 as well. 2024-10-30 08:09:28 +08:00
Klemens Morgenstern
11a0d0d7c1 added pthread to test linking for freebsd 2024-10-30 08:09:28 +08:00
Klemens Morgenstern
fdfb5043cb add kvm to process target on bsd 2024-10-30 08:09:28 +08:00
Klemens Morgenstern
e46a514629 replaced deadline_timer with steady_timer. 2024-10-30 08:09:28 +08:00
Klemens Morgenstern
36954338d8 remove test_impl lib 2024-10-30 08:09:28 +08:00
Klemens Morgenstern
a44fd24523 unified cancellation on process.async_wait() 2024-10-30 08:09:28 +08:00
Klemens Morgenstern
eb6b49c090 disabled /boost//coroutine dependent tests 2024-10-30 08:09:28 +08:00
Klemens Morgenstern
928674d2e3 added test async_wait cancellation test. 2024-10-30 08:09:28 +08:00
Klemens Morgenstern
894f371898 typo fixes. 2024-10-30 08:09:28 +08:00
Klemens Morgenstern
7ed1648032 removed filesystem from the compiled lib.
Shuold fix #390.
2024-10-30 08:09:28 +08:00
Klemens Morgenstern
a96f7a04e0 Wrapped proc_info.h functions with IOS check. Using the ext functions will yield a operation_not_supported at runtime.
Closes #401.
2024-10-30 08:09:28 +08:00
Klemens Morgenstern
46b71d5e96 Switched #error to ENOTSUP for ext libs. Should help #413
Closes #358.
2024-10-30 08:09:28 +08:00
Klemens Morgenstern
9f104634a9 Typo fix.
Closes #365
2024-10-30 08:09:28 +08:00
Klemens Morgenstern
c492c93062 Added BOOST_PROCESS_V2_POSIX_FORCE_DISABLE_CLOSE_RANGE
Implements #378.
2024-10-30 08:09:27 +08:00
Klemens Morgenstern
12192d35d3 Applying @sehe's patch.
closes #317
2024-10-30 08:09:27 +08:00
Samuel Venable
f741b0d120 [DragonFly BSD] Use Proper CWD From PID Code 2024-10-30 08:09:27 +08:00
Brad Smith
211a3134b6 Fix building on OpenBSD
OpenBSD does not have close_range() nor does NetBSD.

OpenBSD needs environ like the other *BSD's.

The build was erroring on kp_pid, it looks like p_pid is appropriate.
2024-10-30 08:09:27 +08:00
Klemens Morgenstern
642bd7cf5c removed more faulty V2_DECLs 2024-10-30 08:09:27 +08:00
Julien Schueller
8df45b8f68 Fix undefined reference to ws2_32
else it fails to link on mingw:
```
process_handle_windows.o:process_handle_windows.cpp:(.text+0x25): undefined reference to `_imp__WSACleanup@0'
```
2024-10-30 08:09:27 +08:00
Benjamin Buch
54479a7372 remove dllimport from utf8.hpp to fix MSVC build 2024-10-30 08:09:27 +08:00
René Ferdinand Rivera Morell
9761be99bb Add support for modular build structure. (#389)
* Make the library modular usable.

* Switch to library requirements instead of source. As source puts extra source in install targets.

* Add requires-b2 check to top-level build file.

* Add missing test deps.

* Bump B2 require to 5.2

* Fix duplicate def of boost.process.fs feature.

* Add missing boost_test dependency.

* Move inter-lib dependencies to a project variable and into the build targets.

* Switch to /boost/test//included target for header only mode of Boost.Test.

* Adjust doc build to avoid boost-root references.

* Update build deps.

* Fix link and build of deps.
2024-10-30 08:09:27 +08:00
Klemens Morgenstern
e5e898f363 fixed v1 reference include. 2024-09-26 18:48:51 +08:00
Jackarain
9561ebad1c Fix mingw cross-compile 2024-07-31 08:19:56 +08:00
Klemens Morgenstern
755a3ec78d fixed dll symbokl export on windows & clean up jamfile. 2024-07-24 10:12:10 +08:00
Klemens Morgenstern
5f80218655 added CLOSE_RANGE_UNSHARE defined for syscall of close_range. 2024-07-20 08:25:10 +08:00
Ruben Perez
3719df39cd Alpine-Linux CI 2024-07-20 08:25:10 +08:00
59 changed files with 1074 additions and 731 deletions

View File

@@ -141,6 +141,43 @@ jobs:
cd ../boost-root cd ../boost-root
./b2 -j3 libs/$LIBRARY/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} variant=debug,release ./b2 -j3 libs/$LIBRARY/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} variant=debug,release
alpine-linux:
runs-on: ubuntu-latest
container:
image: alpine:3.20.1
steps:
- name: Install packages
run: apk add g++ git python3 linux-headers
- uses: actions/checkout@v4
- name: Setup Boost
run: |
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
LIBRARY=${GITHUB_REPOSITORY#*/}
echo LIBRARY: $LIBRARY
echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
echo GITHUB_REF: $GITHUB_REF
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
REF=${REF#refs/heads/}
echo REF: $REF
BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true
echo BOOST_BRANCH: $BOOST_BRANCH
cd ..
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
git submodule update --init tools/boostdep
python3 tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY
./bootstrap.sh
./b2 -d0 headers
- name: Run tests
run: |
cd ../boost-root
./b2 -j3 libs/$LIBRARY/test toolset=gcc cxxstd=23 variant=debug,release
windows: windows:
strategy: strategy:
fail-fast: false fail-fast: false

View File

@@ -57,7 +57,7 @@ else()
endif() endif()
if (WIN32) if (WIN32)
target_link_libraries(boost_process PUBLIC ntdll shell32 Advapi32 user32) target_link_libraries(boost_process PUBLIC ntdll shell32 advapi32 user32)
endif() endif()
if(BUILD_SHARED_LIBS) if(BUILD_SHARED_LIBS)

47
build.jam Normal file
View File

@@ -0,0 +1,47 @@
# Copyright René Ferdinand Rivera Morell 2024
# 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)
require-b2 5.2 ;
import feature : feature ;
feature boost.process.fs : boost std : optional propagated ;
feature boost.process.disable-close-range : on off : optional ;
constant boost_dependencies :
/boost/algorithm//boost_algorithm
/boost/asio//boost_asio
/boost/assert//boost_assert
/boost/config//boost_config
/boost/core//boost_core
/boost/fusion//boost_fusion
/boost/io//boost_io
/boost/iterator//boost_iterator
/boost/move//boost_move
/boost/optional//boost_optional
/boost/system//boost_system
/boost/throw_exception//boost_throw_exception
/boost/tokenizer//boost_tokenizer
/boost/type_index//boost_type_index
/boost/type_traits//boost_type_traits
/boost/utility//boost_utility
/boost/winapi//boost_winapi ;
project /boost/process
: common-requirements
<include>include
: default-build
<boost.process.fs>boost
;
explicit
[ alias boost_process : build//boost_process ]
[ alias all : boost_process example example/v2 test ]
;
call-if : boost-library process
: install boost_process
;

View File

@@ -5,7 +5,8 @@
import os ; import os ;
import feature ; import feature ;
import ../../config/checks/config : requires ; import-search /boost/config/checks ;
import config : requires ;
project : requirements project : requirements
<define>BOOST_ASIO_NO_DEPRECATED <define>BOOST_ASIO_NO_DEPRECATED
@@ -15,11 +16,11 @@ project : requirements
<target-os>windows:<define>WIN32_LEAN_AND_MEAN <target-os>windows:<define>WIN32_LEAN_AND_MEAN
<target-os>linux:<linkflags>-lpthread <target-os>linux:<linkflags>-lpthread
: source-location ../src : source-location ../src
: common-requirements
<library>$(boost_dependencies)
<boost.process.fs>std:<define>BOOST_PROCESS_USE_STD_FS=1
; ;
feature.feature boost.process.fs : boost std : propagated composite ;
feature.compose <boost.process.fs>std : <define>BOOST_PROCESS_USE_STD_FS=1 ;
alias process_sources alias process_sources
: detail/environment_posix.cpp : detail/environment_posix.cpp
detail/environment_win.cpp detail/environment_win.cpp
@@ -40,26 +41,33 @@ alias process_sources
shell.cpp shell.cpp
; ;
if [ os.name ] = NT lib shell32 ;
{ lib advapi32 ;
lib shell32 ; lib ntdll ;
lib Advapi32 ; lib user32 ;
lib Ntdll ; lib ws2_32 ;
lib user32 ;
} lib kvm ;
lib procstat ;
lib boost_process lib boost_process
: process_sources : process_sources
: requirements <define>BOOST_PROCESS_SOURCE=1 : requirements <define>BOOST_PROCESS_SOURCE=1
<link>shared:<define>BOOST_PROCESS_DYN_LINK=1 <link>shared:<define>BOOST_PROCESS_DYN_LINK=1
<boost.process.fs>boost:<library>/boost//filesystem <boost.process.fs>boost:<library>/boost/filesystem//boost_filesystem
<boost.process.disable-close-range>on:<define>BOOST_PROCESS_V2_POSIX_FORCE_DISABLE_CLOSE_RANGE=1
<target-os>windows:<library>shell32 <target-os>windows:<library>shell32
<target-os>windows:<library>user32 <target-os>windows:<library>user32
<target-os>windows:<library>Ntdll <target-os>windows:<library>ntdll
<target-os>windows:<library>Advapi32 <target-os>windows:<library>advapi32
<target-os>windows:<library>ws2_32
<target-os>bsd:<library>kvm
<target-os>freebsd:<library>kvm
<target-os>freebsd:<library>procstat
<target-os>netbsd:<library>kvm
<target-os>openbsd:<library>kvm
<target-os>solaris:<library>kvm
: usage-requirements : usage-requirements
<link>shared:<define>BOOST_PROCESS_DYN_LINK=1 <link>shared:<define>BOOST_PROCESS_DYN_LINK=1
<boost.process.fs>boost:<library>/boost//filesystem <boost.process.fs>boost:<library>/boost/filesystem//boost_filesystem
; ;
boost-install boost_process ;

View File

@@ -24,7 +24,7 @@ generators.register-standard common.copy : XML : XMLPROCESSWORKAROUND ;
xmlprocessworkaround posix_pseudocode : v1/posix_pseudocode.xml ; xmlprocessworkaround posix_pseudocode : v1/posix_pseudocode.xml ;
xmlprocessworkaround windows_pseudocode : v1/windows_pseudocode.xml ; xmlprocessworkaround windows_pseudocode : v1/windows_pseudocode.xml ;
path-constant INCLUDES : ../../.. ; path-constant INCLUDES : ../include ;
doxygen reference_v1 doxygen reference_v1
: :
@@ -63,7 +63,6 @@ doxygen reference_v2
\"BOOST_PROCESS_V2_END_NAMESPACE= } } }\" \\ \"BOOST_PROCESS_V2_END_NAMESPACE= } } }\" \\
BOOST_PROCESS_V2_NAMESPACE=boost::process::v2 \\ BOOST_PROCESS_V2_NAMESPACE=boost::process::v2 \\
BOOST_PROCESS_V2_DECL \\ BOOST_PROCESS_V2_DECL \\
BOOST_PROCESS_V2_SOURCE \\
BOOST_PROCESS_V2_INITFN_AUTO_RESULT_TYPE(x,y)=deduced \\ BOOST_PROCESS_V2_INITFN_AUTO_RESULT_TYPE(x,y)=deduced \\
BOOST_PROCESS_V2_COMPLETION_TOKEN_FOR(X)=Token \\ BOOST_PROCESS_V2_COMPLETION_TOKEN_FOR(X)=Token \\
BOOST_PROCESS_V2_DEFAULT_COMPLETION_TOKEN_TYPE(E)=DEFAULT_TYPE \\ BOOST_PROCESS_V2_DEFAULT_COMPLETION_TOKEN_TYPE(E)=DEFAULT_TYPE \\

View File

@@ -11,7 +11,7 @@
] ]
] ]
[note Process v1 will be deprecated in the future. Use v2 for new projects.] [note Process v1 will be deprecated in the next release (1.88). Use v2 for new projects.]
[include v1.qbk] [include v1.qbk]
[include v2.qbk] [include v2.qbk]

View File

@@ -6,6 +6,6 @@
[include v1/design.qbk] [include v1/design.qbk]
[include v1/extend.qbk] [include v1/extend.qbk]
[include v1/faq.qbk] [include v1/faq.qbk]
[xinclude reference_v2.xml] [xinclude reference_v1.xml]
[endsect] [endsect]

View File

@@ -73,14 +73,6 @@ Instead of using ascii-APIs on windows, process V2 just assumes UTF-8 everywhere
[endsect] [endsect]
[section:src Separate compilation]
Boost.process v2 supports separate compilation similar to other boost libraries.
It can be achieved by defining `BOOST_PROCESS_V2_SEPARATE_COMPILATION` and including
`<process/v2/src.hpp>` in a single compile unit.
[endsect]
[section:limit_fd Fd safe by default] [section:limit_fd Fd safe by default]
While not a problem on windows (since HANDLEs get manually enabled for inheritance), While not a problem on windows (since HANDLEs get manually enabled for inheritance),

View File

@@ -8,7 +8,7 @@
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
project : requirements project : requirements
<include>../../.. <library>/boost/process//boost_process
<toolset>msvc:<define>_SCL_SECURE_NO_WARNINGS <toolset>msvc:<define>_SCL_SECURE_NO_WARNINGS
<target-os>windows:<define>WIN32_LEAN_AND_MEAN <target-os>windows:<define>WIN32_LEAN_AND_MEAN
; ;

View File

@@ -4,14 +4,12 @@
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
project : requirements project : requirements
<include>../../..
<toolset>msvc:<define>_SCL_SECURE_NO_WARNINGS <toolset>msvc:<define>_SCL_SECURE_NO_WARNINGS
<target-os>windows:<define>WIN32_LEAN_AND_MEAN <target-os>windows:<define>WIN32_LEAN_AND_MEAN
<link>static
; ;
import testing ; import testing ;
alias filesystem : /boost//filesystem : <link>static ; exe intro : intro.cpp ;
exe intro_popen : intro_popen.cpp : <boost.process.fs>boost ;
exe intro : intro.cpp filesystem ;
exe intro_popen : intro_popen.cpp filesystem ;

View File

@@ -257,7 +257,16 @@ struct basic_pipebuf : std::basic_streambuf<CharT, Traits>
{ {
if (!is_open()) if (!is_open())
return nullptr; return nullptr;
overflow(Traits::eof()); try {
overflow(Traits::eof());
_pipe.close();
return this;
}
catch(...)
{
_pipe.close();
throw ;
}
return this; return this;
} }
private: private:

View File

@@ -71,7 +71,7 @@ struct bound_launcher
template<typename ExecutionContext, typename Args, typename ... Inits> template<typename ExecutionContext, typename Args, typename ... Inits>
auto operator()(ExecutionContext & context, auto operator()(ExecutionContext & context,
const typename std::enable_if<std::is_convertible< const typename std::enable_if<std::is_convertible<
ExecutionContext&, BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context&>::value, ExecutionContext&, net::execution_context&>::value,
filesystem::path >::type & executable, filesystem::path >::type & executable,
Args && args, Args && args,
Inits && ... inits) -> basic_process<typename ExecutionContext::executor_type> Inits && ... inits) -> basic_process<typename ExecutionContext::executor_type>
@@ -88,7 +88,7 @@ struct bound_launcher
auto operator()(ExecutionContext & context, auto operator()(ExecutionContext & context,
error_code & ec, error_code & ec,
const typename std::enable_if<std::is_convertible< const typename std::enable_if<std::is_convertible<
ExecutionContext&, BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context&>::value, ExecutionContext&, net::execution_context&>::value,
filesystem::path >::type & executable, filesystem::path >::type & executable,
Args && args, Args && args,
Inits && ... inits ) -> basic_process<typename ExecutionContext::executor_type> Inits && ... inits ) -> basic_process<typename ExecutionContext::executor_type>
@@ -103,8 +103,8 @@ struct bound_launcher
template<typename Executor, typename Args, typename ... Inits> template<typename Executor, typename Args, typename ... Inits>
auto operator()(Executor exec, auto operator()(Executor exec,
const typename std::enable_if< const typename std::enable_if<
BOOST_PROCESS_V2_ASIO_NAMESPACE::execution::is_executor<Executor>::value || net::execution::is_executor<Executor>::value ||
BOOST_PROCESS_V2_ASIO_NAMESPACE::is_executor<Executor>::value, net::is_executor<Executor>::value,
filesystem::path >::type & executable, filesystem::path >::type & executable,
Args && args, Args && args,
Inits && ... inits ) -> basic_process<Executor> Inits && ... inits ) -> basic_process<Executor>
@@ -120,8 +120,8 @@ struct bound_launcher
auto operator()(Executor exec, auto operator()(Executor exec,
error_code & ec, error_code & ec,
const typename std::enable_if< const typename std::enable_if<
BOOST_PROCESS_V2_ASIO_NAMESPACE::execution::is_executor<Executor>::value || net::execution::is_executor<Executor>::value ||
BOOST_PROCESS_V2_ASIO_NAMESPACE::is_executor<Executor>::value, net::is_executor<Executor>::value,
filesystem::path >::type & executable, filesystem::path >::type & executable,
Args && args, Args && args,
Inits && ... inits ) -> basic_process<Executor> Inits && ... inits ) -> basic_process<Executor>
@@ -138,7 +138,7 @@ struct bound_launcher
auto invoke(detail::index_sequence<Idx...>, auto invoke(detail::index_sequence<Idx...>,
ExecutionContext & context, ExecutionContext & context,
const typename std::enable_if<std::is_convertible< const typename std::enable_if<std::is_convertible<
ExecutionContext&, BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context&>::value, ExecutionContext&, net::execution_context&>::value,
filesystem::path >::type & executable, filesystem::path >::type & executable,
Args && args, Args && args,
Inits && ... inits) -> basic_process<typename ExecutionContext::executor_type> Inits && ... inits) -> basic_process<typename ExecutionContext::executor_type>
@@ -156,7 +156,7 @@ struct bound_launcher
ExecutionContext & context, ExecutionContext & context,
error_code & ec, error_code & ec,
const typename std::enable_if<std::is_convertible< const typename std::enable_if<std::is_convertible<
ExecutionContext&, BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context&>::value, ExecutionContext&, net::execution_context&>::value,
filesystem::path >::type & executable, filesystem::path >::type & executable,
Args && args, Args && args,
Inits && ... inits ) -> basic_process<typename ExecutionContext::executor_type> Inits && ... inits ) -> basic_process<typename ExecutionContext::executor_type>
@@ -172,8 +172,8 @@ struct bound_launcher
auto invoke(detail::index_sequence<Idx...>, auto invoke(detail::index_sequence<Idx...>,
Executor exec, Executor exec,
const typename std::enable_if< const typename std::enable_if<
BOOST_PROCESS_V2_ASIO_NAMESPACE::execution::is_executor<Executor>::value || net::execution::is_executor<Executor>::value ||
BOOST_PROCESS_V2_ASIO_NAMESPACE::is_executor<Executor>::value, net::is_executor<Executor>::value,
filesystem::path >::type & executable, filesystem::path >::type & executable,
Args && args, Args && args,
Inits && ... inits ) -> basic_process<Executor> Inits && ... inits ) -> basic_process<Executor>
@@ -190,8 +190,8 @@ struct bound_launcher
Executor exec, Executor exec,
error_code & ec, error_code & ec,
const typename std::enable_if< const typename std::enable_if<
BOOST_PROCESS_V2_ASIO_NAMESPACE::execution::is_executor<Executor>::value || net::execution::is_executor<Executor>::value ||
BOOST_PROCESS_V2_ASIO_NAMESPACE::is_executor<Executor>::value, net::is_executor<Executor>::value,
filesystem::path >::type & executable, filesystem::path >::type & executable,
Args && args, Args && args,
Inits && ... inits ) -> basic_process<Executor> Inits && ... inits ) -> basic_process<Executor>

View File

@@ -7,12 +7,7 @@
#if defined(BOOST_PROCESS_V2_STANDALONE) #if defined(BOOST_PROCESS_V2_STANDALONE)
#define BOOST_PROCESS_V2_ASIO_NAMESPACE asio
#define BOOST_PROCESS_V2_COMPLETION_TOKEN_FOR(Sig) ASIO_COMPLETION_TOKEN_FOR(Sig) #define BOOST_PROCESS_V2_COMPLETION_TOKEN_FOR(Sig) ASIO_COMPLETION_TOKEN_FOR(Sig)
#define BOOST_PROCESS_V2_DEFAULT_COMPLETION_TOKEN_TYPE(Executor) ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)
#define BOOST_PROCESS_V2_INITFN_AUTO_RESULT_TYPE(Token, Signature) ASIO_INITFN_AUTO_RESULT_TYPE(Token, Signature)
#define BOOST_PROCESS_V2_DEFAULT_COMPLETION_TOKEN(Executor) ASIO_DEFAULT_COMPLETION_TOKEN(Executor)
#define BOOST_PROCESS_V2_INITFN_DEDUCED_RESULT_TYPE(x,y,z) ASIO_INITFN_DEDUCED_RESULT_TYPE(x,y,z)
#include <asio/detail/config.hpp> #include <asio/detail/config.hpp>
#include <system_error> #include <system_error>
@@ -24,10 +19,6 @@
#if defined(ASIO_WINDOWS) #if defined(ASIO_WINDOWS)
#define BOOST_PROCESS_V2_WINDOWS 1 #define BOOST_PROCESS_V2_WINDOWS 1
// Windows: suppress definition of "min" and "max" macros.
#if !defined(NOMINMAX)
# define NOMINMAX 1
#endif
#endif #endif
#if defined(ASIO_HAS_UNISTD_H) #if defined(ASIO_HAS_UNISTD_H)
@@ -38,14 +29,14 @@
#define BOOST_PROCESS_V2_END_NAMESPACE } #define BOOST_PROCESS_V2_END_NAMESPACE }
#define BOOST_PROCESS_V2_NAMESPACE process_v2 #define BOOST_PROCESS_V2_NAMESPACE process_v2
namespace asio {}
BOOST_PROCESS_V2_BEGIN_NAMESPACE
namespace net = ::asio;
BOOST_PROCESS_V2_END_NAMESPACE
#else #else
#define BOOST_PROCESS_V2_ASIO_NAMESPACE boost::asio
#define BOOST_PROCESS_V2_COMPLETION_TOKEN_FOR(Sig) BOOST_ASIO_COMPLETION_TOKEN_FOR(Sig) #define BOOST_PROCESS_V2_COMPLETION_TOKEN_FOR(Sig) BOOST_ASIO_COMPLETION_TOKEN_FOR(Sig)
#define BOOST_PROCESS_V2_DEFAULT_COMPLETION_TOKEN_TYPE(Executor) BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)
#define BOOST_PROCESS_V2_INITFN_AUTO_RESULT_TYPE(Token, Signature) BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(Token, Signature)
#define BOOST_PROCESS_V2_DEFAULT_COMPLETION_TOKEN(Executor) BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(Executor)
#define BOOST_PROCESS_V2_INITFN_DEDUCED_RESULT_TYPE(x,y,z) BOOST_ASIO_INITFN_DEDUCED_RESULT_TYPE(x,y,z)
#include <boost/config.hpp> #include <boost/config.hpp>
#include <boost/io/quoted.hpp> #include <boost/io/quoted.hpp>
@@ -57,10 +48,6 @@
#if defined(BOOST_WINDOWS_API) #if defined(BOOST_WINDOWS_API)
#define BOOST_PROCESS_V2_WINDOWS 1 #define BOOST_PROCESS_V2_WINDOWS 1
// Windows: suppress definition of "min" and "max" macros.
#if !defined(NOMINMAX)
# define NOMINMAX 1
#endif
#endif #endif
@@ -94,6 +81,11 @@
#define BOOST_PROCESS_V2_END_NAMESPACE } } } #define BOOST_PROCESS_V2_END_NAMESPACE } } }
#define BOOST_PROCESS_V2_NAMESPACE boost::process::v2 #define BOOST_PROCESS_V2_NAMESPACE boost::process::v2
namespace boost { namespace asio {} }
BOOST_PROCESS_V2_BEGIN_NAMESPACE
namespace net = ::boost::asio;
BOOST_PROCESS_V2_END_NAMESPACE
#endif #endif
BOOST_PROCESS_V2_BEGIN_NAMESPACE BOOST_PROCESS_V2_BEGIN_NAMESPACE
@@ -108,9 +100,6 @@ namespace filesystem = std::filesystem;
using std::quoted; using std::quoted;
using std::optional; using std::optional;
#define BOOST_PROCESS_V2_RETURN_EC(ev) \
return ::BOOST_PROCESS_V2_NAMESPACE::error_code(ev, ::BOOST_PROCESS_V2_NAMESPACE::system_category()); \
#define BOOST_PROCESS_V2_ASSIGN_EC(ec, ...) ec.assign(__VA_ARGS__); #define BOOST_PROCESS_V2_ASSIGN_EC(ec, ...) ec.assign(__VA_ARGS__);
#define BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) \ #define BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) \
ec.assign(::BOOST_PROCESS_V2_NAMESPACE::detail::get_last_error()); \ ec.assign(::BOOST_PROCESS_V2_NAMESPACE::detail::get_last_error()); \
@@ -131,31 +120,29 @@ namespace filesystem = std::filesystem;
namespace filesystem = boost::filesystem; namespace filesystem = boost::filesystem;
#endif #endif
#define BOOST_PROCESS_V2_RETURN_EC(ev) \
{ \
static constexpr auto loc##__LINE__((BOOST_CURRENT_LOCATION)); \
return ::BOOST_PROCESS_V2_NAMESPACE::error_code(ev, ::BOOST_PROCESS_V2_NAMESPACE::system_category(), &loc##__LINE__); \
}
#define BOOST_PROCESS_V2_ASSIGN_EC(ec, ...) \ #define BOOST_PROCESS_V2_ASSIGN_EC(ec, ...) \
do \
{ \ { \
static constexpr auto loc##__LINE__((BOOST_CURRENT_LOCATION)); \ static constexpr auto loc##__LINE__((BOOST_CURRENT_LOCATION)); \
ec.assign(__VA_ARGS__, &loc##__LINE__); \ ec.assign(__VA_ARGS__, &loc##__LINE__); \
} } \
while (false)
#define BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) \ #define BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) \
do \
{ \ { \
static constexpr auto loc##__LINE__((BOOST_CURRENT_LOCATION)); \ static constexpr auto loc##__LINE__((BOOST_CURRENT_LOCATION)); \
ec.assign(::BOOST_PROCESS_V2_NAMESPACE::detail::get_last_error(), &loc##__LINE__); \ ec.assign(::BOOST_PROCESS_V2_NAMESPACE::detail::get_last_error(), &loc##__LINE__); \
} } \
while (false)
#endif #endif
BOOST_PROCESS_V2_END_NAMESPACE BOOST_PROCESS_V2_END_NAMESPACE
#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_PROCESS_V2_DYN_LINK) #if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_PROCESS_DYN_LINK)
#if defined(BOOST_PROCESS_V2_SOURCE) #if defined(BOOST_PROCESS_SOURCE)
#define BOOST_PROCESS_V2_DECL BOOST_SYMBOL_EXPORT #define BOOST_PROCESS_V2_DECL BOOST_SYMBOL_EXPORT
#else #else
#define BOOST_PROCESS_V2_DECL BOOST_SYMBOL_IMPORT #define BOOST_PROCESS_V2_DECL BOOST_SYMBOL_IMPORT

View File

@@ -69,7 +69,12 @@ BOOST_PROCESS_V2_DECL native_iterator next(native_handle_type nh);
BOOST_PROCESS_V2_DECL native_iterator find_end(native_handle_type nh); BOOST_PROCESS_V2_DECL native_iterator find_end(native_handle_type nh);
inline const char_type * dereference(native_iterator iterator) {return *iterator;} inline const char_type * dereference(native_iterator iterator) {return *iterator;}
BOOST_PROCESS_V2_DECL bool is_executable(const filesystem::path & pth, error_code & ec); BOOST_PROCESS_V2_DECL bool has_x_access(const char * pth);
inline bool is_executable(const filesystem::path & pth, error_code & ec)
{
return filesystem::is_regular_file(pth, ec) && has_x_access(pth.c_str());
}
} }

View File

@@ -203,7 +203,15 @@ struct native_handle_deleter
inline const char_type * dereference(native_iterator iterator) {return iterator;} inline const char_type * dereference(native_iterator iterator) {return iterator;}
BOOST_PROCESS_V2_DECL native_iterator next(native_iterator nh); BOOST_PROCESS_V2_DECL native_iterator next(native_iterator nh);
BOOST_PROCESS_V2_DECL native_iterator find_end(native_handle_type nh); BOOST_PROCESS_V2_DECL native_iterator find_end(native_handle_type nh);
BOOST_PROCESS_V2_DECL bool is_executable(const filesystem::path & pth, error_code & ec);
BOOST_PROCESS_V2_DECL bool is_exec_type(const wchar_t * pth);
inline bool is_executable(const filesystem::path & pth, error_code & ec)
{
return filesystem::is_regular_file(pth, ec) && is_exec_type(pth.c_str());
}
} }
} }

View File

@@ -34,7 +34,7 @@ BOOST_PROCESS_V2_BEGIN_NAMESPACE
namespace detail namespace detail
{ {
template<typename Executor = BOOST_PROCESS_V2_ASIO_NAMESPACE::any_io_executor> template<typename Executor = net::any_io_executor>
struct basic_process_handle_fd struct basic_process_handle_fd
{ {
using native_handle_type = int; using native_handle_type = int;
@@ -56,7 +56,7 @@ struct basic_process_handle_fd
basic_process_handle_fd(ExecutionContext &context, basic_process_handle_fd(ExecutionContext &context,
typename std::enable_if< typename std::enable_if<
std::is_convertible<ExecutionContext &, std::is_convertible<ExecutionContext &,
BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context &>::value>::type * = nullptr) net::execution_context &>::value>::type * = nullptr)
: pid_(-1), descriptor_(context) : pid_(-1), descriptor_(context)
{ {
} }
@@ -275,35 +275,27 @@ struct basic_process_handle_fd
return pid_ != -1; return pid_ != -1;
} }
template<BOOST_PROCESS_V2_COMPLETION_TOKEN_FOR(void(error_code, native_exit_code_type))
WaitHandler BOOST_PROCESS_V2_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_PROCESS_V2_INITFN_AUTO_RESULT_TYPE(WaitHandler, void (error_code, native_exit_code_type))
async_wait(WaitHandler &&handler BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{
return BOOST_PROCESS_V2_ASIO_NAMESPACE::async_compose<WaitHandler, void(error_code, native_exit_code_type)>(
async_wait_op_{descriptor_, pid_}, handler, descriptor_);
}
private: private:
template<typename> template<typename>
friend friend
struct basic_process_handle_fd; struct basic_process_handle_fd;
pid_type pid_ = -1; pid_type pid_ = -1;
BOOST_PROCESS_V2_ASIO_NAMESPACE::posix::basic_stream_descriptor<Executor> descriptor_; net::posix::basic_stream_descriptor<Executor> descriptor_;
struct async_wait_op_ struct async_wait_op_
{ {
BOOST_PROCESS_V2_ASIO_NAMESPACE::posix::basic_descriptor<Executor> &descriptor; net::posix::basic_descriptor<Executor> &descriptor;
pid_type pid_; pid_type pid_;
template<typename Self> template<typename Self>
void operator()(Self &&self) void operator()(Self &&self)
{ {
self.reset_cancellation_state(asio::enable_total_cancellation());
error_code ec; error_code ec;
native_exit_code_type exit_code{}; native_exit_code_type exit_code{};
int wait_res = -1; int wait_res = -1;
if (pid_ <= 0) // error, complete early if (pid_ <= 0) // error, complete early
ec = BOOST_PROCESS_V2_ASIO_NAMESPACE::error::bad_descriptor; ec = net::error::bad_descriptor;
else else
{ {
wait_res = ::waitpid(pid_, &exit_code, WNOHANG); wait_res = ::waitpid(pid_, &exit_code, WNOHANG);
@@ -314,8 +306,7 @@ struct basic_process_handle_fd
if (!ec && (wait_res == 0)) if (!ec && (wait_res == 0))
{ {
descriptor.async_wait( descriptor.async_wait(net::posix::descriptor_base::wait_read, std::move(self));
BOOST_PROCESS_V2_ASIO_NAMESPACE::posix::descriptor_base::wait_read, std::move(self));
return; return;
} }
@@ -330,8 +321,7 @@ struct basic_process_handle_fd
self.complete(ec, code); self.complete(ec, code);
} }
}; };
BOOST_PROCESS_V2_ASIO_NAMESPACE::post(descriptor.get_executor(), net::post(descriptor.get_executor(), completer{ec, exit_code, std::move(self)});
completer{ec, exit_code, std::move(self)});
} }
@@ -345,6 +335,18 @@ struct basic_process_handle_fd
std::move(self).complete(ec, exit_code); std::move(self).complete(ec, exit_code);
} }
}; };
public:
template<BOOST_PROCESS_V2_COMPLETION_TOKEN_FOR(void(error_code, native_exit_code_type))
WaitHandler = net::default_completion_token_t<executor_type>>
auto async_wait(WaitHandler &&handler = net::default_completion_token_t<executor_type>())
-> decltype(net::async_compose<WaitHandler, void(error_code, native_exit_code_type)>(
async_wait_op_{descriptor_, pid_}, handler, descriptor_))
{
return net::async_compose<WaitHandler, void(error_code, native_exit_code_type)>(
async_wait_op_{descriptor_, pid_}, handler, descriptor_);
}
}; };
} }

View File

@@ -37,7 +37,7 @@ BOOST_PROCESS_V2_BEGIN_NAMESPACE
namespace detail namespace detail
{ {
template<typename Executor = BOOST_PROCESS_V2_ASIO_NAMESPACE::any_io_executor> template<typename Executor = net::any_io_executor>
struct basic_process_handle_fd_or_signal struct basic_process_handle_fd_or_signal
{ {
using native_handle_type = int; using native_handle_type = int;
@@ -59,7 +59,7 @@ struct basic_process_handle_fd_or_signal
basic_process_handle_fd_or_signal(ExecutionContext &context, basic_process_handle_fd_or_signal(ExecutionContext &context,
typename std::enable_if< typename std::enable_if<
std::is_convertible<ExecutionContext &, std::is_convertible<ExecutionContext &,
BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context &>::value net::execution_context &>::value
>::type * = nullptr) >::type * = nullptr)
: pid_(-1), descriptor_(context) : pid_(-1), descriptor_(context)
{ {
@@ -70,7 +70,7 @@ struct basic_process_handle_fd_or_signal
pid_type pid, pid_type pid,
typename std::enable_if< typename std::enable_if<
std::is_convertible<ExecutionContext &, std::is_convertible<ExecutionContext &,
BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context &>::value net::execution_context &>::value
>::type * = nullptr) >::type * = nullptr)
: pid_(pid), descriptor_(context) : pid_(pid), descriptor_(context)
{ {
@@ -81,7 +81,7 @@ struct basic_process_handle_fd_or_signal
pid_type pid, native_handle_type process_handle, pid_type pid, native_handle_type process_handle,
typename std::enable_if< typename std::enable_if<
std::is_convertible<ExecutionContext &, std::is_convertible<ExecutionContext &,
BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context &>::value net::execution_context &>::value
>::type * = nullptr) >::type * = nullptr)
: pid_(pid), descriptor_(context, process_handle) : pid_(pid), descriptor_(context, process_handle)
{ {
@@ -305,37 +305,35 @@ struct basic_process_handle_fd_or_signal
return pid_ != -1; return pid_ != -1;
} }
template<BOOST_PROCESS_V2_COMPLETION_TOKEN_FOR(void(error_code, int))
WaitHandler BOOST_PROCESS_V2_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_PROCESS_V2_INITFN_AUTO_RESULT_TYPE(WaitHandler, void (error_code, native_exit_code_type))
async_wait(WaitHandler &&handler BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{
return BOOST_PROCESS_V2_ASIO_NAMESPACE::async_compose<WaitHandler, void(error_code, native_exit_code_type)>(
async_wait_op_{descriptor_, signal_set_, pid_}, handler, descriptor_);
}
private: private:
template<typename> template<typename>
friend friend
struct basic_process_handle_fd_or_signal; struct basic_process_handle_fd_or_signal;
pid_type pid_ = -1; pid_type pid_ = -1;
BOOST_PROCESS_V2_ASIO_NAMESPACE::posix::basic_stream_descriptor<Executor> descriptor_; net::posix::basic_stream_descriptor<Executor> descriptor_;
BOOST_PROCESS_V2_ASIO_NAMESPACE::basic_signal_set<Executor> signal_set_{descriptor_.get_executor(), SIGCHLD}; net::basic_signal_set<Executor> signal_set_{descriptor_.get_executor(), SIGCHLD};
struct async_wait_op_ struct async_wait_op_
{ {
BOOST_PROCESS_V2_ASIO_NAMESPACE::posix::basic_descriptor<Executor> &descriptor; net::posix::basic_descriptor<Executor> &descriptor;
BOOST_PROCESS_V2_ASIO_NAMESPACE::basic_signal_set<Executor> &handle; net::basic_signal_set<Executor> &handle;
pid_type pid_; pid_type pid_;
bool needs_post = true; bool needs_post = true;
template<typename Self> template<typename Self>
void operator()(Self &&self, error_code ec = {}, int = 0) void operator()(Self && self)
{
self.reset_cancellation_state(asio::enable_total_cancellation());
(*this)(std::move(self), error_code{});
}
template<typename Self>
void operator()(Self &&self, error_code ec, int = 0)
{ {
native_exit_code_type exit_code{}; native_exit_code_type exit_code{};
int wait_res = -1; int wait_res = -1;
if (pid_ <= 0) // error, complete early if (pid_ <= 0) // error, complete early
ec = BOOST_PROCESS_V2_ASIO_NAMESPACE::error::bad_descriptor; ec = net::error::bad_descriptor;
else else
{ {
wait_res = ::waitpid(pid_, &exit_code, WNOHANG); wait_res = ::waitpid(pid_, &exit_code, WNOHANG);
@@ -348,7 +346,7 @@ struct basic_process_handle_fd_or_signal
needs_post = false; needs_post = false;
if (descriptor.is_open()) if (descriptor.is_open())
descriptor.async_wait( descriptor.async_wait(
BOOST_PROCESS_V2_ASIO_NAMESPACE::posix::descriptor_base::wait_read, net::posix::descriptor_base::wait_read,
std::move(self)); std::move(self));
else else
handle.async_wait(std::move(self)); handle.async_wait(std::move(self));
@@ -370,12 +368,22 @@ struct basic_process_handle_fd_or_signal
const auto exec = self.get_executor(); const auto exec = self.get_executor();
completer cpl{ec, exit_code, std::move(self)}; completer cpl{ec, exit_code, std::move(self)};
if (needs_post) if (needs_post)
BOOST_PROCESS_V2_ASIO_NAMESPACE::post(exec, std::move(cpl)); net::post(exec, std::move(cpl));
else else
BOOST_PROCESS_V2_ASIO_NAMESPACE::dispatch(exec, std::move(cpl)); net::dispatch(exec, std::move(cpl));
} }
}; };
public:
template<BOOST_PROCESS_V2_COMPLETION_TOKEN_FOR(void(error_code, int))
WaitHandler = net::default_completion_token_t<executor_type>>
auto async_wait(WaitHandler &&handler = net::default_completion_token_t<executor_type>())
-> decltype(net::async_compose<WaitHandler, void(error_code, native_exit_code_type)>(
async_wait_op_{descriptor_, signal_set_, pid_}, handler, descriptor_))
{
return net::async_compose<WaitHandler, void(error_code, native_exit_code_type)>(
async_wait_op_{descriptor_, signal_set_, pid_}, handler, descriptor_);
}
}; };
} }

View File

@@ -34,7 +34,7 @@ BOOST_PROCESS_V2_BEGIN_NAMESPACE
namespace detail namespace detail
{ {
template<typename Executor = BOOST_PROCESS_V2_ASIO_NAMESPACE::any_io_executor> template<typename Executor = net::any_io_executor>
struct basic_process_handle_signal struct basic_process_handle_signal
{ {
struct native_handle_type struct native_handle_type
@@ -61,7 +61,7 @@ struct basic_process_handle_signal
basic_process_handle_signal(ExecutionContext &context, basic_process_handle_signal(ExecutionContext &context,
typename std::enable_if< typename std::enable_if<
std::is_convertible<ExecutionContext &, std::is_convertible<ExecutionContext &,
BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context &>::value net::execution_context &>::value
>::type * = nullptr) >::type * = nullptr)
: pid_(-1), signal_set_(context, SIGCHLD) : pid_(-1), signal_set_(context, SIGCHLD)
{ {
@@ -87,7 +87,7 @@ struct basic_process_handle_signal
{ {
pid_ = handle.id(); pid_ = handle.id();
signal_set_.~basic_signal_set(); signal_set_.~basic_signal_set();
using ss = BOOST_PROCESS_V2_ASIO_NAMESPACE::basic_signal_set<Executor>; using ss = net::basic_signal_set<Executor>;
new (&signal_set_) ss(handle.get_executor(), SIGCHLD); new (&signal_set_) ss(handle.get_executor(), SIGCHLD);
handle.pid_ = -1; handle.pid_ = -1;
return *this; return *this;
@@ -269,29 +269,21 @@ struct basic_process_handle_signal
return pid_ != -1; return pid_ != -1;
} }
template<BOOST_PROCESS_V2_COMPLETION_TOKEN_FOR(void(error_code, int))
WaitHandler BOOST_PROCESS_V2_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_PROCESS_V2_INITFN_AUTO_RESULT_TYPE(WaitHandler, void (error_code, native_exit_code_type))
async_wait(WaitHandler &&handler BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{
return BOOST_PROCESS_V2_ASIO_NAMESPACE::async_compose<WaitHandler, void(error_code, native_exit_code_type)>(
async_wait_op_{signal_set_, pid_}, handler, signal_set_);
}
private: private:
template<typename> template<typename>
friend struct basic_process_handle_signal; friend struct basic_process_handle_signal;
pid_type pid_ = -1; pid_type pid_ = -1;
BOOST_PROCESS_V2_ASIO_NAMESPACE::basic_signal_set<Executor> signal_set_; net::basic_signal_set<Executor> signal_set_;
struct async_wait_op_ struct async_wait_op_
{ {
BOOST_PROCESS_V2_ASIO_NAMESPACE::basic_signal_set<Executor> &handle; net::basic_signal_set<Executor> &handle;
pid_type pid_; pid_type pid_;
template<typename Self> template<typename Self>
void operator()(Self &&self) void operator()(Self &&self)
{ {
self.reset_cancellation_state(asio::enable_total_cancellation());
handle.async_wait(std::move(self)); handle.async_wait(std::move(self));
handle.cancel(); handle.cancel();
// we cancel so we end up on the signal-sets executor // we cancel so we end up on the signal-sets executor
@@ -300,16 +292,16 @@ struct basic_process_handle_signal
template<typename Self> template<typename Self>
void operator()(Self &&self, error_code ec, int sig) void operator()(Self &&self, error_code ec, int sig)
{ {
if (ec == BOOST_PROCESS_V2_ASIO_NAMESPACE::error::operation_aborted && if (ec == net::error::operation_aborted &&
self.get_cancellation_state().cancelled() self.get_cancellation_state().cancelled()
== BOOST_PROCESS_V2_ASIO_NAMESPACE::cancellation_type::none) == net::cancellation_type::none)
ec.clear(); ec.clear();
native_exit_code_type exit_code = -1; native_exit_code_type exit_code = -1;
int wait_res = -1; int wait_res = -1;
if (pid_ <= 0) // error, complete early if (pid_ <= 0) // error, complete early
ec = BOOST_PROCESS_V2_ASIO_NAMESPACE::error::bad_descriptor; ec = net::error::bad_descriptor;
else if (!ec) else if (!ec)
{ {
wait_res = ::waitpid(pid_, &exit_code, WNOHANG); wait_res = ::waitpid(pid_, &exit_code, WNOHANG);
@@ -336,9 +328,19 @@ struct basic_process_handle_signal
}; };
const auto exec = self.get_executor(); const auto exec = self.get_executor();
BOOST_PROCESS_V2_ASIO_NAMESPACE::dispatch(exec, completer{ec, exit_code, std::move(self)}); net::dispatch(exec, completer{ec, exit_code, std::move(self)});
} }
}; };
public:
template<BOOST_PROCESS_V2_COMPLETION_TOKEN_FOR(void(error_code, int))
WaitHandler = net::default_completion_token_t<executor_type>>
auto async_wait(WaitHandler &&handler = net::default_completion_token_t<executor_type>())
-> decltype(net::async_compose<WaitHandler, void(error_code, native_exit_code_type)>(
async_wait_op_{signal_set_, pid_}, handler, signal_set_))
{
return net::async_compose<WaitHandler, void(error_code, native_exit_code_type)>(
async_wait_op_{signal_set_, pid_}, handler, signal_set_);
}
}; };
} }

View File

@@ -38,10 +38,10 @@ BOOST_PROCESS_V2_DECL void terminate_(void * handle, error_code & ec, native_exi
BOOST_PROCESS_V2_DECL void request_exit_(pid_type pid_, error_code & ec); BOOST_PROCESS_V2_DECL void request_exit_(pid_type pid_, error_code & ec);
BOOST_PROCESS_V2_DECL void check_running_(void* handle, error_code & ec, native_exit_code_type & exit_status); BOOST_PROCESS_V2_DECL void check_running_(void* handle, error_code & ec, native_exit_code_type & exit_status);
template<typename Executor = BOOST_PROCESS_V2_ASIO_NAMESPACE::any_io_executor> template<typename Executor = net::any_io_executor>
struct basic_process_handle_win struct basic_process_handle_win
{ {
typedef BOOST_PROCESS_V2_ASIO_NAMESPACE::windows::basic_object_handle<Executor> handle_type; typedef net::windows::basic_object_handle<Executor> handle_type;
typedef typename handle_type::native_handle_type native_handle_type; typedef typename handle_type::native_handle_type native_handle_type;
typedef Executor executor_type; typedef Executor executor_type;
@@ -61,7 +61,7 @@ struct basic_process_handle_win
basic_process_handle_win(ExecutionContext &context, basic_process_handle_win(ExecutionContext &context,
typename std::enable_if< typename std::enable_if<
std::is_convertible<ExecutionContext &, std::is_convertible<ExecutionContext &,
BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context &>::value net::execution_context &>::value
>::type = 0) >::type = 0)
: pid_(0), handle_(context) : pid_(0), handle_(context)
{ {
@@ -266,15 +266,6 @@ struct basic_process_handle_win
return handle_.is_open(); return handle_.is_open();
} }
template<BOOST_PROCESS_V2_COMPLETION_TOKEN_FOR(void(error_code, native_exit_code_type))
WaitHandler BOOST_PROCESS_V2_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_PROCESS_V2_INITFN_AUTO_RESULT_TYPE(WaitHandler, void (error_code, native_exit_code_type))
async_wait(WaitHandler &&handler BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{
return BOOST_PROCESS_V2_ASIO_NAMESPACE::async_compose<WaitHandler, void(error_code, native_exit_code_type)>(
async_wait_op_{handle_}, handler, handle_
);
}
template<typename> template<typename>
friend struct basic_process_handle_win; friend struct basic_process_handle_win;
private: private:
@@ -288,6 +279,17 @@ struct basic_process_handle_win
template<typename Self> template<typename Self>
void operator()(Self &&self) void operator()(Self &&self)
{ {
self.reset_cancellation_state(asio::enable_total_cancellation());
auto sl = self.get_cancellation_state().slot();
auto & h = handle;
if (sl.is_connected())
sl.assign(
[&h](asio::cancellation_type ct)
{
boost::system::error_code ec;
h.cancel(ec);
});
handle.async_wait(std::move(self)); handle.async_wait(std::move(self));
} }
@@ -295,11 +297,25 @@ struct basic_process_handle_win
void operator()(Self &&self, error_code ec) void operator()(Self &&self, error_code ec)
{ {
native_exit_code_type exit_code{}; native_exit_code_type exit_code{};
if (ec == asio::error::operation_aborted && !self.get_cancellation_state().cancelled())
return handle.async_wait(std::move(self));
if (!ec) if (!ec)
detail::get_exit_code_(handle.native_handle(), exit_code, ec); detail::get_exit_code_(handle.native_handle(), exit_code, ec);
std::move(self).complete(ec, exit_code); std::move(self).complete(ec, exit_code);
} }
}; };
public:
template<BOOST_PROCESS_V2_COMPLETION_TOKEN_FOR(void(error_code, native_exit_code_type))
WaitHandler = net::default_completion_token_t<executor_type>>
auto async_wait(WaitHandler &&handler = default_completion_token_t<executor_type>())
-> decltype(net::async_compose<WaitHandler, void(error_code, native_exit_code_type)>(
async_wait_op_{handle_}, handler, handle_))
{
return net::async_compose<WaitHandler, void(error_code, native_exit_code_type)>(
async_wait_op_{handle_}, handler, handle_
);
}
}; };
extern template struct basic_process_handle_win<>; extern template struct basic_process_handle_win<>;

View File

@@ -24,7 +24,6 @@ BOOST_PROCESS_V2_DECL std::size_t convert_to_wide(const char * in, std::size_
template<typename CharOut, typename Traits = std::char_traits<CharOut>, template<typename CharOut, typename Traits = std::char_traits<CharOut>,
typename Allocator = std::allocator<CharOut>, typename CharIn, typename Allocator = std::allocator<CharOut>, typename CharIn,
typename = typename std::enable_if<std::is_same<CharOut, CharIn>::value>::type> typename = typename std::enable_if<std::is_same<CharOut, CharIn>::value>::type>
BOOST_PROCESS_V2_DECL
std::basic_string<CharOut, Traits, Allocator> conv_string( std::basic_string<CharOut, Traits, Allocator> conv_string(
const CharIn * data, std::size_t size, const CharIn * data, std::size_t size,
const Allocator allocator = Allocator{}) const Allocator allocator = Allocator{})
@@ -36,7 +35,6 @@ std::basic_string<CharOut, Traits, Allocator> conv_string(
template<typename CharOut, typename Traits = std::char_traits<CharOut>, template<typename CharOut, typename Traits = std::char_traits<CharOut>,
typename Allocator = std::allocator<CharOut>, typename Allocator = std::allocator<CharOut>,
typename = typename std::enable_if<std::is_same<CharOut, char>::value>::type> typename = typename std::enable_if<std::is_same<CharOut, char>::value>::type>
BOOST_PROCESS_V2_DECL
std::basic_string<CharOut, Traits, Allocator> conv_string( std::basic_string<CharOut, Traits, Allocator> conv_string(
const wchar_t * data, std::size_t size, const wchar_t * data, std::size_t size,
const Allocator allocator = Allocator{}) const Allocator allocator = Allocator{})
@@ -60,7 +58,6 @@ std::basic_string<CharOut, Traits, Allocator> conv_string(
template<typename CharOut, typename Traits = std::char_traits<CharOut>, template<typename CharOut, typename Traits = std::char_traits<CharOut>,
typename Allocator = std::allocator<CharOut>, typename Allocator = std::allocator<CharOut>,
typename = typename std::enable_if<std::is_same<CharOut, wchar_t>::value>::type> typename = typename std::enable_if<std::is_same<CharOut, wchar_t>::value>::type>
BOOST_PROCESS_V2_DECL
std::basic_string<CharOut, Traits, Allocator> conv_string( std::basic_string<CharOut, Traits, Allocator> conv_string(
const char * data, std::size_t size, const char * data, std::size_t size,
const Allocator allocator = Allocator{}) const Allocator allocator = Allocator{})

View File

@@ -764,7 +764,7 @@ struct value
value& operator=( const Source& source ) value& operator=( const Source& source )
{ {
value_ = BOOST_PROCESS_V2_NAMESPACE::detail::conv_string<char_type, traits_type>( value_ = BOOST_PROCESS_V2_NAMESPACE::detail::conv_string<char_type, traits_type>(
source.data(), source.size); source.data(), source.size());
return *this; return *this;
} }

View File

@@ -47,7 +47,7 @@ struct execute_op
struct cancel struct cancel
{ {
using cancellation_type = BOOST_PROCESS_V2_ASIO_NAMESPACE::cancellation_type; using cancellation_type = net::cancellation_type;
basic_process<Executor> * proc; basic_process<Executor> * proc;
cancel(basic_process<Executor> * proc) : proc(proc) {} cancel(basic_process<Executor> * proc) : proc(proc) {}
@@ -66,15 +66,15 @@ struct execute_op
template<typename Self> template<typename Self>
void operator()(Self && self) void operator()(Self && self)
{ {
self.reset_cancellation_state(BOOST_PROCESS_V2_ASIO_NAMESPACE::enable_total_cancellation()); self.reset_cancellation_state(net::enable_total_cancellation());
BOOST_PROCESS_V2_ASIO_NAMESPACE::cancellation_slot s = self.get_cancellation_state().slot(); net::cancellation_slot s = self.get_cancellation_state().slot();
if (s.is_connected()) if (s.is_connected())
s.emplace<cancel>(proc.get()); s.emplace<cancel>(proc.get());
auto pro_ = proc.get(); auto pro_ = proc.get();
pro_->async_wait( pro_->async_wait(
BOOST_PROCESS_V2_ASIO_NAMESPACE::bind_cancellation_slot( net::bind_cancellation_slot(
BOOST_PROCESS_V2_ASIO_NAMESPACE::cancellation_slot(), net::cancellation_slot(),
std::move(self))); std::move(self)));
} }
@@ -101,17 +101,18 @@ struct execute_op
* It is to note that `async_execute` will us the lowest selected cancellation * It is to note that `async_execute` will us the lowest selected cancellation
* type. A subprocess might ignore anything not terminal. * type. A subprocess might ignore anything not terminal.
*/ */
template<typename Executor = BOOST_PROCESS_V2_ASIO_NAMESPACE::any_io_executor, template<typename Executor = net::any_io_executor,
BOOST_PROCESS_V2_COMPLETION_TOKEN_FOR(void (error_code, int)) BOOST_PROCESS_V2_COMPLETION_TOKEN_FOR(void (error_code, int))
WaitHandler BOOST_PROCESS_V2_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)> WaitHandler = net::default_completion_token_t<Executor>>
inline inline
BOOST_PROCESS_V2_INITFN_AUTO_RESULT_TYPE(WaitHandler, void (error_code, int)) auto async_execute(basic_process<Executor> proc,
async_execute(basic_process<Executor> proc, WaitHandler && handler = net::default_completion_token_t<Executor>())
WaitHandler && handler BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(Executor)) -> decltype(net::async_compose<WaitHandler, void(error_code, int)>(
detail::execute_op<Executor>{nullptr}, handler, std::declval<Executor>()))
{ {
std::unique_ptr<basic_process<Executor>> pro_(new basic_process<Executor>(std::move(proc))); std::unique_ptr<basic_process<Executor>> pro_(new basic_process<Executor>(std::move(proc)));
auto exec = pro_->get_executor(); auto exec = pro_->get_executor();
return BOOST_PROCESS_V2_ASIO_NAMESPACE::async_compose<WaitHandler, void(error_code, int)>( return net::async_compose<WaitHandler, void(error_code, int)>(
detail::execute_op<Executor>{std::move(pro_)}, handler, exec); detail::execute_op<Executor>{std::move(pro_)}, handler, exec);
} }

View File

@@ -8,6 +8,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <memory>
#include <boost/process/v2/detail/config.hpp> #include <boost/process/v2/detail/config.hpp>
#include <boost/process/v2/detail/throw_error.hpp> #include <boost/process/v2/detail/throw_error.hpp>
@@ -36,7 +37,7 @@ BOOST_PROCESS_V2_DECL shell cmd(HANDLE handle);
#endif #endif
template<typename Executor> template<typename Executor>
BOOST_PROCESS_V2_DECL shell cmd(basic_process_handle<Executor> & handle, error_code & ec) inline shell cmd(basic_process_handle<Executor> & handle, error_code & ec)
{ {
#if defined(BOOST_PROCESS_V2_WINDOWS) #if defined(BOOST_PROCESS_V2_WINDOWS)
return cmd(handle.native_handle(), ec); return cmd(handle.native_handle(), ec);
@@ -46,7 +47,7 @@ BOOST_PROCESS_V2_DECL shell cmd(basic_process_handle<Executor> & handle, error_c
} }
template<typename Executor> template<typename Executor>
BOOST_PROCESS_V2_DECL shell cmd(basic_process_handle<Executor> & handle) inline shell cmd(basic_process_handle<Executor> & handle)
{ {
#if defined(BOOST_PROCESS_V2_WINDOWS) #if defined(BOOST_PROCESS_V2_WINDOWS)
return cmd(handle.native_handle()); return cmd(handle.native_handle());

View File

@@ -27,7 +27,7 @@ BOOST_PROCESS_V2_DECL filesystem::path cwd(pid_type pid, error_code & ec);
BOOST_PROCESS_V2_DECL filesystem::path cwd(pid_type pid); BOOST_PROCESS_V2_DECL filesystem::path cwd(pid_type pid);
template<typename Executor> template<typename Executor>
BOOST_PROCESS_V2_DECL filesystem::path cwd(basic_process_handle<Executor> & handle, error_code & ec) inline filesystem::path cwd(basic_process_handle<Executor> & handle, error_code & ec)
{ {
#if defined(BOOST_PROCESS_V2_WINDOWS) #if defined(BOOST_PROCESS_V2_WINDOWS)
return cwd(handle.native_handle(), ec); return cwd(handle.native_handle(), ec);
@@ -37,7 +37,7 @@ BOOST_PROCESS_V2_DECL filesystem::path cwd(basic_process_handle<Executor> & hand
} }
template<typename Executor> template<typename Executor>
BOOST_PROCESS_V2_DECL filesystem::path cwd(basic_process_handle<Executor> & handle) inline filesystem::path cwd(basic_process_handle<Executor> & handle)
{ {
#if defined(BOOST_PROCESS_V2_WINDOWS) #if defined(BOOST_PROCESS_V2_WINDOWS)
return cwd(handle.native_handle()); return cwd(handle.native_handle());

View File

@@ -8,6 +8,7 @@
#define BOOST_PROCESS_V2_ENV_HPP #define BOOST_PROCESS_V2_ENV_HPP
#include <string> #include <string>
#include <vector> #include <vector>
#include <memory>
#include <boost/process/v2/detail/config.hpp> #include <boost/process/v2/detail/config.hpp>
#include <boost/process/v2/detail/throw_error.hpp> #include <boost/process/v2/detail/throw_error.hpp>
@@ -26,9 +27,6 @@ namespace ext
#if defined(BOOST_PROCESS_V2_WINDOWS) #if defined(BOOST_PROCESS_V2_WINDOWS)
using native_env_handle_type = wchar_t *; using native_env_handle_type = wchar_t *;
using native_env_iterator = wchar_t *; using native_env_iterator = wchar_t *;
#elif defined(__FreeBSD__)
using native_env_handle_type = char **;
using native_env_iterator = char **;
#else #else
using native_env_handle_type = char *; using native_env_handle_type = char *;
using native_env_iterator = char *; using native_env_iterator = char *;
@@ -120,7 +118,7 @@ BOOST_PROCESS_V2_DECL env_view env(pid_type pid, error_code & ec);
BOOST_PROCESS_V2_DECL env_view env(pid_type pid); BOOST_PROCESS_V2_DECL env_view env(pid_type pid);
template<typename Executor> template<typename Executor>
BOOST_PROCESS_V2_DECL env_view env(basic_process_handle<Executor> & handle, error_code & ec) inline env_view env(basic_process_handle<Executor> & handle, error_code & ec)
{ {
#if defined(BOOST_PROCESS_V2_WINDOWS) #if defined(BOOST_PROCESS_V2_WINDOWS)
return env(handle.native_handle(), ec); return env(handle.native_handle(), ec);
@@ -130,7 +128,7 @@ BOOST_PROCESS_V2_DECL env_view env(basic_process_handle<Executor> & handle, erro
} }
template<typename Executor> template<typename Executor>
BOOST_PROCESS_V2_DECL env_view env(basic_process_handle<Executor> & handle) inline env_view env(basic_process_handle<Executor> & handle)
{ {
#if defined(BOOST_PROCESS_V2_WINDOWS) #if defined(BOOST_PROCESS_V2_WINDOWS)
return env(handle.native_handle()); return env(handle.native_handle());

View File

@@ -10,6 +10,7 @@
#include <boost/process/v2/detail/throw_error.hpp> #include <boost/process/v2/detail/throw_error.hpp>
#include <vector> #include <vector>
#include <memory>
BOOST_PROCESS_V2_BEGIN_NAMESPACE BOOST_PROCESS_V2_BEGIN_NAMESPACE

View File

@@ -34,7 +34,7 @@ BOOST_PROCESS_V2_BEGIN_NAMESPACE
* *
* Popen can be used as a stream object in other protocols. * Popen can be used as a stream object in other protocols.
*/ */
template<typename Executor = BOOST_PROCESS_V2_ASIO_NAMESPACE::any_io_executor> template<typename Executor = net::any_io_executor>
struct basic_popen : basic_process<Executor> struct basic_popen : basic_process<Executor>
{ {
/// The executor of the process /// The executor of the process
@@ -69,7 +69,7 @@ struct basic_popen : basic_process<Executor>
explicit basic_popen(ExecutionContext & context, explicit basic_popen(ExecutionContext & context,
typename std::enable_if< typename std::enable_if<
is_convertible<ExecutionContext&, is_convertible<ExecutionContext&,
BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context&>::value, void *>::type = nullptr) net::execution_context&>::value, void *>::type = nullptr)
: basic_process<Executor>{context} : basic_process<Executor>{context}
{ {
} }
@@ -148,7 +148,7 @@ struct basic_popen : basic_process<Executor>
ExecutionContext & context, ExecutionContext & context,
typename std::enable_if< typename std::enable_if<
std::is_convertible<ExecutionContext&, std::is_convertible<ExecutionContext&,
BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context&>::value, net::execution_context&>::value,
const filesystem::path&>::type exe, const filesystem::path&>::type exe,
std::initializer_list<string_view> args, std::initializer_list<string_view> args,
Inits&&... inits) Inits&&... inits)
@@ -169,7 +169,7 @@ struct basic_popen : basic_process<Executor>
ExecutionContext & context, ExecutionContext & context,
typename std::enable_if< typename std::enable_if<
std::is_convertible<ExecutionContext&, std::is_convertible<ExecutionContext&,
BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context&>::value, net::execution_context&>::value,
const filesystem::path&>::type exe, const filesystem::path&>::type exe,
std::initializer_list<string_view> args, std::initializer_list<string_view> args,
Inits&&... inits) Inits&&... inits)
@@ -189,7 +189,7 @@ struct basic_popen : basic_process<Executor>
ExecutionContext & context, ExecutionContext & context,
typename std::enable_if< typename std::enable_if<
std::is_convertible<ExecutionContext&, std::is_convertible<ExecutionContext&,
BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context&>::value, net::execution_context&>::value,
const filesystem::path&>::type exe, const filesystem::path&>::type exe,
Args&& args, Inits&&... inits) Args&& args, Inits&&... inits)
: basic_process<Executor>(context) : basic_process<Executor>(context)
@@ -209,7 +209,7 @@ struct basic_popen : basic_process<Executor>
ExecutionContext & context, ExecutionContext & context,
typename std::enable_if< typename std::enable_if<
std::is_convertible<ExecutionContext&, std::is_convertible<ExecutionContext&,
BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context&>::value, net::execution_context&>::value,
const filesystem::path&>::type exe, const filesystem::path&>::type exe,
Args&& args, Inits&&... inits) Args&& args, Inits&&... inits)
: basic_process<Executor>(context) : basic_process<Executor>(context)
@@ -224,9 +224,9 @@ struct basic_popen : basic_process<Executor>
/// The type used for stdin on the parent process side. /// The type used for stdin on the parent process side.
using stdin_type = BOOST_PROCESS_V2_ASIO_NAMESPACE::basic_writable_pipe<Executor>; using stdin_type = net::basic_writable_pipe<Executor>;
/// The type used for stdout on the parent process side. /// The type used for stdout on the parent process side.
using stdout_type = BOOST_PROCESS_V2_ASIO_NAMESPACE::basic_readable_pipe<Executor>; using stdout_type = net::basic_readable_pipe<Executor>;
/// Get the stdin pipe. /// Get the stdin pipe.
stdin_type & get_stdin() {return stdin_; } stdin_type & get_stdin() {return stdin_; }
@@ -336,14 +336,11 @@ struct basic_popen : basic_process<Executor>
* std::vector. * std::vector.
*/ */
template <typename ConstBufferSequence, template <typename ConstBufferSequence,
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code, std::size_t))
std::size_t)) WriteToken WriteToken = net::default_completion_token_t<executor_type>>
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)> auto async_write_some(const ConstBufferSequence& buffers,
BOOST_PROCESS_V2_INITFN_AUTO_RESULT_TYPE(WriteToken, WriteToken && token = net::default_completion_token_t<executor_type>())
void (boost::system::error_code, std::size_t)) -> decltype(std::declval<stdin_type&>().async_write_some(buffers, std::forward<WriteToken>(token)))
async_write_some(const ConstBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(WriteToken) token
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{ {
return stdin_.async_write_some(buffers, std::forward<WriteToken>(token)); return stdin_.async_write_some(buffers, std::forward<WriteToken>(token));
} }
@@ -451,14 +448,12 @@ struct basic_popen : basic_process<Executor>
* std::vector. * std::vector.
*/ */
template <typename MutableBufferSequence, template <typename MutableBufferSequence,
BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code, BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code, std::size_t))
std::size_t)) ReadToken ReadToken = net::default_completion_token_t<executor_type>>
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)> auto async_read_some(const MutableBufferSequence& buffers,
BOOST_PROCESS_V2_INITFN_AUTO_RESULT_TYPE(ReadToken,
void (boost::system::error_code, std::size_t))
async_read_some(const MutableBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(ReadToken) token BOOST_ASIO_MOVE_ARG(ReadToken) token
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) = net::default_completion_token_t<executor_type>())
-> decltype(std::declval<stdout_type&>().async_read_some(buffers, std::forward<ReadToken>(token)))
{ {
return stdout_.async_read_some(buffers, std::forward<ReadToken>(token)); return stdout_.async_read_some(buffers, std::forward<ReadToken>(token));
} }

View File

@@ -29,7 +29,7 @@
#include <unistd.h> #include <unistd.h>
#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__APPLE__) || defined(__MACH__) #if defined(__APPLE__) || defined(__MACH__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
extern "C" { extern char **environ; } extern "C" { extern char **environ; }
#endif #endif
@@ -305,7 +305,7 @@ struct default_launcher
template<typename ExecutionContext, typename Args, typename ... Inits> template<typename ExecutionContext, typename Args, typename ... Inits>
auto operator()(ExecutionContext & context, auto operator()(ExecutionContext & context,
const typename std::enable_if<std::is_convertible< const typename std::enable_if<std::is_convertible<
ExecutionContext&, BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context&>::value, ExecutionContext&, net::execution_context&>::value,
filesystem::path >::type & executable, filesystem::path >::type & executable,
Args && args, Args && args,
Inits && ... inits ) -> basic_process<typename ExecutionContext::executor_type> Inits && ... inits ) -> basic_process<typename ExecutionContext::executor_type>
@@ -324,7 +324,7 @@ struct default_launcher
auto operator()(ExecutionContext & context, auto operator()(ExecutionContext & context,
error_code & ec, error_code & ec,
const typename std::enable_if<std::is_convertible< const typename std::enable_if<std::is_convertible<
ExecutionContext&, BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context&>::value, ExecutionContext&, net::execution_context&>::value,
filesystem::path >::type & executable, filesystem::path >::type & executable,
Args && args, Args && args,
Inits && ... inits ) -> basic_process<typename ExecutionContext::executor_type> Inits && ... inits ) -> basic_process<typename ExecutionContext::executor_type>
@@ -335,8 +335,8 @@ struct default_launcher
template<typename Executor, typename Args, typename ... Inits> template<typename Executor, typename Args, typename ... Inits>
auto operator()(Executor exec, auto operator()(Executor exec,
const typename std::enable_if< const typename std::enable_if<
BOOST_PROCESS_V2_ASIO_NAMESPACE::execution::is_executor<Executor>::value || net::execution::is_executor<Executor>::value ||
BOOST_PROCESS_V2_ASIO_NAMESPACE::is_executor<Executor>::value, net::is_executor<Executor>::value,
filesystem::path >::type & executable, filesystem::path >::type & executable,
Args && args, Args && args,
Inits && ... inits ) -> basic_process<Executor> Inits && ... inits ) -> basic_process<Executor>
@@ -354,8 +354,8 @@ struct default_launcher
auto operator()(Executor exec, auto operator()(Executor exec,
error_code & ec, error_code & ec,
const typename std::enable_if< const typename std::enable_if<
BOOST_PROCESS_V2_ASIO_NAMESPACE::execution::is_executor<Executor>::value || net::execution::is_executor<Executor>::value ||
BOOST_PROCESS_V2_ASIO_NAMESPACE::is_executor<Executor>::value, net::is_executor<Executor>::value,
filesystem::path >::type & executable, filesystem::path >::type & executable,
Args && args, Args && args,
Inits && ... inits ) -> basic_process<Executor> Inits && ... inits ) -> basic_process<Executor>
@@ -365,12 +365,12 @@ struct default_launcher
pipe_guard pg; pipe_guard pg;
if (::pipe(pg.p)) if (::pipe(pg.p))
{ {
BOOST_PROCESS_V2_ASSIGN_EC(ec, errno, system_category()) BOOST_PROCESS_V2_ASSIGN_EC(ec, errno, system_category());
return basic_process<Executor>{exec}; return basic_process<Executor>{exec};
} }
if (::fcntl(pg.p[1], F_SETFD, FD_CLOEXEC)) if (::fcntl(pg.p[1], F_SETFD, FD_CLOEXEC))
{ {
BOOST_PROCESS_V2_ASSIGN_EC(ec, errno, system_category()) BOOST_PROCESS_V2_ASSIGN_EC(ec, errno, system_category());
return basic_process<Executor>{exec}; return basic_process<Executor>{exec};
} }
ec = detail::on_setup(*this, executable, argv, inits ...); ec = detail::on_setup(*this, executable, argv, inits ...);
@@ -381,23 +381,23 @@ struct default_launcher
} }
fd_whitelist.push_back(pg.p[1]); fd_whitelist.push_back(pg.p[1]);
auto & ctx = BOOST_PROCESS_V2_ASIO_NAMESPACE::query( auto & ctx = net::query(
exec, BOOST_PROCESS_V2_ASIO_NAMESPACE::execution::context); exec, net::execution::context);
ctx.notify_fork(BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context::fork_prepare); ctx.notify_fork(net::execution_context::fork_prepare);
pid = ::fork(); pid = ::fork();
if (pid == -1) if (pid == -1)
{ {
ctx.notify_fork(BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context::fork_parent); ctx.notify_fork(net::execution_context::fork_parent);
detail::on_fork_error(*this, executable, argv, ec, inits...); detail::on_fork_error(*this, executable, argv, ec, inits...);
detail::on_error(*this, executable, argv, ec, inits...); detail::on_error(*this, executable, argv, ec, inits...);
BOOST_PROCESS_V2_ASSIGN_EC(ec, errno, system_category()) BOOST_PROCESS_V2_ASSIGN_EC(ec, errno, system_category());
return basic_process<Executor>{exec}; return basic_process<Executor>{exec};
} }
else if (pid == 0) else if (pid == 0)
{ {
::close(pg.p[0]); ::close(pg.p[0]);
ctx.notify_fork(BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context::fork_child); ctx.notify_fork(net::execution_context::fork_child);
ec = detail::on_exec_setup(*this, executable, argv, inits...); ec = detail::on_exec_setup(*this, executable, argv, inits...);
if (!ec) if (!ec)
{ {
@@ -407,13 +407,13 @@ struct default_launcher
::execve(executable.c_str(), const_cast<char * const *>(argv), const_cast<char * const *>(env)); ::execve(executable.c_str(), const_cast<char * const *>(argv), const_cast<char * const *>(env));
ignore_unused(::write(pg.p[1], &errno, sizeof(int))); ignore_unused(::write(pg.p[1], &errno, sizeof(int)));
BOOST_PROCESS_V2_ASSIGN_EC(ec, errno, system_category()) BOOST_PROCESS_V2_ASSIGN_EC(ec, errno, system_category());
detail::on_exec_error(*this, executable, argv, ec, inits...); detail::on_exec_error(*this, executable, argv, ec, inits...);
::exit(EXIT_FAILURE); ::exit(EXIT_FAILURE);
return basic_process<Executor>{exec}; return basic_process<Executor>{exec};
} }
ctx.notify_fork(BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context::fork_parent); ctx.notify_fork(net::execution_context::fork_parent);
::close(pg.p[1]); ::close(pg.p[1]);
pg.p[1] = -1; pg.p[1] = -1;
int child_error{0}; int child_error{0};
@@ -423,12 +423,12 @@ struct default_launcher
int err = errno; int err = errno;
if ((err != EAGAIN) && (err != EINTR)) if ((err != EAGAIN) && (err != EINTR))
{ {
BOOST_PROCESS_V2_ASSIGN_EC(ec, err, system_category()) BOOST_PROCESS_V2_ASSIGN_EC(ec, err, system_category());
break; break;
} }
} }
if (count != 0) if (count != 0)
BOOST_PROCESS_V2_ASSIGN_EC(ec, child_error, system_category()) BOOST_PROCESS_V2_ASSIGN_EC(ec, child_error, system_category());
if (ec) if (ec)
{ {

View File

@@ -20,7 +20,7 @@ struct fork_and_forget_launcher : default_launcher
template<typename ExecutionContext, typename Args, typename ... Inits> template<typename ExecutionContext, typename Args, typename ... Inits>
auto operator()(ExecutionContext & context, auto operator()(ExecutionContext & context,
const typename std::enable_if<is_convertible< const typename std::enable_if<is_convertible<
ExecutionContext&, BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context&>::value, ExecutionContext&, net::execution_context&>::value,
filesystem::path >::type & executable, filesystem::path >::type & executable,
Args && args, Args && args,
Inits && ... inits ) -> basic_process<typename ExecutionContext::executor_type> Inits && ... inits ) -> basic_process<typename ExecutionContext::executor_type>
@@ -39,7 +39,7 @@ struct fork_and_forget_launcher : default_launcher
auto operator()(ExecutionContext & context, auto operator()(ExecutionContext & context,
error_code & ec, error_code & ec,
const typename std::enable_if<is_convertible< const typename std::enable_if<is_convertible<
ExecutionContext&, BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context&>::value, ExecutionContext&, net::execution_context&>::value,
filesystem::path >::type & executable, filesystem::path >::type & executable,
Args && args, Args && args,
Inits && ... inits ) -> basic_process<typename ExecutionContext::executor_type> Inits && ... inits ) -> basic_process<typename ExecutionContext::executor_type>
@@ -50,8 +50,8 @@ struct fork_and_forget_launcher : default_launcher
template<typename Executor, typename Args, typename ... Inits> template<typename Executor, typename Args, typename ... Inits>
auto operator()(Executor exec, auto operator()(Executor exec,
const typename std::enable_if< const typename std::enable_if<
BOOST_PROCESS_V2_ASIO_NAMESPACE::execution::is_executor<Executor>::value || net::execution::is_executor<Executor>::value ||
BOOST_PROCESS_V2_ASIO_NAMESPACE::is_executor<Executor>::value, net::is_executor<Executor>::value,
filesystem::path >::type & executable, filesystem::path >::type & executable,
Args && args, Args && args,
Inits && ... inits ) -> basic_process<Executor> Inits && ... inits ) -> basic_process<Executor>
@@ -69,8 +69,8 @@ struct fork_and_forget_launcher : default_launcher
auto operator()(Executor exec, auto operator()(Executor exec,
error_code & ec, error_code & ec,
const typename std::enable_if< const typename std::enable_if<
BOOST_PROCESS_V2_ASIO_NAMESPACE::execution::is_executor<Executor>::value || net::execution::is_executor<Executor>::value ||
BOOST_PROCESS_V2_ASIO_NAMESPACE::is_executor<Executor>::value, net::is_executor<Executor>::value,
filesystem::path >::type & executable, filesystem::path >::type & executable,
Args && args, Args && args,
Inits && ... inits ) -> basic_process<Executor> Inits && ... inits ) -> basic_process<Executor>
@@ -84,22 +84,22 @@ struct fork_and_forget_launcher : default_launcher
return basic_process<Executor>(exec); return basic_process<Executor>(exec);
} }
auto & ctx = BOOST_PROCESS_V2_ASIO_NAMESPACE::query( auto & ctx = net::query(
exec, BOOST_PROCESS_V2_ASIO_NAMESPACE::execution::context); exec, net::execution::context);
ctx.notify_fork(BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context::fork_prepare); ctx.notify_fork(net::execution_context::fork_prepare);
pid = ::fork(); pid = ::fork();
if (pid == -1) if (pid == -1)
{ {
ctx.notify_fork(BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context::fork_parent); ctx.notify_fork(net::execution_context::fork_parent);
detail::on_fork_error(*this, executable, argv, ec, inits...); detail::on_fork_error(*this, executable, argv, ec, inits...);
detail::on_error(*this, executable, argv, ec, inits...); detail::on_error(*this, executable, argv, ec, inits...);
BOOST_PROCESS_V2_ASSIGN_EC(ec, errno, system_category()) BOOST_PROCESS_V2_ASSIGN_EC(ec, errno, system_category());
return basic_process<Executor>{exec}; return basic_process<Executor>{exec};
} }
else if (pid == 0) else if (pid == 0)
{ {
ctx.notify_fork(BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context::fork_child); ctx.notify_fork(net::execution_context::fork_child);
ec = detail::on_exec_setup(*this, executable, argv, inits...); ec = detail::on_exec_setup(*this, executable, argv, inits...);
if (!ec) if (!ec)
@@ -107,12 +107,12 @@ struct fork_and_forget_launcher : default_launcher
if (!ec) if (!ec)
::execve(executable.c_str(), const_cast<char * const *>(argv), const_cast<char * const *>(env)); ::execve(executable.c_str(), const_cast<char * const *>(argv), const_cast<char * const *>(env));
BOOST_PROCESS_V2_ASSIGN_EC(ec, errno, system_category()) BOOST_PROCESS_V2_ASSIGN_EC(ec, errno, system_category());
detail::on_exec_error(*this, executable, argv, ec, inits...); detail::on_exec_error(*this, executable, argv, ec, inits...);
::exit(EXIT_FAILURE); ::exit(EXIT_FAILURE);
return basic_process<Executor>{exec}; return basic_process<Executor>{exec};
} }
ctx.notify_fork(BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context::fork_parent); ctx.notify_fork(net::execution_context::fork_parent);
if (ec) if (ec)
{ {
detail::on_error(*this, executable, argv, ec, inits...); detail::on_error(*this, executable, argv, ec, inits...);

View File

@@ -25,7 +25,7 @@ struct pdfork_launcher : default_launcher
template<typename ExecutionContext, typename Args, typename ... Inits> template<typename ExecutionContext, typename Args, typename ... Inits>
auto operator()(ExecutionContext & context, auto operator()(ExecutionContext & context,
const typename std::enable_if<is_convertible< const typename std::enable_if<is_convertible<
ExecutionContext&, BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context&>::value, ExecutionContext&, net::execution_context&>::value,
filesystem::path >::type & executable, filesystem::path >::type & executable,
Args && args, Args && args,
Inits && ... inits ) -> basic_process<typename ExecutionContext::executor_type> Inits && ... inits ) -> basic_process<typename ExecutionContext::executor_type>
@@ -44,7 +44,7 @@ struct pdfork_launcher : default_launcher
auto operator()(ExecutionContext & context, auto operator()(ExecutionContext & context,
error_code & ec, error_code & ec,
const typename std::enable_if<is_convertible< const typename std::enable_if<is_convertible<
ExecutionContext&, BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context&>::value, ExecutionContext&, net::execution_context&>::value,
filesystem::path >::type & executable, filesystem::path >::type & executable,
Args && args, Args && args,
Inits && ... inits ) -> basic_process<typename ExecutionContext::executor_type> Inits && ... inits ) -> basic_process<typename ExecutionContext::executor_type>
@@ -55,8 +55,8 @@ struct pdfork_launcher : default_launcher
template<typename Executor, typename Args, typename ... Inits> template<typename Executor, typename Args, typename ... Inits>
auto operator()(Executor exec, auto operator()(Executor exec,
const typename std::enable_if< const typename std::enable_if<
BOOST_PROCESS_V2_ASIO_NAMESPACE::execution::is_executor<Executor>::value || net::execution::is_executor<Executor>::value ||
BOOST_PROCESS_V2_ASIO_NAMESPACE::is_executor<Executor>::value, net::is_executor<Executor>::value,
filesystem::path >::type & executable, filesystem::path >::type & executable,
Args && args, Args && args,
Inits && ... inits ) -> basic_process<Executor> Inits && ... inits ) -> basic_process<Executor>
@@ -74,8 +74,8 @@ struct pdfork_launcher : default_launcher
auto operator()(Executor exec, auto operator()(Executor exec,
error_code & ec, error_code & ec,
const typename std::enable_if< const typename std::enable_if<
BOOST_PROCESS_V2_ASIO_NAMESPACE::execution::is_executor<Executor>::value || net::execution::is_executor<Executor>::value ||
BOOST_PROCESS_V2_ASIO_NAMESPACE::is_executor<Executor>::value, net::is_executor<Executor>::value,
filesystem::path >::type & executable, filesystem::path >::type & executable,
Args && args, Args && args,
Inits && ... inits ) -> basic_process<Executor> Inits && ... inits ) -> basic_process<Executor>
@@ -85,12 +85,12 @@ struct pdfork_launcher : default_launcher
pipe_guard pg; pipe_guard pg;
if (::pipe(pg.p)) if (::pipe(pg.p))
{ {
BOOST_PROCESS_V2_ASSIGN_EC(ec, errno, system_category()) BOOST_PROCESS_V2_ASSIGN_EC(ec, errno, system_category());
return basic_process<Executor>{exec}; return basic_process<Executor>{exec};
} }
if (::fcntl(pg.p[1], F_SETFD, FD_CLOEXEC)) if (::fcntl(pg.p[1], F_SETFD, FD_CLOEXEC))
{ {
BOOST_PROCESS_V2_ASSIGN_EC(ec, errno, system_category()) BOOST_PROCESS_V2_ASSIGN_EC(ec, errno, system_category());
return basic_process<Executor>{exec}; return basic_process<Executor>{exec};
} }
ec = detail::on_setup(*this, executable, argv, inits ...); ec = detail::on_setup(*this, executable, argv, inits ...);
@@ -101,22 +101,22 @@ struct pdfork_launcher : default_launcher
} }
fd_whitelist.push_back(pg.p[1]); fd_whitelist.push_back(pg.p[1]);
auto & ctx = BOOST_PROCESS_V2_ASIO_NAMESPACE::query( auto & ctx = net::query(
exec, BOOST_PROCESS_V2_ASIO_NAMESPACE::execution::context); exec, net::execution::context);
ctx.notify_fork(BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context::fork_prepare); ctx.notify_fork(net::execution_context::fork_prepare);
pid = ::pdfork(&fd, PD_DAEMON | PD_CLOEXEC); pid = ::pdfork(&fd, PD_DAEMON | PD_CLOEXEC);
if (pid == -1) if (pid == -1)
{ {
ctx.notify_fork(BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context::fork_parent); ctx.notify_fork(net::execution_context::fork_parent);
detail::on_fork_error(*this, executable, argv, ec, inits...); detail::on_fork_error(*this, executable, argv, ec, inits...);
detail::on_error(*this, executable, argv, ec, inits...); detail::on_error(*this, executable, argv, ec, inits...);
BOOST_PROCESS_V2_ASSIGN_EC(ec, errno, system_category()) BOOST_PROCESS_V2_ASSIGN_EC(ec, errno, system_category());
return basic_process<Executor>{exec}; return basic_process<Executor>{exec};
} }
else if (pid == 0) else if (pid == 0)
{ {
ctx.notify_fork(BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context::fork_child); ctx.notify_fork(net::execution_context::fork_child);
::close(pg.p[0]); ::close(pg.p[0]);
ec = detail::on_exec_setup(*this, executable, argv, inits...); ec = detail::on_exec_setup(*this, executable, argv, inits...);
@@ -128,12 +128,12 @@ struct pdfork_launcher : default_launcher
::execve(executable.c_str(), const_cast<char * const *>(argv), const_cast<char * const *>(env)); ::execve(executable.c_str(), const_cast<char * const *>(argv), const_cast<char * const *>(env));
default_launcher::ignore_unused(::write(pg.p[1], &errno, sizeof(int))); default_launcher::ignore_unused(::write(pg.p[1], &errno, sizeof(int)));
BOOST_PROCESS_V2_ASSIGN_EC(ec, errno, system_category()) BOOST_PROCESS_V2_ASSIGN_EC(ec, errno, system_category());
detail::on_exec_error(*this, executable, argv, ec, inits...); detail::on_exec_error(*this, executable, argv, ec, inits...);
::exit(EXIT_FAILURE); ::exit(EXIT_FAILURE);
return basic_process<Executor>{exec}; return basic_process<Executor>{exec};
} }
ctx.notify_fork(BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context::fork_parent); ctx.notify_fork(net::execution_context::fork_parent);
::close(pg.p[1]); ::close(pg.p[1]);
pg.p[1] = -1; pg.p[1] = -1;
int child_error{0}; int child_error{0};
@@ -143,12 +143,12 @@ struct pdfork_launcher : default_launcher
int err = errno; int err = errno;
if ((err != EAGAIN) && (err != EINTR)) if ((err != EAGAIN) && (err != EINTR))
{ {
BOOST_PROCESS_V2_ASSIGN_EC(ec, err, system_category()) BOOST_PROCESS_V2_ASSIGN_EC(ec, err, system_category());
break; break;
} }
} }
if (count != 0) if (count != 0)
BOOST_PROCESS_V2_ASSIGN_EC(ec, child_error, system_category()) BOOST_PROCESS_V2_ASSIGN_EC(ec, child_error, system_category());
if (ec) if (ec)
{ {

View File

@@ -22,7 +22,7 @@ struct vfork_launcher : default_launcher
template<typename ExecutionContext, typename Args, typename ... Inits> template<typename ExecutionContext, typename Args, typename ... Inits>
auto operator()(ExecutionContext & context, auto operator()(ExecutionContext & context,
const typename std::enable_if<std::is_convertible< const typename std::enable_if<std::is_convertible<
ExecutionContext&, BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context&>::value, ExecutionContext&, net::execution_context&>::value,
filesystem::path >::type & executable, filesystem::path >::type & executable,
Args && args, Args && args,
Inits && ... inits ) -> basic_process<typename ExecutionContext::executor_type> Inits && ... inits ) -> basic_process<typename ExecutionContext::executor_type>
@@ -41,7 +41,7 @@ struct vfork_launcher : default_launcher
auto operator()(ExecutionContext & context, auto operator()(ExecutionContext & context,
error_code & ec, error_code & ec,
const typename std::enable_if<std::is_convertible< const typename std::enable_if<std::is_convertible<
ExecutionContext&, BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context&>::value, ExecutionContext&, net::execution_context&>::value,
filesystem::path >::type & executable, filesystem::path >::type & executable,
Args && args, Args && args,
Inits && ... inits ) -> basic_process<typename ExecutionContext::executor_type> Inits && ... inits ) -> basic_process<typename ExecutionContext::executor_type>
@@ -52,8 +52,8 @@ struct vfork_launcher : default_launcher
template<typename Executor, typename Args, typename ... Inits> template<typename Executor, typename Args, typename ... Inits>
auto operator()(Executor exec, auto operator()(Executor exec,
const typename std::enable_if< const typename std::enable_if<
BOOST_PROCESS_V2_ASIO_NAMESPACE::execution::is_executor<Executor>::value || net::execution::is_executor<Executor>::value ||
BOOST_PROCESS_V2_ASIO_NAMESPACE::is_executor<Executor>::value, net::is_executor<Executor>::value,
filesystem::path >::type & executable, filesystem::path >::type & executable,
Args && args, Args && args,
Inits && ... inits ) -> basic_process<Executor> Inits && ... inits ) -> basic_process<Executor>
@@ -71,8 +71,8 @@ struct vfork_launcher : default_launcher
auto operator()(Executor exec, auto operator()(Executor exec,
error_code & ec, error_code & ec,
const typename std::enable_if< const typename std::enable_if<
BOOST_PROCESS_V2_ASIO_NAMESPACE::execution::is_executor<Executor>::value || net::execution::is_executor<Executor>::value ||
BOOST_PROCESS_V2_ASIO_NAMESPACE::is_executor<Executor>::value, net::is_executor<Executor>::value,
filesystem::path >::type & executable, filesystem::path >::type & executable,
Args && args, Args && args,
Inits && ... inits ) -> basic_process<Executor> Inits && ... inits ) -> basic_process<Executor>
@@ -86,17 +86,17 @@ struct vfork_launcher : default_launcher
return basic_process<Executor>(exec); return basic_process<Executor>(exec);
} }
auto & ctx = BOOST_PROCESS_V2_ASIO_NAMESPACE::query( auto & ctx = net::query(
exec, BOOST_PROCESS_V2_ASIO_NAMESPACE::execution::context); exec, net::execution::context);
ctx.notify_fork(BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context::fork_prepare); ctx.notify_fork(net::execution_context::fork_prepare);
pid = ::vfork(); pid = ::vfork();
if (pid == -1) if (pid == -1)
{ {
ctx.notify_fork(BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context::fork_parent); ctx.notify_fork(net::execution_context::fork_parent);
detail::on_fork_error(*this, executable, argv, ec, inits...); detail::on_fork_error(*this, executable, argv, ec, inits...);
detail::on_error(*this, executable, argv, ec, inits...); detail::on_error(*this, executable, argv, ec, inits...);
BOOST_PROCESS_V2_ASSIGN_EC(ec, errno, system_category()) BOOST_PROCESS_V2_ASSIGN_EC(ec, errno, system_category());
return basic_process<Executor>{exec}; return basic_process<Executor>{exec};
} }
else if (pid == 0) else if (pid == 0)
@@ -107,12 +107,12 @@ struct vfork_launcher : default_launcher
if (!ec) if (!ec)
::execve(executable.c_str(), const_cast<char * const *>(argv), const_cast<char * const *>(env)); ::execve(executable.c_str(), const_cast<char * const *>(argv), const_cast<char * const *>(env));
BOOST_PROCESS_V2_ASSIGN_EC(ec, errno, system_category()) BOOST_PROCESS_V2_ASSIGN_EC(ec, errno, system_category());
detail::on_exec_error(*this, executable, argv, ec, inits...); detail::on_exec_error(*this, executable, argv, ec, inits...);
::_exit(EXIT_FAILURE); ::_exit(EXIT_FAILURE);
return basic_process<Executor>{exec}; return basic_process<Executor>{exec};
} }
ctx.notify_fork(BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context::fork_parent); ctx.notify_fork(net::execution_context::fork_parent);
if (ec) if (ec)
{ {

View File

@@ -34,7 +34,7 @@ BOOST_PROCESS_V2_BEGIN_NAMESPACE
/* A `basic_process` object manages a subprocess; it tracks the status and exit-code, /* A `basic_process` object manages a subprocess; it tracks the status and exit-code,
* and will terminate the process on destruction if `detach` was not called. * and will terminate the process on destruction if `detach` was not called.
*/ */
template<typename Executor = BOOST_PROCESS_V2_ASIO_NAMESPACE::any_io_executor> template<typename Executor = net::any_io_executor>
struct basic_process struct basic_process
{ {
/// The executor of the process /// The executor of the process
@@ -111,7 +111,7 @@ struct basic_process
ExecutionContext & context, ExecutionContext & context,
typename std::enable_if< typename std::enable_if<
std::is_convertible<ExecutionContext&, std::is_convertible<ExecutionContext&,
BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context&>::value, net::execution_context&>::value,
const filesystem::path&>::type exe, const filesystem::path&>::type exe,
std::initializer_list<string_view> args, std::initializer_list<string_view> args,
Inits&&... inits) Inits&&... inits)
@@ -125,7 +125,7 @@ struct basic_process
ExecutionContext & context, ExecutionContext & context,
typename std::enable_if< typename std::enable_if<
std::is_convertible<ExecutionContext&, std::is_convertible<ExecutionContext&,
BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context&>::value, net::execution_context&>::value,
const filesystem::path&>::type exe, const filesystem::path&>::type exe,
Args&& args, Inits&&... inits) Args&& args, Inits&&... inits)
: basic_process(default_process_launcher()(executor_type(context.get_executor()), : basic_process(default_process_launcher()(executor_type(context.get_executor()),
@@ -148,7 +148,7 @@ struct basic_process
explicit basic_process(ExecutionContext & context, pid_type pid, explicit basic_process(ExecutionContext & context, pid_type pid,
typename std::enable_if< typename std::enable_if<
std::is_convertible<ExecutionContext&, std::is_convertible<ExecutionContext&,
BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context&>::value, void *>::type = nullptr) net::execution_context&>::value, void *>::type = nullptr)
: process_handle_(context, pid) {} : process_handle_(context, pid) {}
/// Attach to an existing process and the internal handle /// Attach to an existing process and the internal handle
@@ -156,7 +156,7 @@ struct basic_process
explicit basic_process(ExecutionContext & context, pid_type pid, native_handle_type native_handle, explicit basic_process(ExecutionContext & context, pid_type pid, native_handle_type native_handle,
typename std::enable_if< typename std::enable_if<
std::is_convertible<ExecutionContext&, std::is_convertible<ExecutionContext&,
BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context&>::value, void *>::type = nullptr) net::execution_context&>::value, void *>::type = nullptr)
: process_handle_(context.get_executor(), pid, native_handle) {} : process_handle_(context.get_executor(), pid, native_handle) {}
/// Create an invalid handle /// Create an invalid handle
@@ -164,7 +164,7 @@ struct basic_process
explicit basic_process(ExecutionContext & context, explicit basic_process(ExecutionContext & context,
typename std::enable_if< typename std::enable_if<
is_convertible<ExecutionContext&, is_convertible<ExecutionContext&,
BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context&>::value, void *>::type = nullptr) net::execution_context&>::value, void *>::type = nullptr)
: process_handle_(context.get_executor()) {} : process_handle_(context.get_executor()) {}
@@ -325,15 +325,7 @@ struct basic_process
/** Note that this might be a process that already exited.*/ /** Note that this might be a process that already exited.*/
bool is_open() const { return process_handle_.is_open(); } bool is_open() const { return process_handle_.is_open(); }
/// Asynchronously wait for the process to exit and deliver the native exit-code in the completion handler.
template <BOOST_PROCESS_V2_COMPLETION_TOKEN_FOR(void (error_code, int))
WaitHandler BOOST_PROCESS_V2_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_PROCESS_V2_INITFN_AUTO_RESULT_TYPE(WaitHandler, void (error_code, int))
async_wait(WaitHandler && handler BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
{
return BOOST_PROCESS_V2_ASIO_NAMESPACE::async_compose<WaitHandler, void (error_code, int)>(
async_wait_op_{process_handle_, exit_status_}, handler, process_handle_);
}
private: private:
template<typename Executor1> template<typename Executor1>
@@ -363,7 +355,7 @@ private:
} }
}; };
BOOST_PROCESS_V2_ASIO_NAMESPACE::post(handle.get_executor(), net::post(handle.get_executor(),
completer{static_cast<int>(res), std::move(self)}); completer{static_cast<int>(res), std::move(self)});
} }
else else
@@ -383,6 +375,18 @@ private:
} }
} }
}; };
public:
/// Asynchronously wait for the process to exit and deliver the native exit-code in the completion handler.
template <BOOST_PROCESS_V2_COMPLETION_TOKEN_FOR(void (error_code, int))
WaitHandler = net::default_completion_token_t<executor_type>>
auto async_wait(WaitHandler && handler = net::default_completion_token_t<executor_type>())
-> decltype(net::async_compose<WaitHandler, void (error_code, int)>(
async_wait_op_{process_handle_, exit_status_}, handler, process_handle_))
{
return net::async_compose<WaitHandler, void (error_code, int)>(
async_wait_op_{process_handle_, exit_status_}, handler, process_handle_);
}
}; };
/// Process with the default executor. /// Process with the default executor.

View File

@@ -32,7 +32,7 @@ BOOST_PROCESS_V2_BEGIN_NAMESPACE
* Note that the exit code might be discovered early, during a call to `running`. * Note that the exit code might be discovered early, during a call to `running`.
* Thus it can only be discovered that process has exited already. * Thus it can only be discovered that process has exited already.
*/ */
template<typename Executor = BOOST_PROCESS_V2_ASIO_NAMESPACE::any_io_executor> template<typename Executor = net::any_io_executor>
struct basic_process_handle struct basic_process_handle
{ {
/// The native handle of the process. /// The native handle of the process.
@@ -123,28 +123,26 @@ struct basic_process_handle
/// Asynchronously wait for the process to exit and deliver the native exit-code in the completion handler. /// Asynchronously wait for the process to exit and deliver the native exit-code in the completion handler.
template<BOOST_PROCESS_V2_COMPLETION_TOKEN_FOR(void(error_code, native_exit_code_type)) template<BOOST_PROCESS_V2_COMPLETION_TOKEN_FOR(void(error_code, native_exit_code_type))
WaitHandler BOOST_PROCESS_V2_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)> WaitHandler = net::default_completion_token_t<executor_type>>
BOOST_PROCESS_V2_INITFN_AUTO_RESULT_TYPE(WaitHandler, void (error_code, native_exit_code_type)) auto async_wait(WaitHandler &&handler = net::default_completion_token_t<executor_type>());
async_wait(WaitHandler &&handler BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type));
}; };
#else #else
#if defined(BOOST_PROCESS_V2_WINDOWS) #if defined(BOOST_PROCESS_V2_WINDOWS)
template<typename Executor = BOOST_PROCESS_V2_ASIO_NAMESPACE::any_io_executor> template<typename Executor = net::any_io_executor>
using basic_process_handle = detail::basic_process_handle_win<Executor>; using basic_process_handle = detail::basic_process_handle_win<Executor>;
#else #else
#if defined(BOOST_PROCESS_V2_PIDFD_OPEN) #if defined(BOOST_PROCESS_V2_PIDFD_OPEN)
template<typename Executor = BOOST_PROCESS_V2_ASIO_NAMESPACE::any_io_executor> template<typename Executor = net::any_io_executor>
using basic_process_handle = detail::basic_process_handle_fd<Executor>; using basic_process_handle = detail::basic_process_handle_fd<Executor>;
#elif defined(BOOST_PROCESS_V2_PDFORK) #elif defined(BOOST_PROCESS_V2_PDFORK)
template<typename Executor = BOOST_PROCESS_V2_ASIO_NAMESPACE::any_io_executor> template<typename Executor = net::any_io_executor>
using basic_process_handle = detail::basic_process_handle_fd_or_signal<Executor>; using basic_process_handle = detail::basic_process_handle_fd_or_signal<Executor>;
#else #else
template<typename Executor = BOOST_PROCESS_V2_ASIO_NAMESPACE::any_io_executor> template<typename Executor = net::any_io_executor>
using basic_process_handle = detail::basic_process_handle_signal<Executor>; using basic_process_handle = detail::basic_process_handle_signal<Executor>;
#endif #endif

View File

@@ -103,7 +103,7 @@ struct process_io_binding
template<typename Executor> template<typename Executor>
process_io_binding(BOOST_PROCESS_V2_ASIO_NAMESPACE::basic_readable_pipe<Executor> & pipe) process_io_binding(net::basic_readable_pipe<Executor> & pipe)
{ {
if (Target == STD_INPUT_HANDLE) if (Target == STD_INPUT_HANDLE)
{ {
@@ -112,9 +112,9 @@ struct process_io_binding
return ; return ;
} }
BOOST_PROCESS_V2_ASIO_NAMESPACE::detail::native_pipe_handle p[2]; net::detail::native_pipe_handle p[2];
error_code ec; error_code ec;
BOOST_PROCESS_V2_ASIO_NAMESPACE::detail::create_pipe(p, ec); net::detail::create_pipe(p, ec);
if (ec) if (ec)
detail::throw_error(ec, "create_pipe"); detail::throw_error(ec, "create_pipe");
@@ -124,7 +124,7 @@ struct process_io_binding
template<typename Executor> template<typename Executor>
process_io_binding(BOOST_PROCESS_V2_ASIO_NAMESPACE::basic_writable_pipe<Executor> & pipe) process_io_binding(net::basic_writable_pipe<Executor> & pipe)
{ {
if (Target != STD_INPUT_HANDLE) if (Target != STD_INPUT_HANDLE)
{ {
@@ -132,9 +132,9 @@ struct process_io_binding
h = std::unique_ptr<void, handle_closer>{h_, get_flags(h_)}; h = std::unique_ptr<void, handle_closer>{h_, get_flags(h_)};
return ; return ;
} }
BOOST_PROCESS_V2_ASIO_NAMESPACE::detail::native_pipe_handle p[2]; net::detail::native_pipe_handle p[2];
error_code ec; error_code ec;
BOOST_PROCESS_V2_ASIO_NAMESPACE::detail::create_pipe(p, ec); net::detail::create_pipe(p, ec);
if (ec) if (ec)
detail::throw_error(ec, "create_pipe"); detail::throw_error(ec, "create_pipe");
@@ -181,7 +181,7 @@ struct process_io_binding
} }
template<typename Executor> template<typename Executor>
process_io_binding(BOOST_PROCESS_V2_ASIO_NAMESPACE::basic_readable_pipe<Executor> & readable_pipe) process_io_binding(net::basic_readable_pipe<Executor> & readable_pipe)
{ {
if (Target == STDIN_FILENO) if (Target == STDIN_FILENO)
{ {
@@ -189,15 +189,15 @@ struct process_io_binding
return ; return ;
} }
BOOST_PROCESS_V2_ASIO_NAMESPACE::detail::native_pipe_handle p[2]; net::detail::native_pipe_handle p[2];
BOOST_PROCESS_V2_ASIO_NAMESPACE::detail::create_pipe(p, ec); net::detail::create_pipe(p, ec);
if (ec) if (ec)
detail::throw_error(ec, "create_pipe"); detail::throw_error(ec, "create_pipe");
fd = p[1]; fd = p[1];
if (::fcntl(p[0], F_SETFD, FD_CLOEXEC) == -1) if (::fcntl(p[0], F_SETFD, FD_CLOEXEC) == -1)
{ {
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return ; return ;
} }
fd_needs_closing = true; fd_needs_closing = true;
@@ -206,7 +206,7 @@ struct process_io_binding
template<typename Executor> template<typename Executor>
process_io_binding(BOOST_PROCESS_V2_ASIO_NAMESPACE::basic_writable_pipe<Executor> & writable_pipe) process_io_binding(net::basic_writable_pipe<Executor> & writable_pipe)
{ {
if (Target != STDIN_FILENO) if (Target != STDIN_FILENO)
@@ -214,16 +214,16 @@ struct process_io_binding
fd = writable_pipe.native_handle(); fd = writable_pipe.native_handle();
return ; return ;
} }
BOOST_PROCESS_V2_ASIO_NAMESPACE::detail::native_pipe_handle p[2]; net::detail::native_pipe_handle p[2];
error_code ec; error_code ec;
BOOST_PROCESS_V2_ASIO_NAMESPACE::detail::create_pipe(p, ec); net::detail::create_pipe(p, ec);
if (ec) if (ec)
detail::throw_error(ec, "create_pipe"); detail::throw_error(ec, "create_pipe");
fd = p[0]; fd = p[0];
if (::fcntl(p[1], F_SETFD, FD_CLOEXEC) == -1) if (::fcntl(p[1], F_SETFD, FD_CLOEXEC) == -1)
{ {
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return ; return ;
} }
fd_needs_closing = true; fd_needs_closing = true;

View File

@@ -28,7 +28,7 @@ struct as_user_launcher : default_launcher
template<typename ExecutionContext, typename Args, typename ... Inits> template<typename ExecutionContext, typename Args, typename ... Inits>
auto operator()(ExecutionContext & context, auto operator()(ExecutionContext & context,
const typename std::enable_if<std::is_convertible< const typename std::enable_if<std::is_convertible<
ExecutionContext&, BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context&>::value, ExecutionContext&, net::execution_context&>::value,
filesystem::path >::type & executable, filesystem::path >::type & executable,
Args && args, Args && args,
Inits && ... inits ) -> basic_process<typename ExecutionContext::executor_type> Inits && ... inits ) -> basic_process<typename ExecutionContext::executor_type>
@@ -47,7 +47,7 @@ struct as_user_launcher : default_launcher
auto operator()(ExecutionContext & context, auto operator()(ExecutionContext & context,
error_code & ec, error_code & ec,
const typename std::enable_if<std::is_convertible< const typename std::enable_if<std::is_convertible<
ExecutionContext&, BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context&>::value, ExecutionContext&, net::execution_context&>::value,
filesystem::path >::type & executable, filesystem::path >::type & executable,
Args && args, Args && args,
Inits && ... inits ) -> basic_process<typename ExecutionContext::executor_type> Inits && ... inits ) -> basic_process<typename ExecutionContext::executor_type>
@@ -58,8 +58,8 @@ struct as_user_launcher : default_launcher
template<typename Executor, typename Args, typename ... Inits> template<typename Executor, typename Args, typename ... Inits>
auto operator()(Executor exec, auto operator()(Executor exec,
const typename std::enable_if< const typename std::enable_if<
BOOST_PROCESS_V2_ASIO_NAMESPACE::execution::is_executor<Executor>::value || net::execution::is_executor<Executor>::value ||
BOOST_PROCESS_V2_ASIO_NAMESPACE::is_executor<Executor>::value, net::is_executor<Executor>::value,
filesystem::path >::type & executable, filesystem::path >::type & executable,
Args && args, Args && args,
Inits && ... inits ) -> basic_process<Executor> Inits && ... inits ) -> basic_process<Executor>
@@ -77,8 +77,8 @@ struct as_user_launcher : default_launcher
auto operator()(Executor exec, auto operator()(Executor exec,
error_code & ec, error_code & ec,
const typename std::enable_if< const typename std::enable_if<
BOOST_PROCESS_V2_ASIO_NAMESPACE::execution::is_executor<Executor>::value || net::execution::is_executor<Executor>::value ||
BOOST_PROCESS_V2_ASIO_NAMESPACE::is_executor<Executor>::value, net::is_executor<Executor>::value,
filesystem::path >::type & executable, filesystem::path >::type & executable,
Args && args, Args && args,
Inits && ... inits ) -> basic_process<Executor> Inits && ... inits ) -> basic_process<Executor>
@@ -107,7 +107,7 @@ struct as_user_launcher : default_launcher
if (ok == 0) if (ok == 0)
{ {
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
detail::on_error(*this, executable, command_line, ec, inits...); detail::on_error(*this, executable, command_line, ec, inits...);
if (process_information.hProcess != INVALID_HANDLE_VALUE) if (process_information.hProcess != INVALID_HANDLE_VALUE)

View File

@@ -236,7 +236,7 @@ struct default_launcher
template<typename ExecutionContext, typename Args, typename ... Inits> template<typename ExecutionContext, typename Args, typename ... Inits>
auto operator()(ExecutionContext & context, auto operator()(ExecutionContext & context,
const typename std::enable_if<std::is_convertible< const typename std::enable_if<std::is_convertible<
ExecutionContext&, BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context&>::value, ExecutionContext&, net::execution_context&>::value,
filesystem::path >::type & executable, filesystem::path >::type & executable,
Args && args, Args && args,
Inits && ... inits ) -> enable_init<typename ExecutionContext::executor_type, Inits...> Inits && ... inits ) -> enable_init<typename ExecutionContext::executor_type, Inits...>
@@ -255,7 +255,7 @@ struct default_launcher
auto operator()(ExecutionContext & context, auto operator()(ExecutionContext & context,
error_code & ec, error_code & ec,
const typename std::enable_if<std::is_convertible< const typename std::enable_if<std::is_convertible<
ExecutionContext&, BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context&>::value, ExecutionContext&, net::execution_context&>::value,
filesystem::path >::type & executable, filesystem::path >::type & executable,
Args && args, Args && args,
Inits && ... inits ) -> enable_init<typename ExecutionContext::executor_type, Inits...> Inits && ... inits ) -> enable_init<typename ExecutionContext::executor_type, Inits...>
@@ -266,8 +266,8 @@ struct default_launcher
template<typename Executor, typename Args, typename ... Inits> template<typename Executor, typename Args, typename ... Inits>
auto operator()(Executor exec, auto operator()(Executor exec,
const typename std::enable_if< const typename std::enable_if<
BOOST_PROCESS_V2_ASIO_NAMESPACE::execution::is_executor<Executor>::value net::execution::is_executor<Executor>::value
|| BOOST_PROCESS_V2_ASIO_NAMESPACE::is_executor<Executor>::value, || net::is_executor<Executor>::value,
filesystem::path >::type & executable, filesystem::path >::type & executable,
Args && args, Args && args,
Inits && ... inits ) -> enable_init<Executor, Inits...> Inits && ... inits ) -> enable_init<Executor, Inits...>
@@ -285,8 +285,8 @@ struct default_launcher
auto operator()(Executor exec, auto operator()(Executor exec,
error_code & ec, error_code & ec,
const typename std::enable_if< const typename std::enable_if<
BOOST_PROCESS_V2_ASIO_NAMESPACE::execution::is_executor<Executor>::value || net::execution::is_executor<Executor>::value ||
BOOST_PROCESS_V2_ASIO_NAMESPACE::is_executor<Executor>::value, net::is_executor<Executor>::value,
filesystem::path >::type & executable, filesystem::path >::type & executable,
Args && args, Args && args,
Inits && ... inits ) -> enable_init<Executor, Inits...> Inits && ... inits ) -> enable_init<Executor, Inits...>
@@ -314,7 +314,7 @@ struct default_launcher
if (ok == 0) if (ok == 0)
{ {
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
detail::on_error(*this, executable, command_line, ec, inits...); detail::on_error(*this, executable, command_line, ec, inits...);
if (process_information.hProcess != INVALID_HANDLE_VALUE) if (process_information.hProcess != INVALID_HANDLE_VALUE)

View File

@@ -39,7 +39,7 @@ struct with_logon_launcher : default_launcher
auto operator()(ExecutionContext & context, auto operator()(ExecutionContext & context,
error_code & ec, error_code & ec,
const typename std::enable_if<std::is_convertible< const typename std::enable_if<std::is_convertible<
ExecutionContext&, BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context&>::value, ExecutionContext&, net::execution_context&>::value,
filesystem::path >::type & executable, filesystem::path >::type & executable,
Args && args, Args && args,
Inits && ... inits ) -> basic_process<typename ExecutionContext::executor_type> Inits && ... inits ) -> basic_process<typename ExecutionContext::executor_type>
@@ -51,7 +51,7 @@ struct with_logon_launcher : default_launcher
template<typename ExecutionContext, typename Args, typename ... Inits> template<typename ExecutionContext, typename Args, typename ... Inits>
auto operator()(ExecutionContext & context, auto operator()(ExecutionContext & context,
const typename std::enable_if<std::is_convertible< const typename std::enable_if<std::is_convertible<
ExecutionContext&, BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context&>::value, ExecutionContext&, net::execution_context&>::value,
filesystem::path >::type & executable, filesystem::path >::type & executable,
Args && args, Args && args,
Inits && ... inits ) -> basic_process<typename ExecutionContext::executor_type> Inits && ... inits ) -> basic_process<typename ExecutionContext::executor_type>
@@ -62,8 +62,8 @@ struct with_logon_launcher : default_launcher
template<typename Executor, typename Args, typename ... Inits> template<typename Executor, typename Args, typename ... Inits>
auto operator()(Executor exec, auto operator()(Executor exec,
const typename std::enable_if< const typename std::enable_if<
BOOST_PROCESS_V2_ASIO_NAMESPACE::execution::is_executor<Executor>::value || net::execution::is_executor<Executor>::value ||
BOOST_PROCESS_V2_ASIO_NAMESPACE::is_executor<Executor>::value, net::is_executor<Executor>::value,
filesystem::path >::type & executable, filesystem::path >::type & executable,
Args && args, Args && args,
Inits && ... inits ) -> basic_process<Executor> Inits && ... inits ) -> basic_process<Executor>
@@ -81,8 +81,8 @@ struct with_logon_launcher : default_launcher
auto operator()(Executor exec, auto operator()(Executor exec,
error_code & ec, error_code & ec,
const typename std::enable_if< const typename std::enable_if<
BOOST_PROCESS_V2_ASIO_NAMESPACE::execution::is_executor<Executor>::value || net::execution::is_executor<Executor>::value ||
BOOST_PROCESS_V2_ASIO_NAMESPACE::is_executor<Executor>::value, net::is_executor<Executor>::value,
filesystem::path >::type & executable, filesystem::path >::type & executable,
Args && args, Args && args,
Inits && ... inits ) -> basic_process<Executor> Inits && ... inits ) -> basic_process<Executor>
@@ -111,7 +111,7 @@ struct with_logon_launcher : default_launcher
if (ok == 0) if (ok == 0)
{ {
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
detail::on_error(*this, executable, command_line, ec, inits...); detail::on_error(*this, executable, command_line, ec, inits...);
if (process_information.hProcess != INVALID_HANDLE_VALUE) if (process_information.hProcess != INVALID_HANDLE_VALUE)

View File

@@ -29,7 +29,7 @@ struct with_token_launcher : default_launcher
template<typename ExecutionContext, typename Args, typename ... Inits> template<typename ExecutionContext, typename Args, typename ... Inits>
auto operator()(ExecutionContext & context, auto operator()(ExecutionContext & context,
const typename std::enable_if<std::is_convertible< const typename std::enable_if<std::is_convertible<
ExecutionContext&, BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context&>::value, ExecutionContext&, net::execution_context&>::value,
filesystem::path >::type & executable, filesystem::path >::type & executable,
Args && args, Args && args,
Inits && ... inits ) -> basic_process<typename ExecutionContext::executor_type> Inits && ... inits ) -> basic_process<typename ExecutionContext::executor_type>
@@ -48,7 +48,7 @@ struct with_token_launcher : default_launcher
auto operator()(ExecutionContext & context, auto operator()(ExecutionContext & context,
error_code & ec, error_code & ec,
const typename std::enable_if<std::is_convertible< const typename std::enable_if<std::is_convertible<
ExecutionContext&, BOOST_PROCESS_V2_ASIO_NAMESPACE::execution_context&>::value, ExecutionContext&, net::execution_context&>::value,
filesystem::path >::type & executable, filesystem::path >::type & executable,
Args && args, Args && args,
Inits && ... inits ) -> basic_process<typename ExecutionContext::executor_type> Inits && ... inits ) -> basic_process<typename ExecutionContext::executor_type>
@@ -59,8 +59,8 @@ struct with_token_launcher : default_launcher
template<typename Executor, typename Args, typename ... Inits> template<typename Executor, typename Args, typename ... Inits>
auto operator()(Executor exec, auto operator()(Executor exec,
const typename std::enable_if< const typename std::enable_if<
BOOST_PROCESS_V2_ASIO_NAMESPACE::execution::is_executor<Executor>::value || net::execution::is_executor<Executor>::value ||
BOOST_PROCESS_V2_ASIO_NAMESPACE::is_executor<Executor>::value, net::is_executor<Executor>::value,
filesystem::path >::type & executable, filesystem::path >::type & executable,
Args && args, Args && args,
Inits && ... inits ) -> basic_process<Executor> Inits && ... inits ) -> basic_process<Executor>
@@ -78,8 +78,8 @@ struct with_token_launcher : default_launcher
auto operator()(Executor exec, auto operator()(Executor exec,
error_code & ec, error_code & ec,
const typename std::enable_if< const typename std::enable_if<
BOOST_PROCESS_V2_ASIO_NAMESPACE::execution::is_executor<Executor>::value || net::execution::is_executor<Executor>::value ||
BOOST_PROCESS_V2_ASIO_NAMESPACE::is_executor<Executor>::value, net::is_executor<Executor>::value,
filesystem::path >::type & executable, filesystem::path >::type & executable,
Args && args, Args && args,
Inits && ... inits ) -> basic_process<Executor> Inits && ... inits ) -> basic_process<Executor>
@@ -106,7 +106,7 @@ struct with_token_launcher : default_launcher
if (ok == 0) if (ok == 0)
{ {
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
detail::on_error(*this, executable, command_line, ec, inits...); detail::on_error(*this, executable, command_line, ec, inits...);
if (process_information.hProcess != INVALID_HANDLE_VALUE) if (process_information.hProcess != INVALID_HANDLE_VALUE)

View File

@@ -30,7 +30,7 @@ basic_cstring_ref<char_type, value_char_traits<char>> get(
auto res = ::getenv(key.c_str()); auto res = ::getenv(key.c_str());
if (res == nullptr) if (res == nullptr)
{ {
BOOST_PROCESS_V2_ASSIGN_EC(ec, ENOENT, system_category()) BOOST_PROCESS_V2_ASSIGN_EC(ec, ENOENT, system_category());
return {}; return {};
} }
return res; return res;
@@ -41,13 +41,13 @@ void set(basic_cstring_ref<char_type, key_char_traits<char_type>> key,
error_code & ec) error_code & ec)
{ {
if (::setenv(key.c_str(), value.c_str(), true)) if (::setenv(key.c_str(), value.c_str(), true))
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
} }
void unset(basic_cstring_ref<char_type, key_char_traits<char_type>> key, error_code & ec) void unset(basic_cstring_ref<char_type, key_char_traits<char_type>> key, error_code & ec)
{ {
if (::unsetenv(key.c_str())) if (::unsetenv(key.c_str()))
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
} }
@@ -65,9 +65,10 @@ native_iterator find_end(native_handle_type nh)
nh++; nh++;
return nh; return nh;
} }
bool is_executable(const filesystem::path & p, error_code & ec)
bool has_x_access(const char * pth)
{ {
return filesystem::is_regular_file(p, ec) && (::access(p.c_str(), X_OK) == 0); return (::access(pth, X_OK) == 0);
} }
} }

View File

@@ -45,7 +45,7 @@ std::basic_string<char_type, value_char_traits<char_type>> get(
buf.resize(size); buf.resize(size);
if (buf.size() == 0) if (buf.size() == 0)
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return buf; return buf;
} }
@@ -55,14 +55,14 @@ void set(basic_cstring_ref<char_type, key_char_traits<char_type>> key,
error_code & ec) error_code & ec)
{ {
if (!::SetEnvironmentVariableW(key.c_str(), value.c_str())) if (!::SetEnvironmentVariableW(key.c_str(), value.c_str()))
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
} }
void unset(basic_cstring_ref<char_type, key_char_traits<char_type>> key, void unset(basic_cstring_ref<char_type, key_char_traits<char_type>> key,
error_code & ec) error_code & ec)
{ {
if (!::SetEnvironmentVariableW(key.c_str(), nullptr)) if (!::SetEnvironmentVariableW(key.c_str(), nullptr))
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
} }
@@ -83,7 +83,7 @@ std::basic_string<char, value_char_traits<char>> get(
buf.resize(size); buf.resize(size);
if (buf.size() == 0) if (buf.size() == 0)
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return buf; return buf;
} }
@@ -93,14 +93,14 @@ void set(basic_cstring_ref<char, key_char_traits<char>> key,
error_code & ec) error_code & ec)
{ {
if (!::SetEnvironmentVariableA(key.c_str(), value.c_str())) if (!::SetEnvironmentVariableA(key.c_str(), value.c_str()))
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
} }
void unset(basic_cstring_ref<char, key_char_traits<char>> key, void unset(basic_cstring_ref<char, key_char_traits<char>> key,
error_code & ec) error_code & ec)
{ {
if (!::SetEnvironmentVariableA(key.c_str(), nullptr)) if (!::SetEnvironmentVariableA(key.c_str(), nullptr))
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
} }
@@ -125,9 +125,9 @@ native_iterator find_end(native_handle_type nh)
return ++nh; return ++nh;
} }
bool is_executable(const filesystem::path & pth, error_code & ec) bool is_exec_type(const wchar_t * pth)
{ {
return filesystem::is_regular_file(pth, ec) && SHGetFileInfoW(pth.native().c_str(), 0,0,0, SHGFI_EXETYPE); return SHGetFileInfoW(pth, 0,0,0, SHGFI_EXETYPE);
} }
} }

View File

@@ -35,7 +35,7 @@ void get_exit_code_(
error_code & ec) error_code & ec)
{ {
if (!::GetExitCodeProcess(handle, &exit_code)) if (!::GetExitCodeProcess(handle, &exit_code))
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
} }
@@ -45,7 +45,7 @@ HANDLE open_process_(DWORD pid)
if (proc == nullptr) if (proc == nullptr)
{ {
error_code ec; error_code ec;
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
throw system_error(ec, "open_process()"); throw system_error(ec, "open_process()");
} }
@@ -67,7 +67,7 @@ bool check_handle_(HANDLE handle, error_code & ec)
{ {
if (handle == INVALID_HANDLE_VALUE) if (handle == INVALID_HANDLE_VALUE)
{ {
BOOST_PROCESS_V2_ASSIGN_EC(ec, ERROR_INVALID_HANDLE_STATE, system_category()) BOOST_PROCESS_V2_ASSIGN_EC(ec, ERROR_INVALID_HANDLE_STATE, system_category());
return false; return false;
} }
return true; return true;
@@ -77,7 +77,7 @@ bool check_pid_(pid_type pid_, error_code & ec)
{ {
if (pid_ == 0) if (pid_ == 0)
{ {
BOOST_PROCESS_V2_ASSIGN_EC(ec, ERROR_INVALID_HANDLE_STATE, system_category()) BOOST_PROCESS_V2_ASSIGN_EC(ec, ERROR_INVALID_HANDLE_STATE, system_category());
return false; return false;
} }
return true; return true;
@@ -100,7 +100,7 @@ static BOOL CALLBACK enum_window(HWND hwnd, LPARAM param)
LRESULT res = ::SendMessageW(hwnd, WM_CLOSE, 0, 0); LRESULT res = ::SendMessageW(hwnd, WM_CLOSE, 0, 0);
if (res) if (res)
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(data->ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(data->ec);
return res == 0; return res == 0;
} }
@@ -109,25 +109,25 @@ void request_exit_(pid_type pid_, error_code & ec)
enum_windows_data_t data{ec, pid_}; enum_windows_data_t data{ec, pid_};
if (!::EnumWindows(enum_window, reinterpret_cast<LONG_PTR>(&data))) if (!::EnumWindows(enum_window, reinterpret_cast<LONG_PTR>(&data)))
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
} }
void interrupt_(pid_type pid_, error_code & ec) void interrupt_(pid_type pid_, error_code & ec)
{ {
if (!::GenerateConsoleCtrlEvent(CTRL_C_EVENT, pid_)) if (!::GenerateConsoleCtrlEvent(CTRL_C_EVENT, pid_))
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
} }
void terminate_(HANDLE handle, error_code & ec, DWORD & exit_status) void terminate_(HANDLE handle, error_code & ec, DWORD & exit_status)
{ {
if (!::TerminateProcess(handle, 260)) if (!::TerminateProcess(handle, 260))
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
} }
void check_running_(HANDLE handle, error_code & ec, DWORD & exit_status) void check_running_(HANDLE handle, error_code & ec, DWORD & exit_status)
{ {
if (!::GetExitCodeProcess(handle, &exit_status)) if (!::GetExitCodeProcess(handle, &exit_status))
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
} }
#if !defined(BOOST_PROCESS_V2_DISABLE_UNDOCUMENTED_API) #if !defined(BOOST_PROCESS_V2_DISABLE_UNDOCUMENTED_API)
@@ -136,7 +136,7 @@ void suspend_(HANDLE handle, error_code & ec)
auto nt_err = NtSuspendProcess(handle); auto nt_err = NtSuspendProcess(handle);
ULONG dos_err = RtlNtStatusToDosError(nt_err); ULONG dos_err = RtlNtStatusToDosError(nt_err);
if (dos_err) if (dos_err)
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
} }
void resume_(HANDLE handle, error_code & ec) void resume_(HANDLE handle, error_code & ec)
@@ -144,17 +144,17 @@ void resume_(HANDLE handle, error_code & ec)
auto nt_err = NtResumeProcess(handle); auto nt_err = NtResumeProcess(handle);
ULONG dos_err = RtlNtStatusToDosError(nt_err); ULONG dos_err = RtlNtStatusToDosError(nt_err);
if (dos_err) if (dos_err)
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
} }
#else #else
void suspend_(HANDLE, error_code & ec) void suspend_(HANDLE, error_code & ec)
{ {
BOOST_PROCESS_V2_ASSIGN_EC(ec, ERROR_CALL_NOT_IMPLEMENTED, system_category()) BOOST_PROCESS_V2_ASSIGN_EC(ec, ERROR_CALL_NOT_IMPLEMENTED, system_category());
} }
void resume_(HANDLE handle, error_code & ec) void resume_(HANDLE handle, error_code & ec)
{ {
BOOST_PROCESS_V2_ASSIGN_EC(ec, ERROR_CALL_NOT_IMPLEMENTED, system_category()) BOOST_PROCESS_V2_ASSIGN_EC(ec, ERROR_CALL_NOT_IMPLEMENTED, system_category());
} }
#endif #endif

View File

@@ -9,7 +9,7 @@
#include <boost/process/v2/error.hpp> #include <boost/process/v2/error.hpp>
#if defined(BOOST_PROCESS_V2_WINDOWS) #if defined(BOOST_PROCESS_V2_WINDOWS)
#include <Windows.h> #include <windows.h>
#endif #endif
BOOST_PROCESS_V2_BEGIN_NAMESPACE BOOST_PROCESS_V2_BEGIN_NAMESPACE
@@ -25,13 +25,13 @@ inline void handle_error(error_code & ec)
switch (err) switch (err)
{ {
case ERROR_INSUFFICIENT_BUFFER: case ERROR_INSUFFICIENT_BUFFER:
BOOST_PROCESS_V2_ASSIGN_EC(ec, error::insufficient_buffer, error::utf8_category) BOOST_PROCESS_V2_ASSIGN_EC(ec, error::insufficient_buffer, error::utf8_category);
break; break;
case ERROR_NO_UNICODE_TRANSLATION: case ERROR_NO_UNICODE_TRANSLATION:
BOOST_PROCESS_V2_ASSIGN_EC(ec, error::invalid_character, error::utf8_category) BOOST_PROCESS_V2_ASSIGN_EC(ec, error::invalid_character, error::utf8_category);
break; break;
default: default:
BOOST_PROCESS_V2_ASSIGN_EC(ec, err, system_category()) BOOST_PROCESS_V2_ASSIGN_EC(ec, err, system_category());
} }
} }
@@ -240,7 +240,7 @@ std::size_t convert_to_utf8(const wchar_t * in, std::size_t size,
if (*from > max_wchar) { if (*from > max_wchar) {
from_next = from; from_next = from;
to_next = to; to_next = to;
BOOST_PROCESS_V2_ASSIGN_EC(ec, error::invalid_character, error::get_utf8_category()) BOOST_PROCESS_V2_ASSIGN_EC(ec, error::invalid_character, error::get_utf8_category());
return 0u; return 0u;
} }
@@ -268,7 +268,7 @@ std::size_t convert_to_utf8(const wchar_t * in, std::size_t size,
if (to == to_end && i != cont_octet_count) { if (to == to_end && i != cont_octet_count) {
from_next = from; from_next = from;
to_next = to - (i + 1); to_next = to - (i + 1);
BOOST_PROCESS_V2_ASSIGN_EC(ec, error::insufficient_buffer, error::get_utf8_category()) BOOST_PROCESS_V2_ASSIGN_EC(ec, error::insufficient_buffer, error::get_utf8_category());
return 0u; return 0u;
} }
++from; ++from;
@@ -278,7 +278,7 @@ std::size_t convert_to_utf8(const wchar_t * in, std::size_t size,
// Were we done or did we run out of destination space // Were we done or did we run out of destination space
if (from != from_end) if (from != from_end)
BOOST_PROCESS_V2_ASSIGN_EC(ec, error::insufficient_buffer, error::get_utf8_category()) BOOST_PROCESS_V2_ASSIGN_EC(ec, error::insufficient_buffer, error::get_utf8_category());
return to_next - out; return to_next - out;
} }
@@ -313,7 +313,7 @@ std::size_t convert_to_wide(const char * in, std::size_t size,
if (invalid_leading_octet(*from)) { if (invalid_leading_octet(*from)) {
from_next = from; from_next = from;
to_next = to; to_next = to;
BOOST_PROCESS_V2_ASSIGN_EC(ec, error::invalid_character, error::get_utf8_category()) BOOST_PROCESS_V2_ASSIGN_EC(ec, error::invalid_character, error::get_utf8_category());
return 0u; return 0u;
} }
@@ -337,7 +337,7 @@ std::size_t convert_to_wide(const char * in, std::size_t size,
if (invalid_continuing_octet(*from)) { if (invalid_continuing_octet(*from)) {
from_next = from; from_next = from;
to_next = to; to_next = to;
BOOST_PROCESS_V2_ASSIGN_EC(ec, error::invalid_character, error::get_utf8_category()) BOOST_PROCESS_V2_ASSIGN_EC(ec, error::invalid_character, error::get_utf8_category());
return 0u; return 0u;
} }
@@ -354,7 +354,7 @@ std::size_t convert_to_wide(const char * in, std::size_t size,
// rewind "from" to before the current character translation // rewind "from" to before the current character translation
from_next = from - (i + 1); from_next = from - (i + 1);
to_next = to; to_next = to;
BOOST_PROCESS_V2_ASSIGN_EC(ec, error::insufficient_buffer, error::get_utf8_category()) BOOST_PROCESS_V2_ASSIGN_EC(ec, error::insufficient_buffer, error::get_utf8_category());
return 0u; return 0u;
} }
*to++ = ucs_result; *to++ = ucs_result;
@@ -363,7 +363,7 @@ std::size_t convert_to_wide(const char * in, std::size_t size,
to_next = to; to_next = to;
if (from != from_end) if (from != from_end)
BOOST_PROCESS_V2_ASSIGN_EC(ec, error::insufficient_buffer, error::get_utf8_category()) BOOST_PROCESS_V2_ASSIGN_EC(ec, error::insufficient_buffer, error::get_utf8_category());
return to_next - out; return to_next - out;
} }

View File

@@ -23,9 +23,12 @@
#endif #endif
#if (defined(__APPLE__) && defined(__MACH__)) #if (defined(__APPLE__) && defined(__MACH__))
#include <sys/proc_info.h> #include <TargetConditionals.h>
#include <sys/sysctl.h> #if !TARGET_OS_IOS
#include <libproc.h> #include <sys/proc_info.h>
#include <sys/sysctl.h>
#include <libproc.h>
#endif
#endif #endif
#if (defined(__linux__) || defined(__ANDROID__)) #if (defined(__linux__) || defined(__ANDROID__))
@@ -49,6 +52,7 @@
#endif #endif
#if defined(__sun) #if defined(__sun)
#include <cstdlib>
#include <sys/types.h> #include <sys/types.h>
#include <kvm.h> #include <kvm.h>
#include <sys/param.h> #include <sys/param.h>
@@ -156,7 +160,7 @@ shell cmd(boost::process::v2::pid_type pid, boost::system::error_code & ec)
} }
#elif (defined(__APPLE__) && defined(__MACH__)) #elif (defined(__APPLE__) && defined(__MACH__)) && !TARGET_OS_IOS
shell cmd(boost::process::v2::pid_type pid, boost::system::error_code & ec) shell cmd(boost::process::v2::pid_type pid, boost::system::error_code & ec)
{ {
@@ -165,7 +169,7 @@ shell cmd(boost::process::v2::pid_type pid, boost::system::error_code & ec)
auto size = sizeof(argmax); auto size = sizeof(argmax);
if (sysctl(mib, 2, &argmax, &size, nullptr, 0) == -1) if (sysctl(mib, 2, &argmax, &size, nullptr, 0) == -1)
{ {
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return {}; return {};
} }
@@ -178,7 +182,7 @@ shell cmd(boost::process::v2::pid_type pid, boost::system::error_code & ec)
if (sysctl(mib, 3, &*procargs.begin(), &size, nullptr, 0) != 0) if (sysctl(mib, 3, &*procargs.begin(), &size, nullptr, 0) != 0)
{ {
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return {}; return {};
} }
@@ -195,7 +199,7 @@ shell cmd(boost::process::v2::pid_type pid, boost::system::error_code & ec)
auto e = std::find(itr, end, '\0'); auto e = std::find(itr, end, '\0');
if (e == end && n < argc) // something off if (e == end && n < argc) // something off
{ {
BOOST_PROCESS_V2_ASSIGN_EC(ec, EINVAL, system_category()) BOOST_PROCESS_V2_ASSIGN_EC(ec, EINVAL, system_category());
return {}; return {};
} }
argv[n] = &*itr; argv[n] = &*itr;
@@ -220,7 +224,7 @@ shell cmd(boost::process::v2::pid_type pid, boost::system::error_code & ec)
auto r = ::read(f, &*(procargs.end() - 4096), 4096); auto r = ::read(f, &*(procargs.end() - 4096), 4096);
if (r < 0) if (r < 0)
{ {
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
::close(f); ::close(f);
return {}; return {};
} }
@@ -251,7 +255,7 @@ shell cmd(boost::process::v2::pid_type pid, boost::system::error_code & ec)
auto e = std::find(itr, end, '\0'); auto e = std::find(itr, end, '\0');
if (e == end && n < argc) // something off if (e == end && n < argc) // something off
{ {
BOOST_PROCESS_V2_ASSIGN_EC(ec, EINVAL, system_category()) BOOST_PROCESS_V2_ASSIGN_EC(ec, EINVAL, system_category());
return {}; return {};
} }
argv[n] = &*itr; argv[n] = &*itr;
@@ -271,6 +275,7 @@ shell cmd(boost::process::v2::pid_type pid, boost::system::error_code & ec)
kinfo_proc *proc_info = nullptr; kinfo_proc *proc_info = nullptr;
const char *nlistf, *memf; const char *nlistf, *memf;
nlistf = memf = "/dev/null"; nlistf = memf = "/dev/null";
struct closer struct closer
{ {
void operator()(kvm_t * kd) void operator()(kvm_t * kd)
@@ -280,17 +285,17 @@ shell cmd(boost::process::v2::pid_type pid, boost::system::error_code & ec)
}; };
std::unique_ptr<kvm_t, closer> kd{kvm_openfiles(nlistf, memf, nullptr, O_RDONLY, nullptr)}; std::unique_ptr<kvm_t, closer> kd{kvm_openfiles(nlistf, memf, nullptr, O_RDONLY, nullptr)};
if (!kd) {BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) return {};} if (!kd) {BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec); return {};}
if ((proc_info = kvm_getprocs(kd.get(), KERN_PROC_PID, pid, &cntp))) if ((proc_info = kvm_getprocs(kd.get(), KERN_PROC_PID, pid, &cntp)))
{ {
char **cmd = kvm_getargv(kd.get(), proc_info, 0); char **cmd = kvm_getargv(kd.get(), proc_info, 0);
if (cmd) if (cmd)
return make_cmd_shell_::clone(cmd); return make_cmd_shell_::clone(cmd);
else else
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
} }
else else
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return {}; return {};
} }
@@ -298,10 +303,9 @@ shell cmd(boost::process::v2::pid_type pid, boost::system::error_code & ec)
shell cmd(boost::process::v2::pid_type pid, boost::system::error_code & ec) shell cmd(boost::process::v2::pid_type pid, boost::system::error_code & ec)
{ {
std::vector<std::string> vec;
int cntp = 0; int cntp = 0;
kinfo_proc2 *proc_info = nullptr; kinfo_proc2 *proc_info = nullptr;
struct closer struct closer
{ {
void operator()(kvm_t * kd) void operator()(kvm_t * kd)
@@ -312,25 +316,24 @@ shell cmd(boost::process::v2::pid_type pid, boost::system::error_code & ec)
std::unique_ptr<kvm_t, closer> kd{kvm_openfiles(nullptr, nullptr, nullptr, KVM_NO_FILES, nullptr)}; std::unique_ptr<kvm_t, closer> kd{kvm_openfiles(nullptr, nullptr, nullptr, KVM_NO_FILES, nullptr)};
if (!kd) {BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) return vec;} if (!kd) {BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec); return {};}
if ((proc_info = kvm_getproc2(kd.get(), KERN_PROC_PID, pid, sizeof(struct kinfo_proc2), &cntp))) if ((proc_info = kvm_getproc2(kd.get(), KERN_PROC_PID, pid, sizeof(struct kinfo_proc2), &cntp)))
{ {
char **cmd = kvm_getargv2(kd.get(), proc_info, 0); char **cmd = kvm_getargv2(kd.get(), proc_info, 0);
if (cmd) if (cmd)
return make_cmd_shell_::clone(cmd); return make_cmd_shell_::clone(cmd);
else else
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
} }
else else
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return vec; return {};
} }
#elif defined(__OpenBSD__) #elif defined(__OpenBSD__)
shell cmd(boost::process::v2::pid_type pid, boost::system::error_code & ec) shell cmd(boost::process::v2::pid_type pid, boost::system::error_code & ec)
{ {
std::vector<std::string> vec;
int cntp = 0; int cntp = 0;
kinfo_proc *proc_info = nullptr; kinfo_proc *proc_info = nullptr;
@@ -343,18 +346,17 @@ shell cmd(boost::process::v2::pid_type pid, boost::system::error_code & ec)
}; };
std::unique_ptr<kvm_t, closer> kd{kvm_openfiles(nullptr, nullptr, nullptr, KVM_NO_FILES, nullptr)}; std::unique_ptr<kvm_t, closer> kd{kvm_openfiles(nullptr, nullptr, nullptr, KVM_NO_FILES, nullptr)};
if (!kd) {BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) return vec;} if (!kd) {BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec); return {};}
if ((proc_info = kvm_getprocs(kd.get(), KERN_PROC_PID, pid, sizeof(struct kinfo_proc), &cntp))) if ((proc_info = kvm_getprocs(kd.get(), KERN_PROC_PID, pid, sizeof(struct kinfo_proc), &cntp)))
{ {
char **cmd = kvm_getargv(kd.get(), proc_info, 0); char **cmd = kvm_getargv(kd.get(), proc_info, 0);
if (cmd) if (cmd)
return make_cmd_shell_::clone(cmd); return make_cmd_shell_::clone(cmd);
else else
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
} }
else else
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
kvm_close(kd);
return {}; return {};
} }
@@ -365,36 +367,47 @@ shell cmd(boost::process::v2::pid_type pid, boost::system::error_code & ec)
char **cmd = nullptr; char **cmd = nullptr;
proc *proc_info = nullptr; proc *proc_info = nullptr;
user *proc_user = nullptr; user *proc_user = nullptr;
kd = kvm_open(nullptr, nullptr, nullptr, O_RDONLY, nullptr);
if (!kd) {BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) return {};} struct closer
if ((proc_info = kvm_getproc(kd, pid)))
{ {
if ((proc_user = kvm_getu(kd, proc_info))) void operator()(kvm_t * kd)
{ {
if (!kvm_getcmd(kd, proc_info, proc_user, &cmd, nullptr)) kvm_close(kd);
}
};
std::unique_ptr<kvm_t, closer> kd{kvm_open(nullptr, nullptr, nullptr, O_RDONLY, nullptr)};
if (!kd) {BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec); return {};}
if ((proc_info = kvm_getproc(kd.get(), pid)))
{
if ((proc_user = kvm_getu(kd.get(), proc_info)))
{
if (!kvm_getcmd(kd.get(), proc_info, proc_user, &cmd, nullptr))
{ {
int argc = 0; int argc = 0;
for (int i = 0; cmd[i] != nullptr; i++) for (int i = 0; cmd[i] != nullptr; i++)
argc ++; argc++;
return make_cmd_shell_::make( return make_cmd_shell_::make(
{}, argc, cmd, {}, argc, cmd,
+[](int, char ** argv) {::free(argv);}) +[](int, char ** argv) {::free(argv);})
} }
else else
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
} }
else else
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
} }
else else
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
kvm_close(kd);
return {}; return {};
} }
#else #else
#error "Platform not supported" filesystem::path cmd(boost::process::v2::pid_type, boost::system::error_code & ec)
{
BOOST_PROCESS_V2_ASSIGN_EC(ec, ENOTSUP, system_category());
return "";
}
#endif #endif
shell cmd(boost::process::v2::pid_type pid) shell cmd(boost::process::v2::pid_type pid)

View File

@@ -24,8 +24,11 @@
#endif #endif
#if (defined(__APPLE__) && defined(__MACH__)) #if (defined(__APPLE__) && defined(__MACH__))
#include <sys/proc_info.h> #include <TargetConditionals.h>
#include <libproc.h> #if !TARGET_OS_IOS
#include <sys/proc_info.h>
#include <libproc.h>
#endif
#endif #endif
#if (defined(BOOST_PROCESS_V2_WINDOWS) || defined(__linux__) || defined(__ANDROID__) || defined(__sun)) #if (defined(BOOST_PROCESS_V2_WINDOWS) || defined(__linux__) || defined(__ANDROID__) || defined(__sun))
@@ -46,8 +49,10 @@
#endif #endif
#if defined(__DragonFly__) #if defined(__DragonFly__)
#include <climits>
#include <cstring> #include <cstring>
#include <cstdio> #include <sys/types.h>
#include <sys/sysctl.h>
#endif #endif
#ifdef BOOST_PROCESS_USE_STD_FS #ifdef BOOST_PROCESS_USE_STD_FS
@@ -68,7 +73,7 @@ filesystem::path cwd(HANDLE proc, boost::system::error_code & ec)
if (!buffer.empty()) if (!buffer.empty())
return filesystem::canonical(buffer, ec); return filesystem::canonical(buffer, ec);
else else
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return ""; return "";
} }
@@ -83,7 +88,7 @@ filesystem::path cwd(boost::process::v2::pid_type pid, boost::system::error_code
}; };
std::unique_ptr<void, del> proc{detail::ext::open_process_with_debug_privilege(pid, ec)}; std::unique_ptr<void, del> proc{detail::ext::open_process_with_debug_privilege(pid, ec)};
if (proc == nullptr) if (proc == nullptr)
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
else else
return cwd(proc.get(), ec); return cwd(proc.get(), ec);
return {}; return {};
@@ -98,7 +103,7 @@ filesystem::path cwd(HANDLE proc)
return res; return res;
} }
#elif (defined(__APPLE__) && defined(__MACH__)) #elif (defined(__APPLE__) && defined(__MACH__)) && !TARGET_OS_IOS
filesystem::path cwd(boost::process::v2::pid_type pid, boost::system::error_code & ec) filesystem::path cwd(boost::process::v2::pid_type pid, boost::system::error_code & ec)
{ {
@@ -106,7 +111,7 @@ filesystem::path cwd(boost::process::v2::pid_type pid, boost::system::error_code
if (proc_pidinfo(pid, PROC_PIDVNODEPATHINFO, 0, &vpi, sizeof(vpi)) > 0) if (proc_pidinfo(pid, PROC_PIDVNODEPATHINFO, 0, &vpi, sizeof(vpi)) > 0)
return filesystem::canonical(vpi.pvi_cdir.vip_path, ec); return filesystem::canonical(vpi.pvi_cdir.vip_path, ec);
else else
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return ""; return "";
} }
@@ -141,10 +146,10 @@ filesystem::path cwd(boost::process::v2::pid_type pid, boost::system::error_code
path = filesystem::canonical(kif.kf_path, ec); path = filesystem::canonical(kif.kf_path, ec);
} }
else else
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
} }
else else
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return path; return path;
} }
@@ -152,55 +157,16 @@ filesystem::path cwd(boost::process::v2::pid_type pid, boost::system::error_code
filesystem::path cwd(boost::process::v2::pid_type pid, boost::system::error_code & ec) filesystem::path cwd(boost::process::v2::pid_type pid, boost::system::error_code & ec)
{ {
/*
filesystem::path path; filesystem::path path;
// Official API (broken OS-level) - including code from DragonFly's fstat(1) char buffer[PATH_MAX];
// command line interface utility currently requires way too much code FWIW. std::size_t sz = 4, len = sizeof(buffer);
std::size_t sz = 4, len = 0;
int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_CWD, pid}; int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_CWD, pid};
if (sysctl(mib, sz, nullptr, &len, nullptr, 0) == 0) if (sysctl(mib, sz, buffer, &len, nullptr, 0) == 0)
{ {
std::vector<char> vecbuff; path = filesystem::canonical(buffer, ec);
vecbuff.resize(len);
if (sysctl(mib, sz, &vecbuff[0], &len, nullptr, 0) == 0)
{
path = filesystem::canonical(&vecbuff[0], ec);
}
else
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
} }
else else
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return path;
*/
filesystem::path path;
/* Probably the hackiest thing ever we are doing here, because the official API is broken OS-level. */
FILE *fp = popen(("pos=`ans=\\`/usr/bin/fstat -w -p " + std::to_string(pid) + " | /usr/bin/sed -n 1p\\`; " +
"/usr/bin/awk -v ans=\"$ans\" 'BEGIN{print index(ans, \"INUM\")}'`; str=`/usr/bin/fstat -w -p " +
std::to_string(pid) + " | /usr/bin/sed -n 3p`; /usr/bin/awk -v str=\"$str\" -v pos=\"$pos\" " +
"'BEGIN{print substr(str, 0, pos + 4)}' | /usr/bin/awk 'NF{NF--};1 {$1=$2=$3=$4=\"\"; print" +
" substr($0, 5)'}").c_str(), "r");
if (fp)
{
char buffer[PATH_MAX];
if (fgets(buffer, sizeof(buffer), fp))
{
std::string str = buffer;
std::size_t pos = str.find("\n", strlen(buffer) - 1);
if (pos != std::string::npos)
{
str.replace(pos, 1, "");
}
path = filesystem::canonical(str.c_str(), ec);
}
else
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
if (pclose(fp) == -1)
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
}
else
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
return path; return path;
} }
@@ -221,20 +187,24 @@ filesystem::path cwd(boost::process::v2::pid_type pid, boost::system::error_code
{ {
std::vector<char> vecbuff; std::vector<char> vecbuff;
vecbuff.resize(len); vecbuff.resize(len);
if (sysctl(mib, 4, &vecbuff[0], &len, nullptr, 0) == 0) if (sysctl(mib, sz, &vecbuff[0], &len, nullptr, 0) == 0)
{ {
path = filesystem::canonical(&vecbuff[0], ec); path = filesystem::canonical(&vecbuff[0], ec);
} }
else else
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
} }
else else
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return path; return path;
} }
#else #else
#error "Platform not supported" filesystem::path cwd(boost::process::v2::pid_type pid, boost::system::error_code & ec)
{
BOOST_PROCESS_V2_ASSIGN_EC(ec, ENOTSUP, system_category());
return "";
}
#endif #endif
filesystem::path cwd(boost::process::v2::pid_type pid) filesystem::path cwd(boost::process::v2::pid_type pid)

View File

@@ -21,9 +21,13 @@
#endif #endif
#if (defined(__APPLE__) && defined(__MACH__)) #if (defined(__APPLE__) && defined(__MACH__))
#include <sys/proc_info.h> #include <TargetConditionals.h>
#include <sys/sysctl.h> #if !TARGET_OS_IOS
#include <libproc.h> #include <algorithm>
#include <sys/proc_info.h>
#include <sys/sysctl.h>
#include <libproc.h>
#endif
#endif #endif
#if (defined(__linux__) || defined(__ANDROID__)) #if (defined(__linux__) || defined(__ANDROID__))
@@ -31,12 +35,50 @@
#endif #endif
#if defined(__FreeBSD__) #if defined(__FreeBSD__)
#include <sys/socket.h> #include <algorithm>
#include <sys/sysctl.h> #include <cstring>
#include <fcntl.h>
#include <kvm.h>
#include <sys/param.h> #include <sys/param.h>
#include <sys/queue.h> #include <sys/sysctl.h>
#include <sys/user.h> #include <sys/user.h>
#include <libprocstat.h> #endif
#if defined(__DragonFly__)
#include <algorithm>
#include <cstring>
#include <sys/types.h>
#include <kvm.h>
#endif
#if defined(__NetBSD__)
#include <algorithm>
#include <cstring>
#include <fcntl.h>
#include <kvm.h>
#include <sys/param.h>
#include <sys/sysctl.h>
#endif
#if defined(__OpenBSD__)
#include <algorithm>
#include <cstring>
#include <sys/param.h>
#include <sys/sysctl.h>
#include <fcntl.h>
#include <kvm.h>
#endif
#if defined(__sun)
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <kvm.h>
#include <fcntl.h>
#include <sys/param.h>
#include <sys/time.h>
#include <sys/user.h>
#include <sys/proc.h>
#endif #endif
BOOST_PROCESS_V2_BEGIN_NAMESPACE BOOST_PROCESS_V2_BEGIN_NAMESPACE
@@ -95,7 +137,7 @@ const environment::char_type * dereference(native_env_iterator iterator)
return iterator; return iterator;
} }
#elif (defined(__APPLE___) || defined(__MACH__)) #elif (defined(__APPLE___) || defined(__MACH__)) || defined(__FreeBSD__) || defined(__DragonFly__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__sun)
void native_env_handle_deleter::operator()(native_env_handle_type h) const void native_env_handle_deleter::operator()(native_env_handle_type h) const
{ {
@@ -120,31 +162,6 @@ const environment::char_type * dereference(native_env_iterator iterator)
return iterator; return iterator;
} }
#elif defined(__FreeBSD__)
void native_env_handle_deleter::operator()(native_env_handle_type h) const
{
delete [] h;
}
native_env_iterator next(native_env_iterator nh)
{
return ++nh ;
}
native_env_iterator find_end(native_env_iterator nh)
{
while (*nh != nullptr)
nh++;
return nh ;
}
const environment::char_type * dereference(native_env_iterator iterator)
{
return *iterator;
}
#endif #endif
} }
@@ -171,19 +188,19 @@ env_view env(HANDLE proc, boost::system::error_code & ec)
if (error) if (error)
{ {
BOOST_PROCESS_V2_ASSIGN_EC(ec, error, boost::system::system_category()) BOOST_PROCESS_V2_ASSIGN_EC(ec, error, system_category());
return {}; return {};
} }
if (!ReadProcessMemory(proc, pbi.PebBaseAddress, &peb, sizeof(peb), &nRead)) if (!ReadProcessMemory(proc, pbi.PebBaseAddress, &peb, sizeof(peb), &nRead))
{ {
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return {}; return {};
} }
if (!ReadProcessMemory(proc, peb.ProcessParameters, &upp, sizeof(upp), &nRead)) if (!ReadProcessMemory(proc, peb.ProcessParameters, &upp, sizeof(upp), &nRead))
{ {
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return {}; return {};
} }
@@ -194,7 +211,7 @@ env_view env(HANDLE proc, boost::system::error_code & ec)
if (!ReadProcessMemory(proc, buf, ev.handle_.get(), len, &nRead)) if (!ReadProcessMemory(proc, buf, ev.handle_.get(), len, &nRead))
{ {
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return {}; return {};
} }
@@ -222,14 +239,14 @@ env_view env(boost::process::v2::pid_type pid, boost::system::error_code & ec)
}; };
std::unique_ptr<void, del> proc{detail::ext::open_process_with_debug_privilege(pid, ec)}; std::unique_ptr<void, del> proc{detail::ext::open_process_with_debug_privilege(pid, ec)};
if (proc == nullptr) if (proc == nullptr)
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
else else
return env(proc.get(), ec); return env(proc.get(), ec);
return {}; return {};
} }
#elif (defined(__APPLE___) || defined(__MACH__)) #elif (defined(__APPLE___) || defined(__MACH__)) && !TARGET_OS_IOS
env_view env(boost::process::v2::pid_type pid, boost::system::error_code & ec) env_view env(boost::process::v2::pid_type pid, boost::system::error_code & ec)
{ {
@@ -238,7 +255,7 @@ env_view env(boost::process::v2::pid_type pid, boost::system::error_code & ec)
auto size = sizeof(argmax); auto size = sizeof(argmax);
if (sysctl(mib, 2, &argmax, &size, nullptr, 0) == -1) if (sysctl(mib, 2, &argmax, &size, nullptr, 0) == -1)
{ {
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return {}; return {};
} }
@@ -251,7 +268,7 @@ env_view env(boost::process::v2::pid_type pid, boost::system::error_code & ec)
if (sysctl(mib, 3, &*procargs.begin(), &size, nullptr, 0) != 0) if (sysctl(mib, 3, &*procargs.begin(), &size, nullptr, 0) != 0)
{ {
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return {}; return {};
} }
std::uint32_t nargs; std::uint32_t nargs;
@@ -309,7 +326,7 @@ env_view env(boost::process::v2::pid_type pid, boost::system::error_code & ec)
auto r = ::read(f, buf.get() + size, 4096); auto r = ::read(f, buf.get() + size, 4096);
if (r < 0) if (r < 0)
{ {
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
::close(f); ::close(f);
return {}; return {};
} }
@@ -328,69 +345,175 @@ env_view env(boost::process::v2::pid_type pid, boost::system::error_code & ec)
return ev; return ev;
} }
#elif defined(__FreeBSD__) #elif defined(__FreeBSD__) || defined(__DragonFly__)
env_view env(boost::process::v2::pid_type pid, boost::system::error_code & ec) env_view env(boost::process::v2::pid_type pid, boost::system::error_code & ec)
{ {
env_view ev; std::vector<char> vec;
int cntp = 0;
kinfo_proc *proc_info = nullptr;
const char *nlistf, *memf;
nlistf = memf = "/dev/null";
unsigned cntp = 0; struct closer
procstat *proc_stat = procstat_open_sysctl();
if (proc_stat != nullptr)
{ {
kinfo_proc *proc_info = procstat_getprocs(proc_stat, KERN_PROC_PID, pid, &cntp); void operator()(kvm_t * kd)
if (proc_info != nullptr)
{ {
char **env = procstat_getenvv(proc_stat, proc_info, 0); kvm_close(kd);
if (env != nullptr) }
};
std::unique_ptr<kvm_t, closer> kd{kvm_openfiles(nlistf, memf, nullptr, O_RDONLY, nullptr)};
if (!kd) {BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec); return {};}
if ((proc_info = kvm_getprocs(kd.get(), KERN_PROC_PID, pid, &cntp))) {
char **env = kvm_getenvv(kd.get(), proc_info, 0);
if (env) {
for (int i = 0; env[i] != nullptr; i++)
{ {
auto e = env; for (int j = 0; j < strlen(env[i]); j++)
std::size_t n = 0u, len = 0u; vec.push_back(env[i][j]);
while (e && *e != nullptr) vec.push_back('\0');
{
n ++;
len += std::strlen(*e);
e++;
}
std::size_t mem_needed =
// environ - nullptr - strlen + null terminators
(n * sizeof(char*)) + sizeof(char*) + len + n;
char * out = new (std::nothrow) char[mem_needed];
if (out != nullptr)
{
auto eno = reinterpret_cast<char**>(out);
auto eeo = eno;
auto str = out + (n * sizeof(char*)) + sizeof(char*);
e = env;
while (*e != nullptr)
{
auto len = std::strlen(*e) + 1u;
std::memcpy(str, *e, len);
*eno = str;
str += len;
eno ++;
e++;
}
*eno = nullptr;
ev.handle_.reset(eeo);
}
else
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec)
} }
procstat_freeprocs(proc_stat, proc_info); vec.push_back('\0');
} }
else else
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
procstat_close(proc_stat);
} }
else else
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
env_view ev;
ev.handle_.reset(new char[vec.size()]());
std::copy(vec.begin(), vec.end(), ev.handle_.get());
return ev; return ev;
} }
#elif defined(__NetBSD__)
env_view env(boost::process::v2::pid_type pid, boost::system::error_code & ec)
{
std::vector<char> vec;
int cntp = 0;
kinfo_proc2 *proc_info = nullptr;
struct closer
{
void operator()(kvm_t * kd)
{
kvm_close(kd);
}
};
std::unique_ptr<kvm_t, closer> kd{kvm_openfiles(nullptr, nullptr, nullptr, KVM_NO_FILES, nullptr)};
if (!kd) {BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec); return {};}
if ((proc_info = kvm_getproc2(kd.get(), KERN_PROC_PID, pid, sizeof(struct kinfo_proc2), &cntp))) {
char **env = kvm_getenvv2(kd.get(), proc_info, 0);
if (env) {
for (int i = 0; env[i] != nullptr; i++)
{
for (int j = 0; j < strlen(env[i]); j++)
vec.push_back(env[i][j]);
vec.push_back('\0');
}
vec.push_back('\0');
}
else
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
}
else
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
env_view ev;
ev.handle_.reset(new char[vec.size()]());
std::copy(vec.begin(), vec.end(), ev.handle_.get());
return ev;
}
#elif defined(__OpenBSD__)
env_view env(boost::process::v2::pid_type pid, boost::system::error_code & ec)
{
std::vector<char> vec;
int cntp = 0;
kinfo_proc *proc_info = nullptr;
struct closer
{
void operator()(kvm_t * kd)
{
kvm_close(kd);
}
};
std::unique_ptr<kvm_t, closer> kd{kvm_openfiles(nullptr, nullptr, nullptr, KVM_NO_FILES, nullptr)};
if (!kd) {BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec); return {};}
if ((proc_info = kvm_getprocs(kd.get(), KERN_PROC_PID, pid, sizeof(struct kinfo_proc), &cntp)))
{
char **env = kvm_getenvv(kd.get(), proc_info, 0);
if (env)
{
for (int i = 0; env[i] != nullptr; i++)
{
for (int j = 0; j < strlen(env[i]); j++)
vec.push_back(env[i][j]);
vec.push_back('\0');
}
vec.push_back('\0');
}
else
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
}
else
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
env_view ev;
ev.handle_.reset(new char[vec.size()]());
std::copy(vec.begin(), vec.end(), ev.handle_.get());
return ev;
}
#elif defined(__sun)
env_view env(boost::process::v2::pid_type pid, boost::system::error_code & ec)
{
std::vector<char> vec;
char **env = nullptr;
proc *proc_info = nullptr;
user *proc_user = nullptr;
struct closer
{
void operator()(kvm_t * kd)
{
kvm_close(kd);
}
};
std::unique_ptr<kvm_t, closer> kd{kvm_open(nullptr, nullptr, nullptr, O_RDONLY, nullptr)};
if (!kd) {BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec); return {};}
if ((proc_info = kvm_getproc(kd.get(), pid)))
{
if ((proc_user = kvm_getu(kd.get(), proc_info)))
{
if (!kvm_getcmd(kd.get(), proc_info, proc_user, nullptr, &env))
{
for (int i = 0; env[i] != nullptr; i++)
{
for (int j = 0; j < strlen(env[i]); j++)
vec.push_back(env[i][j]);
vec.push_back('\0');
}
vec.push_back('\0');
free(env);
}
else
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
}
else
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
}
else
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
env_view ev;
ev.handle_.reset(new char[vec.size()]());
std::copy(vec.begin(), vec.end(), ev.handle_.get());
return ev;
}
#endif #endif
env_view env(boost::process::v2::pid_type pid) env_view env(boost::process::v2::pid_type pid)

View File

@@ -25,8 +25,11 @@
#endif #endif
#if (defined(__APPLE__) && defined(__MACH__)) #if (defined(__APPLE__) && defined(__MACH__))
#include <sys/proc_info.h> #include <TargetConditionals.h>
#include <libproc.h> #if !TARGET_OS_IOS
#include <sys/proc_info.h>
#include <libproc.h>
#endif
#endif #endif
#if (defined(BOOST_PROCESS_V2_WINDOWS) || defined(__linux__) || defined(__ANDROID__) || defined(__sun)) #if (defined(BOOST_PROCESS_V2_WINDOWS) || defined(__linux__) || defined(__ANDROID__) || defined(__sun))
@@ -36,7 +39,7 @@
#if (defined(__FreeBSD__) || defined(__DragonFly__) || defined(__NetBSD__)) #if (defined(__FreeBSD__) || defined(__DragonFly__) || defined(__NetBSD__))
#include <sys/types.h> #include <sys/types.h>
#include <sys/sysctl.h> #include <sys/sysctl.h>
#if !defined(__FreeBSD__) #if !defined(__FreeBSD__) && !defined(__NetBSD__)
#include <alloca.h> #include <alloca.h>
#endif #endif
#endif #endif
@@ -80,7 +83,7 @@ filesystem::path exe(HANDLE proc, boost::system::error_code & ec)
return filesystem::canonical(buffer, ec); return filesystem::canonical(buffer, ec);
} }
else else
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return ""; return "";
} }
@@ -106,14 +109,14 @@ filesystem::path exe(boost::process::v2::pid_type pid, boost::system::error_code
}; };
std::unique_ptr<void, del> proc{detail::ext::open_process_with_debug_privilege(pid, ec)}; std::unique_ptr<void, del> proc{detail::ext::open_process_with_debug_privilege(pid, ec)};
if (proc == nullptr) if (proc == nullptr)
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
else else
return exe(proc.get(), ec); return exe(proc.get(), ec);
} }
return ""; return "";
} }
#elif (defined(__APPLE__) && defined(__MACH__)) #elif (defined(__APPLE__) && defined(__MACH__)) && !TARGET_OS_IOS
filesystem::path exe(boost::process::v2::pid_type pid, boost::system::error_code & ec) filesystem::path exe(boost::process::v2::pid_type pid, boost::system::error_code & ec)
{ {
@@ -122,7 +125,7 @@ filesystem::path exe(boost::process::v2::pid_type pid, boost::system::error_code
{ {
return filesystem::canonical(buffer, ec); return filesystem::canonical(buffer, ec);
} }
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return ""; return "";
} }
@@ -162,7 +165,7 @@ filesystem::path exe(boost::process::v2::pid_type pid, boost::system::error_code
} }
} }
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return ""; return "";
} }
@@ -170,12 +173,16 @@ filesystem::path exe(boost::process::v2::pid_type pid, boost::system::error_code
filesystem::path exe(boost::process::v2::pid_type pid, boost::system::error_code & ec) filesystem::path exe(boost::process::v2::pid_type pid, boost::system::error_code & ec)
{ {
BOOST_PROCESS_V2_ASSIGN_EC(ec, ENOTSUP, boost::system::system_category()) BOOST_PROCESS_V2_ASSIGN_EC(ec, ENOTSUP, system_category());
return ""; return "";
} }
#else #else
#error "Platform not supported" filesystem::path exe(boost::process::v2::pid_type pid, boost::system::error_code & ec)
{
BOOST_PROCESS_V2_ASSIGN_EC(ec, ENOTSUP, system_category());
return "";
}
#endif #endif
filesystem::path exe(boost::process::v2::pid_type pid) filesystem::path exe(boost::process::v2::pid_type pid)

View File

@@ -16,14 +16,6 @@
#include <string> #include <string>
#if (defined(__APPLE__) && defined(__MACH__))
#include <cstdlib>
#include <sys/types.h>
#include <sys/sysctl.h>
#include <sys/proc_info.h>
#include <libproc.h>
#endif
BOOST_PROCESS_V2_BEGIN_NAMESPACE BOOST_PROCESS_V2_BEGIN_NAMESPACE
namespace detail namespace detail
@@ -51,19 +43,19 @@ std::wstring cwd_cmd_from_proc(HANDLE proc, int type, boost::system::error_code
if (error) if (error)
{ {
BOOST_PROCESS_V2_ASSIGN_EC(ec, error, boost::system::system_category()) BOOST_PROCESS_V2_ASSIGN_EC(ec, error, system_category());
return {}; return {};
} }
if (!ReadProcessMemory(proc, pbi.PebBaseAddress, &peb, sizeof(peb), &nRead)) if (!ReadProcessMemory(proc, pbi.PebBaseAddress, &peb, sizeof(peb), &nRead))
{ {
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return {}; return {};
} }
if (!ReadProcessMemory(proc, peb.ProcessParameters, &upp, sizeof(upp), &nRead)) if (!ReadProcessMemory(proc, peb.ProcessParameters, &upp, sizeof(upp), &nRead))
{ {
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return {}; return {};
} }
@@ -82,7 +74,7 @@ std::wstring cwd_cmd_from_proc(HANDLE proc, int type, boost::system::error_code
if (!ReadProcessMemory(proc, buf, &buffer[0], len, &nRead)) if (!ReadProcessMemory(proc, buf, &buffer[0], len, &nRead))
{ {
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return {}; return {};
} }
@@ -115,7 +107,7 @@ HANDLE open_process_with_debug_privilege(boost::process::v2::pid_type pid, boost
if (!proc) if (!proc)
proc = OpenProcess(PROCESS_ALL_ACCESS, false, pid); proc = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
if (!proc) if (!proc)
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return proc; return proc;
} }
#endif #endif

View File

@@ -17,8 +17,11 @@
#endif #endif
#if (defined(__APPLE__) && defined(__MACH__)) #if (defined(__APPLE__) && defined(__MACH__))
#include <sys/proc_info.h> #include <TargetConditionals.h>
#include <libproc.h> #if !TARGET_OS_IOS
#include <sys/proc_info.h>
#include <libproc.h>
#endif
#endif #endif
#if (defined(__linux__) || defined(__ANDROID__)) #if (defined(__linux__) || defined(__ANDROID__))
@@ -26,10 +29,11 @@
#endif #endif
#if defined(__FreeBSD__) #if defined(__FreeBSD__)
#include <sys/types.h> #include <fcntl.h>
#include <kvm.h>
#include <sys/param.h>
#include <sys/sysctl.h>
#include <sys/user.h> #include <sys/user.h>
#include <libutil.h>
#include <cstdlib>
#endif #endif
#if (defined(__DragonFly__) || defined(__OpenBSD__)) #if (defined(__DragonFly__) || defined(__OpenBSD__))
@@ -71,7 +75,7 @@ std::vector<pid_type> all_pids(boost::system::error_code & ec)
HANDLE hp = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); HANDLE hp = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (!hp) if (!hp)
{ {
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return vec; return vec;
} }
PROCESSENTRY32 pe; PROCESSENTRY32 pe;
@@ -93,7 +97,7 @@ pid_type parent_pid(pid_type pid, boost::system::error_code & ec)
HANDLE hp = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); HANDLE hp = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (!hp) if (!hp)
{ {
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return ppid; return ppid;
} }
PROCESSENTRY32 pe; PROCESSENTRY32 pe;
@@ -120,7 +124,7 @@ std::vector<pid_type> child_pids(pid_type pid, boost::system::error_code & ec)
HANDLE hp = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); HANDLE hp = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (!hp) if (!hp)
{ {
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return vec; return vec;
} }
PROCESSENTRY32 pe; PROCESSENTRY32 pe;
@@ -140,7 +144,7 @@ std::vector<pid_type> child_pids(pid_type pid, boost::system::error_code & ec)
return vec; return vec;
} }
#elif (defined(__APPLE__) && defined(__MACH__)) #elif (defined(__APPLE__) && defined(__MACH__)) && !TARGET_OS_IOS
std::vector<pid_type> all_pids(boost::system::error_code & ec) std::vector<pid_type> all_pids(boost::system::error_code & ec)
{ {
@@ -149,7 +153,7 @@ std::vector<pid_type> all_pids(boost::system::error_code & ec)
const auto sz = proc_listpids(PROC_ALL_PIDS, 0, &vec[0], sizeof(pid_type) * vec.size()); const auto sz = proc_listpids(PROC_ALL_PIDS, 0, &vec[0], sizeof(pid_type) * vec.size());
if (sz < 0) if (sz < 0)
{ {
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return {}; return {};
} }
vec.resize(sz); vec.resize(sz);
@@ -162,7 +166,7 @@ pid_type parent_pid(pid_type pid, boost::system::error_code & ec)
proc_bsdinfo proc_info; proc_bsdinfo proc_info;
if (proc_pidinfo(pid, PROC_PIDTBSDINFO, 0, &proc_info, sizeof(proc_info)) <= 0) if (proc_pidinfo(pid, PROC_PIDTBSDINFO, 0, &proc_info, sizeof(proc_info)) <= 0)
{ {
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return ppid; return ppid;
} }
else else
@@ -177,7 +181,7 @@ std::vector<pid_type> child_pids(pid_type pid, boost::system::error_code & ec)
const auto sz = proc_listpids(PROC_PPID_ONLY, (uint32_t)pid, &vec[0], sizeof(pid_type) * vec.size()); const auto sz = proc_listpids(PROC_PPID_ONLY, (uint32_t)pid, &vec[0], sizeof(pid_type) * vec.size());
if (sz < 0) if (sz < 0)
{ {
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return {}; return {};
} }
vec.resize(sz); vec.resize(sz);
@@ -192,7 +196,7 @@ std::vector<pid_type> all_pids(boost::system::error_code & ec)
DIR *proc = opendir("/proc"); DIR *proc = opendir("/proc");
if (!proc) if (!proc)
{ {
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return vec; return vec;
} }
struct dirent *ent = nullptr; struct dirent *ent = nullptr;
@@ -215,9 +219,9 @@ pid_type parent_pid(pid_type pid, boost::system::error_code & ec)
if (!stat) if (!stat)
{ {
if (errno == ENOENT) if (errno == ENOENT)
BOOST_PROCESS_V2_ASSIGN_EC(ec, ESRCH, system_category()) BOOST_PROCESS_V2_ASSIGN_EC(ec, ESRCH, system_category());
else else
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return ppid; return ppid;
} }
else else
@@ -242,7 +246,7 @@ pid_type parent_pid(pid_type pid, boost::system::error_code & ec)
if (!token) if (!token)
{ {
fclose(stat); fclose(stat);
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return ppid; return ppid;
} }
} }
@@ -274,30 +278,63 @@ std::vector<pid_type> all_pids(boost::system::error_code & ec)
{ {
std::vector<pid_type> vec; std::vector<pid_type> vec;
int cntp = 0; int cntp = 0;
kinfo_proc *proc_info = kinfo_getallproc(&cntp); kinfo_proc *proc_info = nullptr;
if (proc_info) const char *nlistf, *memf;
nlistf = memf = "/dev/null";
struct closer
{
void operator()(kvm_t * kd)
{
kvm_close(kd);
}
};
std::unique_ptr<kvm_t, closer> kd{kvm_openfiles(nlistf, memf, nullptr, O_RDONLY, nullptr)};
if (!kd)
{
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return vec;
}
if ((proc_info = kvm_getprocs(kd.get(), KERN_PROC_ALL, 0, &cntp)))
{ {
vec.reserve(cntp); vec.reserve(cntp);
for (int i = 0; i < cntp; i++) for (int i = 0; i < cntp; i++)
vec.push_back(proc_info[i].ki_pid); vec.push_back(proc_info[i].ki_pid);
free(proc_info);
} }
else else
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return vec; return vec;
} }
pid_type parent_pid(pid_type pid, boost::system::error_code & ec) pid_type parent_pid(pid_type pid, boost::system::error_code & ec)
{ {
pid_type ppid = static_cast<pid_type>(-1); pid_type ppid = static_cast<pid_type>(-1);
kinfo_proc *proc_info = kinfo_getproc(pid); int cntp = 0;
if (proc_info) kinfo_proc *proc_info = nullptr;
const char *nlistf, *memf;
nlistf = memf = "/dev/null";
struct closer
{
void operator()(kvm_t * kd)
{
kvm_close(kd);
}
};
std::unique_ptr<kvm_t, closer> kd{kvm_openfiles(nlistf, memf, nullptr, O_RDONLY, nullptr)};
if (!kd)
{
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return ppid;
}
if ((proc_info = kvm_getprocs(kd.get(), KERN_PROC_PID, pid, &cntp)))
{ {
ppid = proc_info->ki_ppid; ppid = proc_info->ki_ppid;
free(proc_info);
} }
else else
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return ppid; return ppid;
} }
@@ -305,8 +342,25 @@ std::vector<pid_type> child_pids(pid_type pid, boost::system::error_code & ec)
{ {
std::vector<pid_type> vec; std::vector<pid_type> vec;
int cntp = 0; int cntp = 0;
kinfo_proc *proc_info = kinfo_getallproc(&cntp); kinfo_proc *proc_info = nullptr;
if (proc_info) const char *nlistf, *memf;
nlistf = memf = "/dev/null";
struct closer
{
void operator()(kvm_t * kd)
{
kvm_close(kd);
}
};
std::unique_ptr<kvm_t, closer> kd{kvm_openfiles(nlistf, memf, nullptr, O_RDONLY, nullptr)};
if (!kd)
{
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return vec;
}
if ((proc_info = kvm_getprocs(kd.get(), KERN_PROC_ALL, 0, &cntp)))
{ {
vec.reserve(cntp); vec.reserve(cntp);
for (int i = 0; i < cntp; i++) for (int i = 0; i < cntp; i++)
@@ -316,10 +370,9 @@ std::vector<pid_type> child_pids(pid_type pid, boost::system::error_code & ec)
vec.push_back(proc_info[i].ki_pid); vec.push_back(proc_info[i].ki_pid);
} }
} }
free(proc_info);
} }
else else
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return vec; return vec;
} }
@@ -332,6 +385,7 @@ std::vector<pid_type> all_pids(boost::system::error_code & ec)
kinfo_proc *proc_info = nullptr; kinfo_proc *proc_info = nullptr;
const char *nlistf, *memf; const char *nlistf, *memf;
nlistf = memf = "/dev/null"; nlistf = memf = "/dev/null";
struct closer struct closer
{ {
void operator()(kvm_t * kd) void operator()(kvm_t * kd)
@@ -343,7 +397,7 @@ std::vector<pid_type> all_pids(boost::system::error_code & ec)
std::unique_ptr<kvm_t, closer> kd{kvm_openfiles(nlistf, memf, nullptr, O_RDONLY, nullptr)}; std::unique_ptr<kvm_t, closer> kd{kvm_openfiles(nlistf, memf, nullptr, O_RDONLY, nullptr)};
if (!kd) if (!kd)
{ {
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return vec; return vec;
} }
if ((proc_info = kvm_getprocs(kd.get(), KERN_PROC_ALL, 0, &cntp))) if ((proc_info = kvm_getprocs(kd.get(), KERN_PROC_ALL, 0, &cntp)))
@@ -354,7 +408,7 @@ std::vector<pid_type> all_pids(boost::system::error_code & ec)
vec.push_back(proc_info[i].kp_pid); vec.push_back(proc_info[i].kp_pid);
} }
else else
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return vec; return vec;
} }
@@ -365,6 +419,7 @@ pid_type parent_pid(pid_type pid, boost::system::error_code & ec)
kinfo_proc *proc_info = nullptr; kinfo_proc *proc_info = nullptr;
const char *nlistf, *memf; const char *nlistf, *memf;
nlistf = memf = "/dev/null"; nlistf = memf = "/dev/null";
struct closer struct closer
{ {
void operator()(kvm_t * kd) void operator()(kvm_t * kd)
@@ -376,7 +431,7 @@ pid_type parent_pid(pid_type pid, boost::system::error_code & ec)
std::unique_ptr<kvm_t, closer> kd{kvm_openfiles(nlistf, memf, nullptr, O_RDONLY, nullptr)}; std::unique_ptr<kvm_t, closer> kd{kvm_openfiles(nlistf, memf, nullptr, O_RDONLY, nullptr)};
if (!kd) if (!kd)
{ {
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return ppid; return ppid;
} }
if ((proc_info = kvm_getprocs(kd.get(), KERN_PROC_PID, pid, &cntp))) if ((proc_info = kvm_getprocs(kd.get(), KERN_PROC_PID, pid, &cntp)))
@@ -387,7 +442,7 @@ pid_type parent_pid(pid_type pid, boost::system::error_code & ec)
} }
} }
else else
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return ppid; return ppid;
} }
@@ -398,6 +453,7 @@ std::vector<pid_type> child_pids(pid_type pid, boost::system::error_code & ec)
kinfo_proc *proc_info = nullptr; kinfo_proc *proc_info = nullptr;
const char *nlistf, *memf; const char *nlistf, *memf;
nlistf = memf = "/dev/null"; nlistf = memf = "/dev/null";
struct closer struct closer
{ {
void operator()(kvm_t * kd) void operator()(kvm_t * kd)
@@ -409,7 +465,7 @@ std::vector<pid_type> child_pids(pid_type pid, boost::system::error_code & ec)
std::unique_ptr<kvm_t, closer> kd{kvm_openfiles(nlistf, memf, nullptr, O_RDONLY, nullptr)}; std::unique_ptr<kvm_t, closer> kd{kvm_openfiles(nlistf, memf, nullptr, O_RDONLY, nullptr)};
if (!kd) if (!kd)
{ {
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return vec; return vec;
} }
if ((proc_info = kvm_getprocs(kd.get(), KERN_PROC_ALL, 0, &cntp))) if ((proc_info = kvm_getprocs(kd.get(), KERN_PROC_ALL, 0, &cntp)))
@@ -424,7 +480,7 @@ std::vector<pid_type> child_pids(pid_type pid, boost::system::error_code & ec)
} }
} }
else else
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return vec; return vec;
} }
@@ -435,6 +491,7 @@ std::vector<pid_type> all_pids(boost::system::error_code & ec)
std::vector<pid_type> vec; std::vector<pid_type> vec;
int cntp = 0; int cntp = 0;
kinfo_proc2 *proc_info = nullptr; kinfo_proc2 *proc_info = nullptr;
struct closer struct closer
{ {
void operator()(kvm_t * kd) void operator()(kvm_t * kd)
@@ -446,7 +503,7 @@ std::vector<pid_type> all_pids(boost::system::error_code & ec)
std::unique_ptr<kvm_t, closer> kd{kvm_openfiles(nullptr, nullptr, nullptr, KVM_NO_FILES, nullptr)}; std::unique_ptr<kvm_t, closer> kd{kvm_openfiles(nullptr, nullptr, nullptr, KVM_NO_FILES, nullptr)};
if (!kd) if (!kd)
{ {
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return vec; return vec;
} }
if ((proc_info = kvm_getproc2(kd.get(), KERN_PROC_ALL, 0, sizeof(struct kinfo_proc2), &cntp))) if ((proc_info = kvm_getproc2(kd.get(), KERN_PROC_ALL, 0, sizeof(struct kinfo_proc2), &cntp)))
@@ -458,7 +515,7 @@ std::vector<pid_type> all_pids(boost::system::error_code & ec)
} }
} }
else else
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return vec; return vec;
} }
@@ -467,6 +524,7 @@ pid_type parent_pid(pid_type pid, boost::system::error_code & ec)
pid_type ppid = static_cast<pid_type>(-1); pid_type ppid = static_cast<pid_type>(-1);
int cntp = 0; int cntp = 0;
kinfo_proc2 *proc_info = nullptr; kinfo_proc2 *proc_info = nullptr;
struct closer struct closer
{ {
void operator()(kvm_t * kd) void operator()(kvm_t * kd)
@@ -478,7 +536,7 @@ pid_type parent_pid(pid_type pid, boost::system::error_code & ec)
std::unique_ptr<kvm_t, closer> kd{kvm_openfiles(nullptr, nullptr, nullptr, KVM_NO_FILES, nullptr)}; std::unique_ptr<kvm_t, closer> kd{kvm_openfiles(nullptr, nullptr, nullptr, KVM_NO_FILES, nullptr)};
if (!kd) if (!kd)
{ {
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return ppid; return ppid;
} }
if ((proc_info = kvm_getproc2(kd.get(), KERN_PROC_PID, pid, sizeof(struct kinfo_proc2), &cntp))) if ((proc_info = kvm_getproc2(kd.get(), KERN_PROC_PID, pid, sizeof(struct kinfo_proc2), &cntp)))
@@ -486,7 +544,7 @@ pid_type parent_pid(pid_type pid, boost::system::error_code & ec)
ppid = proc_info->p_ppid; ppid = proc_info->p_ppid;
} }
else else
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return ppid; return ppid;
} }
@@ -495,6 +553,7 @@ std::vector<pid_type> child_pids(pid_type pid, boost::system::error_code & ec)
std::vector<pid_type> vec; std::vector<pid_type> vec;
int cntp = 0; int cntp = 0;
kinfo_proc2 *proc_info = nullptr; kinfo_proc2 *proc_info = nullptr;
struct closer struct closer
{ {
void operator()(kvm_t * kd) void operator()(kvm_t * kd)
@@ -506,7 +565,7 @@ std::vector<pid_type> child_pids(pid_type pid, boost::system::error_code & ec)
std::unique_ptr<kvm_t, closer> kd{kvm_openfiles(nullptr, nullptr, nullptr, KVM_NO_FILES, nullptr)}; std::unique_ptr<kvm_t, closer> kd{kvm_openfiles(nullptr, nullptr, nullptr, KVM_NO_FILES, nullptr)};
if (!kd) if (!kd)
{ {
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return vec; return vec;
} }
if ((proc_info = kvm_getproc2(kd.get(), KERN_PROC_ALL, 0, sizeof(struct kinfo_proc2), &cntp))) if ((proc_info = kvm_getproc2(kd.get(), KERN_PROC_ALL, 0, sizeof(struct kinfo_proc2), &cntp)))
@@ -521,7 +580,7 @@ std::vector<pid_type> child_pids(pid_type pid, boost::system::error_code & ec)
} }
} }
else else
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return vec; return vec;
} }
@@ -532,6 +591,7 @@ std::vector<pid_type> all_pids(boost::system::error_code & ec)
std::vector<pid_type> vec; std::vector<pid_type> vec;
int cntp = 0; int cntp = 0;
kinfo_proc *proc_info = nullptr; kinfo_proc *proc_info = nullptr;
struct closer struct closer
{ {
void operator()(kvm_t * kd) void operator()(kvm_t * kd)
@@ -543,7 +603,7 @@ std::vector<pid_type> all_pids(boost::system::error_code & ec)
std::unique_ptr<kvm_t, closer> kd{kvm_openfiles(nullptr, nullptr, nullptr, KVM_NO_FILES, nullptr)}; std::unique_ptr<kvm_t, closer> kd{kvm_openfiles(nullptr, nullptr, nullptr, KVM_NO_FILES, nullptr)};
if (!kd) if (!kd)
{ {
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return vec; return vec;
} }
if ((proc_info = kvm_getprocs(kd.get(), KERN_PROC_ALL, 0, sizeof(struct kinfo_proc), &cntp))) if ((proc_info = kvm_getprocs(kd.get(), KERN_PROC_ALL, 0, sizeof(struct kinfo_proc), &cntp)))
@@ -551,14 +611,14 @@ std::vector<pid_type> all_pids(boost::system::error_code & ec)
vec.reserve(cntp); vec.reserve(cntp);
for (int i = cntp - 1; i >= 0; i--) for (int i = cntp - 1; i >= 0; i--)
{ {
if (proc_info[i].kp_pid >= 0) if (proc_info[i].p_pid >= 0)
{ {
vec.push_back(proc_info[i].kp_pid); vec.push_back(proc_info[i].p_pid);
} }
} }
} }
else else
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return vec; return vec;
} }
@@ -567,6 +627,7 @@ pid_type parent_pid(pid_type pid, boost::system::error_code & ec)
pid_type ppid = static_cast<pid_type>(-1); pid_type ppid = static_cast<pid_type>(-1);
int cntp = 0; int cntp = 0;
kinfo_proc *proc_info = nullptr; kinfo_proc *proc_info = nullptr;
struct closer struct closer
{ {
void operator()(kvm_t * kd) void operator()(kvm_t * kd)
@@ -578,7 +639,7 @@ pid_type parent_pid(pid_type pid, boost::system::error_code & ec)
std::unique_ptr<kvm_t, closer> kd{kvm_openfiles(nullptr, nullptr, nullptr, KVM_NO_FILES, nullptr)}; std::unique_ptr<kvm_t, closer> kd{kvm_openfiles(nullptr, nullptr, nullptr, KVM_NO_FILES, nullptr)};
if (!kd) if (!kd)
{ {
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return ppid; return ppid;
} }
if ((proc_info = kvm_getprocs(kd.get(), KERN_PROC_PID, pid, sizeof(struct kinfo_proc), &cntp))) if ((proc_info = kvm_getprocs(kd.get(), KERN_PROC_PID, pid, sizeof(struct kinfo_proc), &cntp)))
@@ -586,7 +647,7 @@ pid_type parent_pid(pid_type pid, boost::system::error_code & ec)
ppid = proc_info->p_ppid; ppid = proc_info->p_ppid;
} }
else else
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return ppid; return ppid;
} }
@@ -595,6 +656,7 @@ std::vector<pid_type> child_pids(pid_type pid, boost::system::error_code & ec)
std::vector<pid_type> vec; std::vector<pid_type> vec;
int cntp = 0; int cntp = 0;
kinfo_proc *proc_info = nullptr; kinfo_proc *proc_info = nullptr;
struct closer struct closer
{ {
void operator()(kvm_t * kd) void operator()(kvm_t * kd)
@@ -606,7 +668,7 @@ std::vector<pid_type> child_pids(pid_type pid, boost::system::error_code & ec)
std::unique_ptr<kvm_t, closer> kd{kvm_openfiles(nullptr, nullptr, nullptr, KVM_NO_FILES, nullptr)}; std::unique_ptr<kvm_t, closer> kd{kvm_openfiles(nullptr, nullptr, nullptr, KVM_NO_FILES, nullptr)};
if (!kd) if (!kd)
{ {
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return vec; return vec;
} }
if ((proc_info = kvm_getprocs(kd.get(), KERN_PROC_ALL, 0, sizeof(struct kinfo_proc), &cntp))) if ((proc_info = kvm_getprocs(kd.get(), KERN_PROC_ALL, 0, sizeof(struct kinfo_proc), &cntp)))
@@ -621,7 +683,7 @@ std::vector<pid_type> child_pids(pid_type pid, boost::system::error_code & ec)
} }
} }
else else
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return vec; return vec;
} }
@@ -633,6 +695,7 @@ std::vector<pid_type> all_pids(boost::system::error_code & ec)
std::vector<pid_type> vec; std::vector<pid_type> vec;
struct pid cur_pid; struct pid cur_pid;
proc *proc_info = nullptr; proc *proc_info = nullptr;
struct closer struct closer
{ {
void operator()(kvm_t * kd) void operator()(kvm_t * kd)
@@ -644,7 +707,7 @@ std::vector<pid_type> all_pids(boost::system::error_code & ec)
std::unique_ptr<kvm_t, closer> kd{kvm_open(nullptr, nullptr, nullptr, O_RDONLY, nullptr)}; std::unique_ptr<kvm_t, closer> kd{kvm_open(nullptr, nullptr, nullptr, O_RDONLY, nullptr)};
if (!kd) if (!kd)
{ {
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return vec; return vec;
} }
while ((proc_info = kvm_nextproc(kd))) while ((proc_info = kvm_nextproc(kd)))
@@ -655,7 +718,7 @@ std::vector<pid_type> all_pids(boost::system::error_code & ec)
} }
else else
{ {
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
break; break;
} }
} }
@@ -666,6 +729,7 @@ pid_type parent_pid(pid_type pid, boost::system::error_code & ec)
{ {
pid_type ppid = static_cast<pid_type>(-1); pid_type ppid = static_cast<pid_type>(-1);
proc *proc_info = nullptr; proc *proc_info = nullptr;
struct closer struct closer
{ {
void operator()(kvm_t * kd) void operator()(kvm_t * kd)
@@ -677,7 +741,7 @@ pid_type parent_pid(pid_type pid, boost::system::error_code & ec)
std::unique_ptr<kvm_t, closer> kd{kvm_open(nullptr, nullptr, nullptr, O_RDONLY, nullptr)}; std::unique_ptr<kvm_t, closer> kd{kvm_open(nullptr, nullptr, nullptr, O_RDONLY, nullptr)};
if (!kd) if (!kd)
{ {
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return ppid; return ppid;
} }
if ((proc_info = kvm_getproc(kd, pid))) if ((proc_info = kvm_getproc(kd, pid)))
@@ -685,7 +749,7 @@ pid_type parent_pid(pid_type pid, boost::system::error_code & ec)
ppid = proc_info->p_ppid; ppid = proc_info->p_ppid;
} }
else else
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return ppid; return ppid;
} }
@@ -694,6 +758,7 @@ std::vector<pid_type> child_pids(pid_type pid, boost::system::error_code & ec)
std::vector<pid_type> vec; std::vector<pid_type> vec;
struct pid cur_pid; struct pid cur_pid;
proc *proc_info = nullptr; proc *proc_info = nullptr;
struct closer struct closer
{ {
void operator()(kvm_t * kd) void operator()(kvm_t * kd)
@@ -705,7 +770,7 @@ std::vector<pid_type> child_pids(pid_type pid, boost::system::error_code & ec)
std::unique_ptr<kvm_t, closer> kd{kvm_open(nullptr, nullptr, nullptr, O_RDONLY, nullptr); std::unique_ptr<kvm_t, closer> kd{kvm_open(nullptr, nullptr, nullptr, O_RDONLY, nullptr);
if (!kd) if (!kd)
{ {
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
return vec; return vec;
} }
while ((proc_info = kvm_nextproc(kd))) while ((proc_info = kvm_nextproc(kd)))
@@ -718,7 +783,7 @@ std::vector<pid_type> child_pids(pid_type pid, boost::system::error_code & ec)
} }
else else
{ {
BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec) BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
break; break;
} }
} }
@@ -727,7 +792,21 @@ std::vector<pid_type> child_pids(pid_type pid, boost::system::error_code & ec)
} }
#else #else
#error "Platform not supported" std::vector<pid_type> all_pids(boost::system::error_code & ec)
{
BOOST_PROCESS_V2_ASSIGN_EC(ec, ENOTSUP, system_category());
return {};
}
pid_type parent_pid(pid_type pid, boost::system::error_code & ec)
{
BOOST_PROCESS_V2_ASSIGN_EC(ec, ENOTSUP, system_category());
return pid;
}
std::vector<pid_type> child_pids(pid_type, boost::system::error_code & ec)
{
BOOST_PROCESS_V2_ASSIGN_EC(ec, ENOTSUP, system_category());
return {};
}
#endif #endif
std::vector<pid_type> all_pids() std::vector<pid_type> all_pids()

View File

@@ -17,10 +17,9 @@
// linux has close_range since 5.19 // linux has close_range since 5.19
#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) #if defined(__FreeBSD__)
// 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://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__ // __FreeBSD__
// //
// gives us // gives us
@@ -45,7 +44,8 @@ int fdwalk(int (*func)(void *, int), void *cd);
#include <linux/version.h> #include <linux/version.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,11,0) // kernel has close_range // kernel has close_range
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,9,0) && !defined(BOOST_PROCESS_V2_POSIX_FORCE_DISABLE_CLOSE_RANGE)
// version is included by stdlib.h #include <gnu/libc-version.h> // version is included by stdlib.h #include <gnu/libc-version.h>
#if (__GLIBC__ >= 2 && __GLIBC_MINOR__ >= 34) // glibc is compiled with close_range support #if (__GLIBC__ >= 2 && __GLIBC_MINOR__ >= 34) // glibc is compiled with close_range support
@@ -60,6 +60,10 @@ int fdwalk(int (*func)(void *, int), void *cd);
#if defined(SYS_close_range) #if defined(SYS_close_range)
#define BOOST_PROCESS_V2_HAS_CLOSE_RANGE 1 #define BOOST_PROCESS_V2_HAS_CLOSE_RANGE 1
#if !defined(CLOSE_RANGE_UNSHARE)
#define CLOSE_RANGE_UNSHARE 2
#endif
int close_range(unsigned int first, unsigned int last, int flags) int close_range(unsigned int first, unsigned int last, int flags)
{ {
return ::syscall(SYS_close_range, first, last, flags); return ::syscall(SYS_close_range, first, last, flags);

View File

@@ -19,7 +19,7 @@
#if defined(BOOST_PROCESS_V2_WINDOWS) #if defined(BOOST_PROCESS_V2_WINDOWS)
#include <windows.h> #include <windows.h>
#include <shellapi.h> #include <shellapi.h>
#else #elif !defined(__OpenBSD__)
#include <wordexp.h> #include <wordexp.h>
#endif #endif
@@ -30,7 +30,7 @@ BOOST_PROCESS_V2_DECL const error_category& get_shell_category()
{ {
return system_category(); return system_category();
} }
#else #elif !defined(__OpenBSD__)
struct shell_category_t final : public error_category struct shell_category_t final : public error_category
{ {
@@ -38,7 +38,7 @@ struct shell_category_t final : public error_category
const char* name() const noexcept const char* name() const noexcept
{ {
return "process.v2.utf8"; return "process.v2.shell";
} }
std::string message(int value) const std::string message(int value) const
{ {
@@ -66,6 +66,13 @@ BOOST_PROCESS_V2_DECL const error_category& get_shell_category()
return instance; return instance;
} }
#else
const error_category& get_shell_category()
{
return system_category();
}
#endif #endif
#if defined (BOOST_PROCESS_V2_WINDOWS) #if defined (BOOST_PROCESS_V2_WINDOWS)
@@ -92,7 +99,7 @@ auto shell::args() const-> args_type
return input_.c_str(); return input_.c_str();
} }
#else #elif !defined(__OpenBSD__)
void shell::parse_() void shell::parse_()
{ {
@@ -135,6 +142,22 @@ auto shell::args() const -> args_type
return const_cast<const char**>(argv()); return const_cast<const char**>(argv());
} }
#else
void shell::parse_()
{
error_code ec;
BOOST_PROCESS_V2_ASSIGN_EC(ec, ENOTSUP, system_category());
throw system_error(ec, "shell::parse");
}
shell::~shell() = default;
auto shell::args() const -> args_type
{
return nullptr;
}
#endif #endif
BOOST_PROCESS_V2_END_NAMESPACE BOOST_PROCESS_V2_END_NAMESPACE

View File

@@ -9,25 +9,23 @@
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
import os ; lib ws2_32 ;
lib shell32 ;
if [ os.name ] = NT lib Advapi32 ;
{ lib Ntdll ;
lib ws2_32 ;
lib shell32 ;
lib Advapi32 ;
lib Ntdll ;
}
project : requirements project : requirements
<library>/boost/process//boost_process
<define>BOOST_ASIO_NO_DEPRECATED <define>BOOST_ASIO_NO_DEPRECATED
<toolset>msvc:<define>_SCL_SECURE_NO_WARNINGS <toolset>msvc:<define>_SCL_SECURE_NO_WARNINGS
<toolset>msvc:<define>_CRT_SECURE_NO_DEPRECATE <toolset>msvc:<define>_CRT_SECURE_NO_DEPRECATE
<toolset>msvc:<cxxflags>/bigobj <toolset>msvc:<cxxflags>/bigobj
<target-os>windows:<define>WIN32_LEAN_AND_MEAN <target-os>windows:<define>WIN32_LEAN_AND_MEAN
<target-os>linux:<linkflags>-lpthread <target-os>linux:<linkflags>-lpthread
<target-os>freebsd:<linkflags>-lpthread
<os>NT,<toolset>cw:<library>ws2_32 <os>NT,<toolset>cw:<library>ws2_32
<os>NT,<toolset>gcc:<library>ws2_32 <os>NT,<toolset>gcc:<library>ws2_32
<library>/boost/test//included
; ;
@@ -35,16 +33,18 @@ project : requirements
import testing ; import testing ;
alias program_options : /boost//program_options : <link>static ; alias program_options : usage-requirements <library>/boost/program_options//boost_program_options ;
alias filesystem : /boost//filesystem ; alias filesystem : usage-requirements <library>/boost/filesystem//boost_filesystem ;
alias iostreams : /boost//iostreams ; alias iostreams : usage-requirements <library>/boost/iostreams//boost_iostreams ;
alias system : /boost//system ; alias system : usage-requirements <library>/boost/system//boost_system ;
alias thread : /boost//thread ; alias thread : usage-requirements <library>/boost/thread//boost_thread ;
alias coroutine : /boost//coroutine : <link>static ; alias scope_exit : usage-requirements <library>/boost/scope_exit//boost_scope_exit ;
alias lambda : usage-requirements <library>/boost/lambda//boost_lambda ;
alias chrono : usage-requirements <library>/boost/chrono//boost_chrono ;
lib multi_ref : multi_ref1.cpp multi_ref2.cpp system : <target-os>windows:<source>shell32 ; lib multi_ref : multi_ref1.cpp multi_ref2.cpp system : <target-os>windows:<source>shell32 ;
exe sparring_partner : sparring_partner.cpp program_options system filesystem iostreams : exe sparring_partner : sparring_partner.cpp program_options system filesystem iostreams lambda :
<warnings>off <target-os>windows:<source>shell32 <target-os>windows:<source>Ntdll <warnings>off <target-os>windows:<source>shell32 <target-os>windows:<source>Ntdll
; ;
@@ -100,15 +100,15 @@ test-suite with-valgrind :
[ run env.cpp program_options system filesystem : [ test-options env ] : sparring_partner ] [ run env.cpp program_options system filesystem : [ test-options env ] : sparring_partner ]
[ run group.cpp system thread filesystem : [ test-options group ] : sub_launch ] [ run group.cpp system thread filesystem : [ test-options group ] : sub_launch ]
[ run group.cpp system thread filesystem : [ test-options group ] : sub_launch : <build>no <target-os>windows:<build>yes <define>BOOST_USE_WINDOWS_H=1 : group-windows-h ] [ run group.cpp system thread filesystem : [ test-options group ] : sub_launch : <build>no <target-os>windows:<build>yes <define>BOOST_USE_WINDOWS_H=1 : group-windows-h ]
[ run group_wait.cpp system thread filesystem : [ test-options group_wait ] : sparring_partner : <target-os>darwin:<build>no <target-os>freebsd:<build>no ] [ run group_wait.cpp system thread filesystem scope_exit : [ test-options group_wait ] : sparring_partner : <target-os>darwin:<build>no <target-os>freebsd:<build>no ]
[ run limit_fd.cpp program_options system filesystem : [ test-options limit_fd ] : sparring_partner : <target-os>freebsd:<build>no ] [ run limit_fd.cpp program_options system filesystem : [ test-options limit_fd ] : sparring_partner : <target-os>freebsd:<build>no ]
[ run run_exe.cpp filesystem : : sparring_partner ] [ run run_exe.cpp filesystem : : sparring_partner ]
[ run run_exe_path.cpp filesystem : [ test-options run_exe_path ] : sparring_partner ] [ run run_exe_path.cpp filesystem : [ test-options run_exe_path ] : sparring_partner ]
[ run search_path.cpp filesystem system : [ test-options search_path ] : : <target-os>windows:<source>shell32 ] [ run search_path.cpp filesystem system : [ test-options search_path ] : : <target-os>windows:<source>shell32 ]
[ run shell.cpp filesystem system : [ test-options shell ] : sparring_partner : <target-os>darwin:<build>no ] [ run shell.cpp filesystem system : [ test-options shell ] : sparring_partner : <target-os>darwin:<build>no ]
[ run shell_path.cpp filesystem system : [ test-options shell_path ] ] [ run shell_path.cpp filesystem system : [ test-options shell_path ] ]
[ run system_test1.cpp filesystem system : [ test-options system_test1 ] : sparring_partner ] [ run system_test1.cpp filesystem system chrono : [ test-options system_test1 ] : sparring_partner ]
[ run system_test2.cpp filesystem system : [ test-options system_test2 ] : sparring_partner ] [ run system_test2.cpp filesystem system chrono : [ test-options system_test2 ] : sparring_partner ]
[ run spawn.cpp filesystem system : [ test-options spawn ] : sparring_partner ] [ run spawn.cpp filesystem system : [ test-options spawn ] : sparring_partner ]
[ run start_dir.cpp filesystem system : [ test-options start_dir ] : sparring_partner ] [ run start_dir.cpp filesystem system : [ test-options start_dir ] : sparring_partner ]
[ run terminate.cpp system filesystem : [ test-options terminate ] : sparring_partner : <target-os>freebsd:<build>no ] [ run terminate.cpp system filesystem : [ test-options terminate ] : sparring_partner : <target-os>freebsd:<build>no ]
@@ -123,13 +123,10 @@ test-suite with-valgrind :
: <dependency>bare ; : <dependency>bare ;
test-suite without-valgrind : test-suite without-valgrind :
[ run async_system_future.cpp filesystem system coroutine : [ test-options async_system_future ] : sparring_partner : <link>static <toolset>msvc:<cxxflags>/bigobj ] [ run async_system_future.cpp filesystem system : [ test-options async_system_future ] : sparring_partner : <link>static <toolset>msvc:<cxxflags>/bigobj ]
[ run async_system_stackful.cpp filesystem system coroutine : [ test-options async_system_stackful ] : sparring_partner : <link>static <toolset>msvc:<cxxflags>/bigobj ] # [ run async_system_stackful.cpp filesystem system coroutine : [ test-options async_system_stackful ] : sparring_partner : <link>static <toolset>msvc:<cxxflags>/bigobj ]
# [ run async_system_stackful_error.cpp filesystem system coroutine : [ test-options async_system_stackful_error ] : sparring_partner : <link>static <toolset>msvc:<cxxflags>/bigobj ] # [ run async_system_stackful_error.cpp filesystem system coroutine : [ test-options async_system_stackful_error ] : sparring_partner : <link>static <toolset>msvc:<cxxflags>/bigobj ]
[ run async_system_stackful_except.cpp filesystem system coroutine : [ test-options async_system_stackful_except ] : sparring_partner : <link>static <toolset>msvc:<cxxflags>/bigobj ] # [ run async_system_stackful_except.cpp filesystem system coroutine : [ test-options async_system_stackful_except ] : sparring_partner : <link>static <toolset>msvc:<cxxflags>/bigobj ]
[ run async_system_stackless.cpp filesystem system coroutine : [ test-options async_system_stackless ] : sparring_partner : <link>static <toolset>msvc:<cxxflags>/bigobj ] [ run async_system_stackless.cpp filesystem system : [ test-options async_system_stackless ] : sparring_partner : <link>static <toolset>msvc:<cxxflags>/bigobj ]
[ run vfork.cpp system filesystem : [ test-options vfork ] : sparring_partner : <build>no <target-os>linux:<build>yes ] [ run vfork.cpp system filesystem : [ test-options vfork ] : sparring_partner : <build>no <target-os>linux:<build>yes ]
; ;
alias v2-tests : v2//standalone v2//with_target ;

View File

@@ -21,7 +21,7 @@
#include <boost/system/error_code.hpp> #include <boost/system/error_code.hpp>
#include <boost/algorithm/string/predicate.hpp> #include <boost/algorithm/string/predicate.hpp>
#include <boost/asio/deadline_timer.hpp> #include <boost/asio/steady_timer.hpp>
using namespace std; using namespace std;
@@ -46,7 +46,7 @@ BOOST_AUTO_TEST_CASE(async_wait, *boost::unit_test::timeout(5))
bool exit_called_for_c1 = false; bool exit_called_for_c1 = false;
int exit_code_c1 = 0; int exit_code_c1 = 0;
boost::asio::deadline_timer timeout{io_context, boost::posix_time::seconds(2)}; boost::asio::steady_timer timeout{io_context, std::chrono::seconds(2)};
timeout.async_wait([&](boost::system::error_code ec){if (!ec) io_context.stop();}); timeout.async_wait([&](boost::system::error_code ec){if (!ec) io_context.stop();});
bp::child c1(master_test_suite().argv[1], bp::child c1(master_test_suite().argv[1],
@@ -97,7 +97,7 @@ BOOST_AUTO_TEST_CASE(async_wait_sync_wait, *boost::unit_test::timeout(5))
int exit_code = 0; int exit_code = 0;
std::error_code ec; std::error_code ec;
boost::asio::deadline_timer timeout{io_context, boost::posix_time::seconds(3)}; boost::asio::steady_timer timeout{io_context, std::chrono::seconds(3)};
timeout.async_wait([&](boost::system::error_code ec){if (!ec) io_context.stop();}); timeout.async_wait([&](boost::system::error_code ec){if (!ec) io_context.stop();});
bp::child c1( bp::child c1(
@@ -140,10 +140,10 @@ BOOST_AUTO_TEST_CASE(async_wait_different_contexts, *boost::unit_test::timeout(1
boost::asio::io_context io_context1; boost::asio::io_context io_context1;
boost::asio::io_context io_context2; boost::asio::io_context io_context2;
boost::asio::deadline_timer timeout1{io_context1, boost::posix_time::seconds(2)}; boost::asio::steady_timer timeout1{io_context1, std::chrono::seconds(2)};
timeout1.async_wait([&](boost::system::error_code ec){if (!ec) io_context1.stop();}); timeout1.async_wait([&](boost::system::error_code ec){if (!ec) io_context1.stop();});
boost::asio::deadline_timer timeout2{io_context2, boost::posix_time::seconds(7)}; boost::asio::steady_timer timeout2{io_context2, std::chrono::seconds(7)};
timeout2.async_wait([&](boost::system::error_code ec){if (!ec) io_context2.stop();}); timeout2.async_wait([&](boost::system::error_code ec){if (!ec) io_context2.stop();});
std::error_code ec; std::error_code ec;
@@ -208,7 +208,7 @@ BOOST_AUTO_TEST_CASE(async_wait_abort, *boost::unit_test::timeout(5))
std::error_code ec; std::error_code ec;
boost::asio::deadline_timer timeout{io_context, boost::posix_time::seconds(5)}; boost::asio::steady_timer timeout{io_context, std::chrono::seconds(5)};
timeout.async_wait([&](boost::system::error_code ec){if (!ec) io_context.stop();}); timeout.async_wait([&](boost::system::error_code ec){if (!ec) io_context.stop();});
bool exit_called = false; bool exit_called = false;
@@ -245,7 +245,7 @@ BOOST_AUTO_TEST_CASE(async_future, *boost::unit_test::timeout(3))
boost::asio::io_context io_context; boost::asio::io_context io_context;
boost::asio::deadline_timer timeout{io_context, boost::posix_time::seconds(2)}; boost::asio::steady_timer timeout{io_context, std::chrono::seconds(2)};
timeout.async_wait([&](boost::system::error_code ec){if (!ec) io_context.stop();}); timeout.async_wait([&](boost::system::error_code ec){if (!ec) io_context.stop();});
std::error_code ec; std::error_code ec;
@@ -278,7 +278,7 @@ BOOST_AUTO_TEST_CASE(async_out_stream, *boost::unit_test::timeout(5))
boost::asio::streambuf buf; boost::asio::streambuf buf;
boost::asio::deadline_timer timeout{io_context, boost::posix_time::seconds(2)}; boost::asio::steady_timer timeout{io_context, std::chrono::seconds(2)};
timeout.async_wait([&](boost::system::error_code ec){if (!ec) io_context.stop();}); timeout.async_wait([&](boost::system::error_code ec){if (!ec) io_context.stop();});
bp::child c(master_test_suite().argv[1], bp::child c(master_test_suite().argv[1],
@@ -318,7 +318,7 @@ BOOST_AUTO_TEST_CASE(async_in_stream, *boost::unit_test::timeout(5))
std::ostream ostr(&in_buf); std::ostream ostr(&in_buf);
ostr << "-string" << endl ; ostr << "-string" << endl ;
boost::asio::deadline_timer timeout{io_context, boost::posix_time::seconds(2)}; boost::asio::steady_timer timeout{io_context, std::chrono::seconds(2)};
timeout.async_wait([&](boost::system::error_code ec){if (!ec) io_context.stop();}); timeout.async_wait([&](boost::system::error_code ec){if (!ec) io_context.stop();});
bp::child c( bp::child c(
@@ -355,7 +355,7 @@ BOOST_AUTO_TEST_CASE(async_error, *boost::unit_test::timeout(3))
boost::asio::io_context io_context; boost::asio::io_context io_context;
boost::asio::deadline_timer timeout{io_context, boost::posix_time::seconds(2)}; boost::asio::steady_timer timeout{io_context, std::chrono::seconds(2)};
timeout.async_wait([&](boost::system::error_code ec){if (!ec) io_context.stop();}); timeout.async_wait([&](boost::system::error_code ec){if (!ec) io_context.stop();});
bool exit_called = false; bool exit_called = false;
@@ -386,7 +386,7 @@ BOOST_AUTO_TEST_CASE(mixed_async, *boost::unit_test::timeout(5))
boost::asio::io_context io_context; boost::asio::io_context io_context;
boost::asio::deadline_timer timeout{io_context, boost::posix_time::seconds(2)}; boost::asio::steady_timer timeout{io_context, std::chrono::seconds(2)};
timeout.async_wait([&](boost::system::error_code ec){if (!ec) io_context.stop();}); timeout.async_wait([&](boost::system::error_code ec){if (!ec) io_context.stop();});
bool exit_called = false; bool exit_called = false;

View File

@@ -110,7 +110,7 @@ BOOST_AUTO_TEST_CASE(async_wait, *boost::unit_test::timeout(10))
boost::asio::io_context io_context; boost::asio::io_context io_context;
boost::asio::deadline_timer timeout{io_context, boost::posix_time::seconds(3)}; boost::asio::steady_timer timeout{io_context, std::chrono::seconds(3)};
timeout.async_wait([&](boost::system::error_code ec){if (!ec) io_context.stop();}); timeout.async_wait([&](boost::system::error_code ec){if (!ec) io_context.stop();});
@@ -148,12 +148,17 @@ BOOST_AUTO_TEST_CASE(async_nowait, *boost::unit_test::timeout(10))
boost::asio::io_context io_context; boost::asio::io_context io_context;
bp::child c( bp::child c(
master_test_suite().argv[1], master_test_suite().argv[1],
"test", "--exit-code", "221", "test", "--exit-code", "121",
ec, ec,
bp::on_exit=[](int exit_code, std::error_code) mutable {}, bp::on_exit=[](int exit_code, std::error_code) mutable {},
io_context io_context
); );
BOOST_REQUIRE(!ec); BOOST_REQUIRE(!ec);
io_context.run_for(std::chrono::milliseconds(100)); while (c.running())
BOOST_CHECK_EQUAL(221, c.exit_code()); {
io_context.run_for(std::chrono::milliseconds(10));
io_context.restart();
}
BOOST_CHECK_EQUAL(121, c.exit_code());
} }

View File

@@ -19,7 +19,7 @@
#include <boost/chrono.hpp> #include <boost/chrono.hpp>
#include <boost/algorithm/string/predicate.hpp> #include <boost/algorithm/string/predicate.hpp>
#include <boost/asio/steady_timer.hpp> #include <boost/asio/steady_timer.hpp>
#include <boost/asio/deadline_timer.hpp> #include <boost/asio/steady_timer.hpp>
#include <boost/process/v1/error.hpp> #include <boost/process/v1/error.hpp>
#include <boost/process/v1/io.hpp> #include <boost/process/v1/io.hpp>

View File

@@ -53,7 +53,7 @@ BOOST_AUTO_TEST_CASE(async_wait, *boost::unit_test::timeout(4))
std::error_code ec; std::error_code ec;
bool called = false; bool called = false;
boost::asio::deadline_timer timeout{io_context, boost::posix_time::seconds(3)}; boost::asio::steady_timer timeout{io_context, std::chrono::seconds(3)};
timeout.async_wait([&](boost::system::error_code ec){if (!ec) io_context.stop();}); timeout.async_wait([&](boost::system::error_code ec){if (!ec) io_context.stop();});

View File

@@ -4,19 +4,15 @@
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
import os ; lib ws2_32 ;
lib shell32 ;
if [ os.name ] = NT lib Advapi32 ;
{ lib Ntdll ;
lib ws2_32 ; lib user32 ;
lib shell32 ; lib Bcrypt ;
lib Advapi32 ;
lib Ntdll ;
lib user32 ;
lib Bcrypt ;
}
project : requirements project : requirements
<library>/boost/process//boost_process
<define>BOOST_ASIO_NO_DEPRECATED <define>BOOST_ASIO_NO_DEPRECATED
<toolset>msvc:<define>_SCL_SECURE_NO_WARNINGS <toolset>msvc:<define>_SCL_SECURE_NO_WARNINGS
<toolset>msvc:<define>_CRT_SECURE_NO_DEPRECATE <toolset>msvc:<define>_CRT_SECURE_NO_DEPRECATE
@@ -24,42 +20,44 @@ project : requirements
<target-os>windows:<define>WIN32_LEAN_AND_MEAN <target-os>windows:<define>WIN32_LEAN_AND_MEAN
<target-os>windows:<define>_WIN32_WINNT=0x0601 <target-os>windows:<define>_WIN32_WINNT=0x0601
<target-os>linux:<linkflags>-lpthread <target-os>linux:<linkflags>-lpthread
<target-os>freebsd:<linkflags>-lutil <target-os>freebsd:<linkflags>-lpthread
<target-os>freebsd:<linkflags>-lkvm <target-os>freebsd:<linkflags>-lkvm
<target-os>freebsd:<linkflags>-lprocstat <target-os>bsd:<linkflags>-lpthread
<target-os>bsd:<linkflags>-lkvm <target-os>bsd:<linkflags>-lkvm
<target-os>netbsd:<linkflags>-lpthread
<target-os>netbsd:<linkflags>-lkvm
<target-os>openbsd:<linkflags>-lpthread
<target-os>openbsd:<linkflags>-lkvm
<target-os>solaris:<linkflags>-lpthread
<target-os>solaris:<linkflags>-lkvm
<os>NT,<toolset>cw:<library>ws2_32 <os>NT,<toolset>cw:<library>ws2_32
<os>NT,<toolset>gcc:<library>ws2_32 <os>NT,<toolset>gcc:<library>ws2_32
<os>NT,<toolset>gcc:<library>Bcrypt <os>NT,<toolset>gcc:<library>Bcrypt
<define>BOOST_PROCESS_V2_SEPARATE_COMPILATION=1 <define>BOOST_PROCESS_V2_SEPARATE_COMPILATION=1
<library>/boost/test//included
; ;
import testing ; import testing ;
alias filesystem : /boost//filesystem : <link>static ;
exe target : target.cpp : exe target : target.cpp :
<warnings>off <target-os>windows:<source>shell32 <warnings>off <target-os>windows:<source>shell32
<target-os>windows:<source>Ntdll <target-os>windows:<source>Ntdll
; ;
lib test_impl : test_impl.cpp filesystem /boost//process : local test_impl = test_impl.cpp /boost/process//boost_process /boost/test//boost_unit_test_framework ;
<define>BOOST_PROCESS_V2_SEPARATE_COMPILATION=1
<define>BOOST_TEST_IGNORE_SIGCHLD=1
<link>static
;
test-suite standalone : test-suite standalone :
[ run utf8.cpp test_impl ] [ run utf8.cpp $(test_impl) ]
[ run cstring_ref.cpp test_impl ] [ run cstring_ref.cpp $(test_impl) ]
[ run environment.cpp test_impl ] [ run environment.cpp $(test_impl) ]
[ run shell.cpp test_impl ] [ run shell.cpp $(test_impl) ]
; ;
test-suite with_target : test-suite with_target :
[ run pid.cpp test_impl : --log_level=all --catch_system_errors=no -- : target ] [ run pid.cpp $(test_impl) : --log_level=all --catch_system_errors=no -- : target ]
[ run process.cpp test_impl : --log_level=all --catch_system_errors=no -- : target ] [ run process.cpp $(test_impl) : --log_level=all --catch_system_errors=no -- : target ]
[ run windows.cpp test_impl : --log_level=all --catch_system_errors=no -- : target : <build>no <target-os>windows:<build>yes <target-os>windows:<source>Advapi32 ] [ run windows.cpp $(test_impl) : --log_level=all --catch_system_errors=no -- : target : <build>no <target-os>windows:<build>yes <target-os>windows:<source>Advapi32 ]
[ run ext.cpp test_impl : --log_level=all --catch_system_errors=no -- : target : <target-os>darwin:<build>no ] [ run ext.cpp $(test_impl) : --log_level=all --catch_system_errors=no -- : target : <target-os>darwin:<build>no ]
; ;

View File

@@ -9,9 +9,6 @@
#define BOOST_ALL_NO_LIB 1 #define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB) #endif // !defined(BOOST_ALL_NO_LIB)
#if defined(BOOST_FILESYSTEM_DYN_LINK)
#undef BOOST_FILESYSTEM_DYN_LINK
#endif
#define BOOST_TEST_IGNORE_SIGCHLD 1 #define BOOST_TEST_IGNORE_SIGCHLD 1
#if true //defined(BOOST_POSIX_API) #if true //defined(BOOST_POSIX_API)
@@ -34,6 +31,7 @@
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
#include <boost/asio/io_context.hpp> #include <boost/asio/io_context.hpp>
#include <boost/asio/connect_pipe.hpp> #include <boost/asio/connect_pipe.hpp>
#include <boost/asio/cancel_after.hpp>
#include <boost/asio/detached.hpp> #include <boost/asio/detached.hpp>
#include <boost/asio/readable_pipe.hpp> #include <boost/asio/readable_pipe.hpp>
#include <boost/asio/read.hpp> #include <boost/asio/read.hpp>
@@ -642,6 +640,30 @@ BOOST_AUTO_TEST_CASE(async_request_exit)
ctx.run(); ctx.run();
} }
BOOST_AUTO_TEST_CASE(async_cancel_wait)
{
asio::io_context ctx;
using boost::unit_test::framework::master_test_suite;
const auto pth = bpv::filesystem::absolute(master_test_suite().argv[1]);
bpv::process proc(ctx, pth, {"sleep", "1000"});
asio::steady_timer tim{ctx, std::chrono::milliseconds(250)};
asio::cancellation_signal sig;
// check that the async_wait gets properly cancelled
proc.async_wait(asio::cancel_after(std::chrono::milliseconds(100),
[&](boost::system::error_code ec, int)
{
BOOST_CHECK(ec == asio::error::operation_aborted);
BOOST_CHECK(proc.running());
if (proc.running())
proc.terminate();
}));
ctx.run();
}
BOOST_AUTO_TEST_SUITE_END(); BOOST_AUTO_TEST_SUITE_END();

View File

@@ -5,4 +5,4 @@
#define BOOST_TEST_IGNORE_SIGCHLD #define BOOST_TEST_IGNORE_SIGCHLD
#define BOOST_TEST_MODULE process_v2_test #define BOOST_TEST_MODULE process_v2_test
#include <boost/test/included/unit_test.hpp> #include <boost/test/unit_test.hpp>

View File

@@ -9,10 +9,6 @@
#define BOOST_ALL_NO_LIB 1 #define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB) #endif // !defined(BOOST_ALL_NO_LIB)
#if defined(BOOST_FILESYSTEM_DYN_LINK)
#undef BOOST_FILESYSTEM_DYN_LINK
#endif
// Test that header file is self-contained. // Test that header file is self-contained.
#include <boost/process/v2/process.hpp> #include <boost/process/v2/process.hpp>