mirror of
https://github.com/boostorg/process.git
synced 2026-01-20 04:42:24 +00:00
Compare commits
49 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0d2da65866 | ||
|
|
7c3ba4b784 | ||
|
|
1e60fcd830 | ||
|
|
d6bcb0014a | ||
|
|
e5f0f245bd | ||
|
|
a4a3770501 | ||
|
|
1e5892b8fb | ||
|
|
85b29d6442 | ||
|
|
b9ee759365 | ||
|
|
f3b163a933 | ||
|
|
be2ae2c3cf | ||
|
|
b2f5ebc760 | ||
|
|
e34557faa0 | ||
|
|
a9f083f45c | ||
|
|
b5ab94c932 | ||
|
|
9ceda79fa2 | ||
|
|
68cbeae491 | ||
|
|
ae778f36a8 | ||
|
|
0671e4a133 | ||
|
|
cbf944c57b | ||
|
|
5f2b8c53f4 | ||
|
|
dac3614a38 | ||
|
|
2fc71ca0a3 | ||
|
|
404682d75d | ||
|
|
9fbbdc3421 | ||
|
|
3df0009a2f | ||
|
|
ecb384b253 | ||
|
|
05bce942c1 | ||
|
|
dcf5d8ce41 | ||
|
|
4209f8ee6e | ||
|
|
d9513269cc | ||
|
|
293f28dab6 | ||
|
|
fe1b629b5d | ||
|
|
278fa57214 | ||
|
|
1addfba12e | ||
|
|
4cc469b2a4 | ||
|
|
6e4d1e29d2 | ||
|
|
dada865fd0 | ||
|
|
380dd1b00f | ||
|
|
7832cb6af3 | ||
|
|
68f4c50be9 | ||
|
|
cd226a7616 | ||
|
|
4243ce72f8 | ||
|
|
9065833e61 | ||
|
|
7cb7af6c8b | ||
|
|
90cbe7cec0 | ||
|
|
df33c1ad7b | ||
|
|
bbabea30dd | ||
|
|
8a61f8daa3 |
@@ -19,7 +19,7 @@ def main(ctx):
|
||||
linux_cxx("docs", "", packages="docbook docbook-xml docbook-xsl xsltproc libsaxonhe-java default-jre-headless flex libfl-dev bison unzip rsync", image="cppalliance/droneubuntu1804:1", buildtype="docs", buildscript="drone", environment={"COMMENT": "docs"}, globalenv=globalenv),
|
||||
linux_cxx("asan", "g++-8", packages="g++-8", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'COMMENT': 'asan', 'B2_VARIANT': 'debug', 'B2_TOOLSET': 'gcc-8', 'B2_CXXSTD': '11', 'B2_ASAN': '1', 'B2_DEFINES': 'BOOST_NO_STRESS_TEST=1', 'DRONE_EXTRA_PRIVILEGED': 'True', 'DRONE_JOB_UUID': '356a192b79'}, globalenv=globalenv, privileged=True),
|
||||
linux_cxx("ubsan", "g++-8", packages="g++-8", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'COMMENT': 'ubsan', 'B2_VARIANT': 'debug', 'B2_TOOLSET': 'gcc-8', 'B2_CXXSTD': '11', 'B2_UBSAN': '1', 'B2_DEFINES': 'BOOST_NO_STRESS_TEST=1', 'B2_LINKFLAGS': '-fuse-ld=gold', 'DRONE_JOB_UUID': '77de68daec'}, globalenv=globalenv),
|
||||
#linux_cxx("gcc 11 arm64", "g++-11", packages="g++-11", buildtype="boost", buildscript="drone", image="cppalliance/droneubuntu2004:multiarch", environment={ 'B2_TOOLSET': 'gcc-11', 'B2_CXXSTD': '11', 'DRONE_JOB_UUID': '17ba079169m'}, arch="arm64", globalenv=globalenv),
|
||||
linux_cxx("gcc 11 arm64", "g++-11", packages="g++-11", buildtype="boost", buildscript="drone", image="cppalliance/droneubuntu2004:multiarch", environment={ 'B2_TOOLSET': 'gcc-11', 'B2_CXXSTD': '11', 'DRONE_JOB_UUID': '17ba079169m'}, arch="arm64", globalenv=globalenv),
|
||||
linux_cxx("GCC 10, Debug + Coverage", "g++-10", packages="g++-10 libssl-dev libffi-dev binutils-gold gdb",
|
||||
image="cppalliance/droneubuntu2004:1", buildtype="boost", buildscript="drone", environment={"GCOV": "gcov-10", "LCOV_VERSION": "1.15", "VARIANT": "process_coverage", "TOOLSET": "gcc", "COMPILER": "g++-10", "CXXSTD": "11", "DRONE_BEFORE_INSTALL" : "process_coverage", "CODECOV_TOKEN": {"from_secret": "codecov_token"}}, globalenv=globalenv, privileged=True),
|
||||
# A set of jobs based on the earlier .travis.yml configuration:
|
||||
|
||||
@@ -26,7 +26,9 @@ set B2_TARGETS=libs/!SELF!/test
|
||||
cd !BOOST_ROOT!
|
||||
call bootstrap.bat
|
||||
b2 headers
|
||||
b2 --debug-configuration variant=%VARIANT% cxxstd=%CXXSTD% define=%DEFINE% address-model=%ADDRESS_MODEL% toolset=%TOOLSET% --verbose-test libs/!SELF!/test libs/!SELF!/example -j3
|
||||
b2 --debug-configuration variant=%VARIANT% cxxstd=%CXXSTD% define=%DEFINE% address-model=%ADDRESS_MODEL% toolset=%TOOLSET% --verbose-test libs/!SELF!/test -j3
|
||||
b2 --debug-configuration variant=%VARIANT% cxxstd=%CXXSTD% define=%DEFINE% address-model=%ADDRESS_MODEL% toolset=%TOOLSET% --verbose-test libs/!SELF!/example -j3
|
||||
|
||||
) else if "%DRONE_JOB_BUILDTYPE%" == "standalone-windows" (
|
||||
|
||||
REM not used
|
||||
|
||||
174
.github/workflows/ci.yml
vendored
174
.github/workflows/ci.yml
vendored
@@ -17,6 +17,10 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- toolset: gcc-4.8
|
||||
cxxstd: "11"
|
||||
os: ubuntu-18.04
|
||||
install: g++-4.8
|
||||
- toolset: gcc-5
|
||||
cxxstd: "11,14,1z"
|
||||
os: ubuntu-18.04
|
||||
@@ -28,10 +32,21 @@ jobs:
|
||||
- toolset: gcc-7
|
||||
cxxstd: "11,14,17"
|
||||
os: ubuntu-18.04
|
||||
- toolset: gcc-8
|
||||
cxxstd: "11,14,17,2a"
|
||||
os: ubuntu-18.04
|
||||
install: g++-8
|
||||
- toolset: gcc-9
|
||||
cxxstd: "11,14,17,2a"
|
||||
os: ubuntu-20.04
|
||||
- toolset: gcc-10
|
||||
cxxstd: "11,14,17,2a"
|
||||
os: ubuntu-20.04
|
||||
install: g++-10
|
||||
- toolset: gcc-11
|
||||
cxxstd: "11,14,17,2a"
|
||||
os: ubuntu-20.04
|
||||
install: g++-11
|
||||
- toolset: gcc-12
|
||||
cxxstd: "11,14,17,20,2b"
|
||||
os: ubuntu-22.04
|
||||
@@ -199,3 +214,162 @@ jobs:
|
||||
run: |
|
||||
cd ../boost-root
|
||||
b2 -j3 libs/%LIBRARY%/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=debug,release embed-manifest-via=linker
|
||||
|
||||
posix-cmake-subdir:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- os: ubuntu-18.04
|
||||
- os: ubuntu-20.04
|
||||
- os: ubuntu-22.04
|
||||
- os: macos-11
|
||||
|
||||
runs-on: ${{matrix.os}}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Install packages
|
||||
if: matrix.install
|
||||
run: sudo apt install ${{matrix.install}}
|
||||
|
||||
- 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
|
||||
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY
|
||||
|
||||
- name: Use library with add_subdirectory
|
||||
run: |
|
||||
cd ../boost-root/libs/$LIBRARY/test/cmake_subdir_test
|
||||
mkdir __build__ && cd __build__
|
||||
cmake ..
|
||||
cmake --build .
|
||||
ctest --output-on-failure --no-tests=error
|
||||
|
||||
posix-cmake-install:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- os: ubuntu-18.04
|
||||
- os: ubuntu-20.04
|
||||
- os: ubuntu-22.04
|
||||
- os: macos-11
|
||||
|
||||
runs-on: ${{matrix.os}}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Install packages
|
||||
if: matrix.install
|
||||
run: sudo apt install ${{matrix.install}}
|
||||
|
||||
- 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
|
||||
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY
|
||||
|
||||
- name: Configure
|
||||
run: |
|
||||
cd ../boost-root
|
||||
mkdir __build__ && cd __build__
|
||||
cmake -DBOOST_INCLUDE_LIBRARIES=$LIBRARY -DCMAKE_INSTALL_PREFIX=~/.local ..
|
||||
|
||||
- name: Install
|
||||
run: |
|
||||
cd ../boost-root/__build__
|
||||
cmake --build . --target install
|
||||
|
||||
- name: Use the installed library
|
||||
run: |
|
||||
cd ../boost-root/libs/$LIBRARY/test/cmake_install_test && mkdir __build__ && cd __build__
|
||||
cmake -DCMAKE_INSTALL_PREFIX=~/.local ..
|
||||
cmake --build .
|
||||
ctest --output-on-failure --no-tests=error
|
||||
|
||||
posix-cmake-test:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- os: ubuntu-18.04
|
||||
- os: ubuntu-20.04
|
||||
- os: ubuntu-22.04
|
||||
- os: macos-11
|
||||
|
||||
runs-on: ${{matrix.os}}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Install packages
|
||||
if: matrix.install
|
||||
run: sudo apt install ${{matrix.install}}
|
||||
|
||||
- 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
|
||||
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY
|
||||
|
||||
- name: Configure
|
||||
run: |
|
||||
cd ../boost-root
|
||||
mkdir __build__ && cd __build__
|
||||
cmake -DBOOST_INCLUDE_LIBRARIES=$LIBRARY -DBUILD_TESTING=ON ..
|
||||
|
||||
- name: Build tests
|
||||
run: |
|
||||
cd ../boost-root/__build__
|
||||
cmake --build . --target tests
|
||||
|
||||
- name: Run tests
|
||||
run: |
|
||||
cd ../boost-root/__build__
|
||||
ctest --output-on-failure --no-tests=error
|
||||
|
||||
@@ -7,30 +7,12 @@ cmake_minimum_required(VERSION 3.5...3.16)
|
||||
|
||||
project(boost_process VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX)
|
||||
|
||||
add_library(boost_process
|
||||
src/detail/environment_posix.cpp
|
||||
src/detail/environment_win.cpp
|
||||
src/detail/last_error.cpp
|
||||
src/detail/process_handle_windows.cpp
|
||||
src/detail/throw_error.cpp
|
||||
src/detail/utf8.cpp
|
||||
src/ext/cmd.cpp
|
||||
src/ext/cwd.cpp
|
||||
src/ext/env.cpp
|
||||
src/ext/exe.cpp
|
||||
src/ext/proc_info.cpp
|
||||
src/posix/close_handles.cpp
|
||||
src/windows/default_launcher.cpp
|
||||
src/environment.cpp
|
||||
src/error.cpp
|
||||
src/pid.cpp
|
||||
src/shell.cpp)
|
||||
|
||||
add_library(boost_process INTERFACE)
|
||||
add_library(Boost::process ALIAS boost_process)
|
||||
|
||||
target_include_directories(boost_process PUBLIC include)
|
||||
target_include_directories(boost_process INTERFACE include)
|
||||
target_link_libraries(boost_process
|
||||
PUBLIC
|
||||
INTERFACE
|
||||
Boost::algorithm
|
||||
Boost::asio
|
||||
Boost::config
|
||||
@@ -46,27 +28,9 @@ target_link_libraries(boost_process
|
||||
Boost::winapi
|
||||
)
|
||||
|
||||
target_compile_definitions(boost_process
|
||||
PRIVATE BOOST_PROCESS_SOURCE=1
|
||||
)
|
||||
|
||||
if (BOOST_PROCESS_USE_STD_FS)
|
||||
target_compile_definitions(boost_process PUBLIC BOOST_PROCESS_USE_STD_FS=1 )
|
||||
else()
|
||||
target_link_libraries(boost_process PUBLIC Boost::filesystem)
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
target_link_libraries(boost_process PUBLIC ntdll shell32 Advapi32 user32)
|
||||
endif()
|
||||
|
||||
if(BUILD_SHARED_LIBS)
|
||||
target_compile_definitions(boost_process PUBLIC BOOST_PROCESS_DYN_LINK)
|
||||
else()
|
||||
target_compile_definitions(boost_process PUBLIC BOOST_PROCESS_STATIC_LINK)
|
||||
endif()
|
||||
|
||||
if(BUILD_TESTING AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test/CMakeLists.txt")
|
||||
|
||||
add_subdirectory(test)
|
||||
|
||||
endif()
|
||||
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
# Copyright (c) 2024 Klemens D. Morgenstern
|
||||
#
|
||||
# Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
import os ;
|
||||
import feature ;
|
||||
import ../../config/checks/config : requires ;
|
||||
|
||||
project : requirements
|
||||
<define>BOOST_ASIO_NO_DEPRECATED
|
||||
<toolset>msvc:<define>_SCL_SECURE_NO_WARNINGS
|
||||
<toolset>msvc:<define>_CRT_SECURE_NO_DEPRECATE
|
||||
<toolset>msvc:<cxxflags>/bigobj
|
||||
<target-os>windows:<define>WIN32_LEAN_AND_MEAN
|
||||
<target-os>linux:<linkflags>-lpthread
|
||||
: source-location ../src
|
||||
;
|
||||
|
||||
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
|
||||
: detail/environment_posix.cpp
|
||||
detail/environment_win.cpp
|
||||
detail/last_error.cpp
|
||||
detail/process_handle_windows.cpp
|
||||
detail/throw_error.cpp
|
||||
detail/utf8.cpp
|
||||
ext/cmd.cpp
|
||||
ext/cwd.cpp
|
||||
ext/env.cpp
|
||||
ext/exe.cpp
|
||||
ext/proc_info.cpp
|
||||
posix/close_handles.cpp
|
||||
windows/default_launcher.cpp
|
||||
environment.cpp
|
||||
error.cpp
|
||||
pid.cpp
|
||||
shell.cpp
|
||||
;
|
||||
|
||||
if [ os.name ] = NT
|
||||
{
|
||||
lib shell32 ;
|
||||
lib Advapi32 ;
|
||||
lib Ntdll ;
|
||||
lib user32 ;
|
||||
}
|
||||
|
||||
lib boost_process
|
||||
: process_sources
|
||||
: requirements <define>BOOST_PROCESS_SOURCE=1
|
||||
<link>shared:<define>BOOST_PROCESS_DYN_LINK=1
|
||||
<boost.process.fs>boost:<library>/boost//filesystem
|
||||
<target-os>windows:<library>shell32
|
||||
<target-os>windows:<library>user32
|
||||
<target-os>windows:<library>Ntdll
|
||||
<target-os>windows:<library>Advapi32
|
||||
: usage-requirements
|
||||
<link>shared:<define>BOOST_PROCESS_DYN_LINK=1
|
||||
<boost.process.fs>boost:<library>/boost//filesystem
|
||||
;
|
||||
|
||||
boost-install boost_process ;
|
||||
@@ -14,28 +14,25 @@ using doxygen ;
|
||||
|
||||
local images = [ glob images/*.svg ] ;
|
||||
install images : $(images) : <location>html/boost_process ;
|
||||
install images_glob : $(images) : <location>$(BOOST_ROOT)/doc/html/boost_process ;
|
||||
install images_glob : $(images) : <location>$(BOOST_ROOT)/doc/html/boost_process ;
|
||||
|
||||
import type ;
|
||||
type.register XMLPROCESSWORKAROUND : : XML ;
|
||||
import generators ;
|
||||
generators.register-standard common.copy : XML : XMLPROCESSWORKAROUND ;
|
||||
|
||||
xmlprocessworkaround posix_pseudocode : v1/posix_pseudocode.xml ;
|
||||
xmlprocessworkaround windows_pseudocode : v1/windows_pseudocode.xml ;
|
||||
xmlprocessworkaround posix_pseudocode : posix_pseudocode.xml ;
|
||||
xmlprocessworkaround windows_pseudocode : windows_pseudocode.xml ;
|
||||
|
||||
path-constant INCLUDES : ../../.. ;
|
||||
|
||||
doxygen reference_v1
|
||||
doxygen autodoc
|
||||
:
|
||||
$(INCLUDES)/boost/process/v1.hpp
|
||||
[ glob $(INCLUDES)/boost/process/v1/*.hpp ]
|
||||
$(INCLUDES)/boost/process.hpp
|
||||
[ glob $(INCLUDES)/boost/process/*.hpp ]
|
||||
:
|
||||
<doxygen:param>EXCLUDE_SYMBOLS=BOOST_ASIO_INITFN_RESULT_TYPE
|
||||
<doxygen:param>"PREDEFINED=\\
|
||||
BOOST_PROCESS_DOXYGEN=1 \\
|
||||
BOOST_PROCESS_V1_INLINE=
|
||||
"
|
||||
<doxygen:param>PREDEFINED=BOOST_PROCESS_DOXYGEN
|
||||
<doxygen:param>HIDE_UNDOC_CLASSES=YES
|
||||
<doxygen:param>HIDE_UNDOC_MEMBERS=YES
|
||||
<doxygen:param>EXAMPLE_PATH=.
|
||||
@@ -70,7 +67,6 @@ doxygen reference_v2
|
||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN=DEFAULT \\
|
||||
BOOST_CONSTEXPR=constexpr \\
|
||||
BOOST_CXX14_CONSTEXPR=constexpr \\
|
||||
BOOST_PROCESS_V2_INLINE= \\
|
||||
BOOST_ATTRIBUTE_NODISCARD=[[nodiscard]]
|
||||
"
|
||||
<doxygen.doxproc.id>reference_v2
|
||||
@@ -88,7 +84,7 @@ boostbook standalone
|
||||
:
|
||||
process.qbk
|
||||
:
|
||||
<dependency>reference_v1
|
||||
<dependency>autodoc
|
||||
<dependency>reference_v2
|
||||
<dependency>images
|
||||
<dependency>images_glob
|
||||
|
||||
@@ -35,13 +35,13 @@ In this library the following functions are used for the creation of unnamed pip
|
||||
As the name suggests, named pipes have a string identifier. This means that a
|
||||
handle to them can be obtained with the identifier, too.
|
||||
|
||||
The implementation on posix uses [@http://pubs.opengroup.org/onlinepubs/009695399/functions/mkfifo.html fifos],
|
||||
The implementation on posix uses [@(http://pubs.opengroup.org/onlinepubs/009695399/functions/mkfifo.html fifos],
|
||||
which means, that the named pipe behaves like a file.
|
||||
|
||||
Windows does provide a facility called [@https://msdn.microsoft.com/en-us/library/windows/desktop/aa365150(v=vs.85).aspx named pipes],
|
||||
which also have file-like names, but are in a different scope than the actual file system.
|
||||
|
||||
[note The main reason named pipes are part of this library, is because they need to be internally used for asynchronous communication on windows.]
|
||||
[note The main reason named pipes are part of this library, is because they need to be internally used for asynchrounous communication on windows.]
|
||||
|
||||
[endsect]
|
||||
|
||||
@@ -75,15 +75,15 @@ but the one of the launching process, not the one passed to the child process.]
|
||||
The simplest form to extend functionality is to provide another handler, which
|
||||
will be called on the respective events on process launching. The names are:
|
||||
|
||||
*`boost::process::v1::on_setup`
|
||||
*`boost::process::v1::on_error`
|
||||
*`boost::process::v1::on_success`
|
||||
*`boost::process::on_setup`
|
||||
*`boost::process::on_error`
|
||||
*`boost::process::on_success`
|
||||
|
||||
|
||||
As an example:
|
||||
|
||||
```
|
||||
child c("ls", on_setup([](){cout << "On Setup" << endl;}));
|
||||
child c("ls", on_setup([](){cout << "On Setup" << endl;});
|
||||
```
|
||||
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
[def __on_exit__ [globalref boost::process::v1::on_exit on_exit]]
|
||||
[def __on_success__ [globalref boost::process::v1::extend::on_success ex::on_success]]
|
||||
[def __child__ [classref boost::process::v1::child child]]
|
||||
[def __handler__ [classref boost::process::v1::extend::handler handler]]
|
||||
[def __on_success__ [memberref boost::process::v1::extend::handler::on_success on_success]]
|
||||
[def __posix_executor__ [classref boost::process::v1::extend::posix_executor ex::posix_executor]]
|
||||
[def __windows_executor__ [classref boost::process::v1::extend::windows_executor ex::windows_executor]]
|
||||
[def __on_exit__ [globalref boost::process::on_exit on_exit]]
|
||||
[def __on_success__ [globalref boost::process::extend::on_success ex::on_success]]
|
||||
[def __child__ [classref boost::process::child child]]
|
||||
[def __handler__ [classref boost::process::extend::handler handler]]
|
||||
[def __on_success__ [memberref boost::process::extend::handler::on_success on_success]]
|
||||
[def __posix_executor__ [classref boost::process::extend::posix_executor ex::posix_executor]]
|
||||
[def __windows_executor__ [classref boost::process::extend::windows_executor ex::windows_executor]]
|
||||
[def __io_context__ [@http://www.boost.org/doc/libs/release/doc/html/boost_asio/reference/io_context.html boost::asio::io_context]]
|
||||
[def __require_io_context__ [classref boost::process::v1::extend::require_io_context ex::require_io_context]]
|
||||
[def __async_handler__ [classref boost::process::v1::extend::async_handler ex::async_handler]]
|
||||
[def __get_io_context__ [funcref boost::process::v1::extend::get_io_context ex::get_io_context]]
|
||||
[def __require_io_context__ [classref boost::process::extend::require_io_context ex::require_io_context]]
|
||||
[def __async_handler__ [classref boost::process::extend::async_handler ex::async_handler]]
|
||||
[def __get_io_context__ [funcref boost::process::extend::get_io_context ex::get_io_context]]
|
||||
|
||||
[section:extend Extensions]
|
||||
To extend the library, the header [headerref boost/process/extend.hpp extend] is provided.
|
||||
@@ -16,7 +16,7 @@ To extend the library, the header [headerref boost/process/extend.hpp extend] is
|
||||
It only provides the explicit style for custom properties, but no implicit style.
|
||||
|
||||
What this means is, that a custom initializer can be implemented, a reference which can be passed to one of the launching functions.
|
||||
If a class inherits [classref boost::process::v1::extend::handler] it will be regarded as an initializer and thus directly put into the sequence
|
||||
If a class inherits [classref boost::process::extend::handler] it will be regarded as an initializer and thus directly put into the sequence
|
||||
the executor gets passed.
|
||||
|
||||
[section:structure Structure]
|
||||
@@ -24,9 +24,9 @@ the executor gets passed.
|
||||
The executor calls different handlers of the initializers during the process launch.
|
||||
The basic structure consists of three functions, as given below:
|
||||
|
||||
* [globalref boost::process::v1::extend::on_setup on_setup]
|
||||
* [globalref boost::process::v1::extend::on_error on_error]
|
||||
* [globalref boost::process::v1::extend::on_success on_success]
|
||||
* [globalref boost::process::extend::on_setup on_setup]
|
||||
* [globalref boost::process::extend::on_error on_error]
|
||||
* [globalref boost::process::extend::on_success on_success]
|
||||
|
||||
'''
|
||||
<imagedata fileref="boost_process/windows_exec.svg"/>
|
||||
@@ -34,11 +34,11 @@ The basic structure consists of three functions, as given below:
|
||||
|
||||
Additionally posix provides three more handlers, listed below:
|
||||
|
||||
* [globalref boost::process::v1::extend::on_fork_error on_fork_error]
|
||||
* [globalref boost::process::v1::extend::on_exec_setup on_exec_setup]
|
||||
* [globalref boost::process::v1::extend::on_exec_error on_exec_error]
|
||||
* [globalref boost::process::extend::on_fork_error on_fork_error]
|
||||
* [globalref boost::process::extend::on_exec_setup on_exec_setup]
|
||||
* [globalref boost::process::extend::on_exec_error on_exec_error]
|
||||
|
||||
For more information see the reference of [classref boost::process::v1::extend::posix_executor posix_executor].
|
||||
For more information see the reference of [classref boost::process::extend::posix_executor posix_executor].
|
||||
|
||||
[endsect]
|
||||
[section:simple Simple extensions]
|
||||
@@ -55,8 +55,8 @@ __child__ c("foo", __on_success__=[](auto & exec) {std::cout << "hello world" <<
|
||||
|
||||
Considering that lambdas can also capture values, data can easily be shared between handlers.
|
||||
|
||||
To see which members the executor has, refer to [classref boost::process::v1::extend::windows_executor windows_executor]
|
||||
and [classref boost::process::v1::extend::posix_executor posix_executor].
|
||||
To see which members the executor has, refer to [classref boost::process::extend::windows_executor windows_executor]
|
||||
and [classref boost::process::extend::posix_executor posix_executor].
|
||||
|
||||
[note Combined with __on_exit__ this can also handle the process exit.]
|
||||
|
||||
@@ -67,7 +67,7 @@ and [classref boost::process::v1::extend::posix_executor posix_executor].
|
||||
[section:handler Handler Types]
|
||||
|
||||
Since the previous example is in a functional style, it is not very reusable.
|
||||
To solve that problem, the [classref boost::process::v1::extend::handler handler] has an alias in the `boost::process::v1::extend` namespace, to be inherited.
|
||||
To solve that problem, the [classref boost::process::extend::handler handler] has an alias in the `boost::process::extend` namespace, to be inherited.
|
||||
So let's implement the hello world example in a class.
|
||||
|
||||
```
|
||||
@@ -86,7 +86,7 @@ __child__ c("foo", hello_world());
|
||||
|
||||
[note The implementation is done via overloading, not overriding.]
|
||||
|
||||
Every handler not implemented defaults to [classref boost::process::v1::extend::handler handler], where an empty handler is defined for each event.
|
||||
Every handler not implemented defaults to [classref boost::process::extend::handler handler], where an empty handler is defined for each event.
|
||||
|
||||
[endsect]
|
||||
|
||||
@@ -108,11 +108,11 @@ struct async_foo : __handler__, __require_io_context__
|
||||
}
|
||||
};
|
||||
```
|
||||
[note Inheriting [globalref boost::process::v1::extend::require_io_context require_io_context] is necessary, so [funcref boost::process::v1::system system] provides one.]
|
||||
[note Inheriting [globalref boost::process::extend::require_io_context require_io_context] is necessary, so [funcref boost::process::system system] provides one.]
|
||||
|
||||
Additionally the handler can provide a function that is invoked when the child process exits. This is done through __async_handler__.
|
||||
|
||||
[note [globalref boost::process::v1::extend::async_handler async_handler] implies [globalref boost::process::v1::extend::require_io_context require_io_context] .]
|
||||
[note [globalref boost::process::extend::async_handler async_handler] implies [globalref boost::process::extend::require_io_context require_io_context] .]
|
||||
|
||||
```
|
||||
struct async_bar : __handler, __async_handler__
|
||||
@@ -131,7 +131,7 @@ struct async_bar : __handler, __async_handler__
|
||||
```
|
||||
|
||||
|
||||
[caution `on_exit_handler` does not default and is always required when [classref boost::process::v1::extend::async_handler async_handler] is inherited. ]
|
||||
[caution `on_exit_handler` does not default and is always required when [classref boost::process::extend::async_handler async_handler] is inherited. ]
|
||||
|
||||
[caution `on_exit_handler` uses `boost::asio::signal_set` to listen for SIGCHLD on posix. The application must not also register a signal handler for SIGCHLD using functions such as `signal()` or `sigaction()` (but using `boost::asio::signal_set` is fine). ]
|
||||
|
||||
@@ -156,7 +156,7 @@ auto set_error = [](auto & exec)
|
||||
__child__ c("foo", on_setup=set_error);
|
||||
```
|
||||
|
||||
Since we do not specify the error-handling mode in this example, this will throw [classref boost::process::v1::process_error process_error].
|
||||
Since we do not specify the error-handling mode in this example, this will throw [classref boost::process::process_error process_error].
|
||||
|
||||
[endsect]
|
||||
|
||||
@@ -10,15 +10,15 @@ Boost.Process is a library to manage system processes. It can be used to:
|
||||
|
||||
Here's a simple example of how to start a program with Boost.Process:
|
||||
|
||||
[def ipstream [classref boost::process::v1::ipstream ipstream]]
|
||||
[def system [funcref boost::process::v1::system system]]
|
||||
[def std_out [globalref boost::process::v1::std_out std_out]]
|
||||
[def child [globalref boost::process::v1::child child]]
|
||||
[def ipstream [classref boost::process::ipstream ipstream]]
|
||||
[def system [funcref boost::process::system system]]
|
||||
[def std_out [globalref boost::process::std_out std_out]]
|
||||
[def child [globalref boost::process::child child]]
|
||||
[def boost/process.hpp [headerref boost/process.hpp boost/process.hpp]]
|
||||
[def std::string [@http://en.cppreference.com/w/cpp/string/basic_string std::string]]
|
||||
[def std::getline [@http://en.cppreference.com/w/cpp/string/basic_string/getline std::getline]]
|
||||
|
||||
[import ../../example/intro.cpp]
|
||||
[import ../example/intro.cpp]
|
||||
[intro]
|
||||
|
||||
[endsect]
|
||||
60
doc/posix_pseudocode.xml
Normal file
60
doc/posix_pseudocode.xml
Normal file
@@ -0,0 +1,60 @@
|
||||
<?xml version="1.0" standalone="yes"?>
|
||||
<programlisting>
|
||||
for (auto & s : seq)
|
||||
s.<methodname alt="boost::process::extend::handler::on_setup">on_setup</methodname>(*this);
|
||||
|
||||
if (<methodname alt="boost::process::extend::posix_executor::error">error</methodname>())
|
||||
{
|
||||
for (auto & s : seq)
|
||||
s.<methodname alt="boost::process::extend::handler::on_error">on_error</methodname>(*this, <methodname alt="boost::process::extend::posix_executor::error">error</methodname>());
|
||||
return <classname alt="boost::process::child">child</classname>();
|
||||
}
|
||||
|
||||
pid = <ulink url="http://pubs.opengroup.org/onlinepubs/009695399/functions/fork.html">fork()</ulink>
|
||||
<methodname alt="boost::process::extend::handler::on_setup">on_setup</methodname>(*this);
|
||||
|
||||
if (pid == -1) //fork error
|
||||
{
|
||||
<methodname alt="boost::process::extend::posix_executor::set_error">set_error</methodname>(<functionname alt="boost::process::extend::get_last_error">get_last_error</functionname>());
|
||||
for (auto & s : seq)
|
||||
s.<methodname alt="boost::process::extend::handler::on_fork_error">on_fork_error</methodname>(*this, <methodname alt="boost::process::extend::posix_executor::error">error</methodname>());
|
||||
for (auto & s : seq)
|
||||
s.<methodname alt="boost::process::extend::handler::on_error">on_error</methodname>(*this, <methodname alt="boost::process::extend::posix_executor::error">error</methodname>());
|
||||
return <classname alt="boost::process::child">child</classname>()
|
||||
}
|
||||
else if (pid == 0) //child process
|
||||
{
|
||||
for (auto & s : seq)
|
||||
s.<methodname alt="boost::process::extend::handler::on_exec_setup">on_exec_setup</methodname>(*this);
|
||||
<ulink url="http://pubs.opengroup.org/onlinepubs/009695399/functions/exec.html">execve</ulink>(exe, cmd_line, env);
|
||||
auto ec = <functionname alt="boost::process::extend::get_last_error">get_last_error</functionname>();
|
||||
for (auto & s : seq)
|
||||
s.<methodname alt="boost::process::extend::handler::on_exec_error">on_exec_error</methodname>(*this);
|
||||
|
||||
<emphasis>unspecified();</emphasis>//here the error is send to the father process interally
|
||||
|
||||
<ulink url="http://en.cppreference.com/w/cpp/utility/program/exit">std::exit</ulink>(<ulink url="http://en.cppreference.com/w/c/program/EXIT_status">EXIT_FAILURE</ulink>);
|
||||
return <classname alt="boost::process::child">child</classname>(); //for C++ compliance
|
||||
}
|
||||
|
||||
<classname alt="boost::process::child">child</classname> c(pid, exit_code);
|
||||
|
||||
<emphasis>unspecified();</emphasis>//here, we read the the error from the child process
|
||||
|
||||
if (<methodname alt="boost::process::extend::posix_executor::error">error</methodname>())
|
||||
for (auto & s : seq)
|
||||
s.<methodname alt="boost::process::extend::handler::on_error">on_error</methodname>(*this, <methodname alt="boost::process::extend::posix_executor::error">error</methodname>());
|
||||
else
|
||||
for (auto & s : seq)
|
||||
s.<methodname alt="boost::process::extend::handler::on_error">on_success</methodname>(*this);
|
||||
|
||||
//now we check again, because a on_success handler might've errored.
|
||||
if (<methodname alt="boost::process::extend::posix_executor::error">error</methodname>())
|
||||
{
|
||||
for (auto & s : seq)
|
||||
s.<methodname alt="boost::process::extend::handler::on_error">on_error</methodname>(*this, <methodname alt="boost::process::extend::posix_executor::error">error</methodname>());
|
||||
return <classname alt="boost::process::child">child</classname>();
|
||||
}
|
||||
else
|
||||
return c;
|
||||
</programlisting>
|
||||
@@ -11,8 +11,14 @@
|
||||
]
|
||||
]
|
||||
|
||||
[note Process v1 will be deprecated in the future. Use v2 for new projects.]
|
||||
[note [link process.v2 Process V2] is available as experimental]
|
||||
|
||||
[include v1.qbk]
|
||||
[include v2.qbk]
|
||||
[include introduction.qbk]
|
||||
[include concepts.qbk]
|
||||
[include tutorial.qbk]
|
||||
[include design.qbk]
|
||||
[include extend.qbk]
|
||||
[include faq.qbk]
|
||||
[xinclude autodoc.xml]
|
||||
[include acknowledgements.qbk]
|
||||
[include v2.qbk]
|
||||
@@ -1,49 +1,49 @@
|
||||
[def bp::system [funcref boost::process::v1::system bp::system]]
|
||||
[def bp::async_system [funcref boost::process::v1::async_system bp::async_system]]
|
||||
[def bp::spawn [funcref boost::process::v1::spawn bp::spawn]]
|
||||
[def bp::child [classref boost::process::v1::child bp::child]]
|
||||
[def bp::cmd [classref boost::process::v1::cmd bp::cmd]]
|
||||
[def bp::group [classref boost::process::v1::group bp::group]]
|
||||
[def bp::ipstream [classref boost::process::v1::ipstream bp::ipstream]]
|
||||
[def bp::opstream [classref boost::process::v1::opstream bp::opstream]]
|
||||
[def bp::pstream [classref boost::process::v1::pstream bp::pstream]]
|
||||
[def bp::pipe [classref boost::process::v1::pipe bp::pipe]]
|
||||
[def bp::async_pipe [classref boost::process::v1::async_pipe bp::async_pipe]]
|
||||
[def bp::search_path [funcref boost::process::v1::search_path bp::search_path]]
|
||||
[def bp::system [funcref boost::process::system bp::system]]
|
||||
[def bp::async_system [funcref boost::process::async_system bp::async_system]]
|
||||
[def bp::spawn [funcref boost::process::spawn bp::spawn]]
|
||||
[def bp::child [classref boost::process::child bp::child]]
|
||||
[def bp::cmd [classref boost::process::cmd bp::cmd]]
|
||||
[def bp::group [classref boost::process::group bp::group]]
|
||||
[def bp::ipstream [classref boost::process::ipstream bp::ipstream]]
|
||||
[def bp::opstream [classref boost::process::opstream bp::opstream]]
|
||||
[def bp::pstream [classref boost::process::pstream bp::pstream]]
|
||||
[def bp::pipe [classref boost::process::pipe bp::pipe]]
|
||||
[def bp::async_pipe [classref boost::process::async_pipe bp::async_pipe]]
|
||||
[def bp::search_path [funcref boost::process::search_path bp::search_path]]
|
||||
[def boost_org [@www.boost.org "www.boost.org"]]
|
||||
[def std::system [@http://en.cppreference.com/w/cpp/utility/program/system std::system]]
|
||||
[def child_running [memberref boost::process::v1::child::running running]]
|
||||
[def child_wait [memberref boost::process::v1::child::wait wait]]
|
||||
[def child_wait_for [memberref boost::process::v1::child::wait_for wait_for]]
|
||||
[def child_exit_code [memberref boost::process::v1::child::exit_code exit_code]]
|
||||
[def group_wait_for [memberref boost::process::v1::group::wait_for wait_for]]
|
||||
[def bp::on_exit [globalref boost::process::v1::on_exit bp::on_exit]]
|
||||
[def bp::null [globalref boost::process::v1::null bp::null]]
|
||||
[def child_terminate [memberref boost::process::v1::child::terminate terminate]]
|
||||
[def group_terminate [memberref boost::process::v1::group::terminate terminate]]
|
||||
[def group_wait [memberref boost::process::v1::group::wait wait]]
|
||||
[def bp::std_in [globalref boost::process::v1::std_in bp::std_in]]
|
||||
[def bp::std_out [globalref boost::process::v1::std_out bp::std_out]]
|
||||
[def bp::std_err [globalref boost::process::v1::std_err bp::std_err]]
|
||||
[def child_running [memberref boost::process::child::running running]]
|
||||
[def child_wait [memberref boost::process::child::wait wait]]
|
||||
[def child_wait_for [memberref boost::process::child::wait_for wait_for]]
|
||||
[def child_exit_code [memberref boost::process::child::exit_code exit_code]]
|
||||
[def group_wait_for [memberref boost::process::group::wait_for wait_for]]
|
||||
[def bp::on_exit [globalref boost::process::on_exit bp::on_exit]]
|
||||
[def bp::null [globalref boost::process::null bp::null]]
|
||||
[def child_terminate [memberref boost::process::child::terminate terminate]]
|
||||
[def group_terminate [memberref boost::process::group::terminate terminate]]
|
||||
[def group_wait [memberref boost::process::group::wait wait]]
|
||||
[def bp::std_in [globalref boost::process::std_in bp::std_in]]
|
||||
[def bp::std_out [globalref boost::process::std_out bp::std_out]]
|
||||
[def bp::std_err [globalref boost::process::std_err bp::std_err]]
|
||||
[def io_service [@http://www.boost.org/doc/libs/release/doc/html/boost_asio/reference/io_service.html boost::asio::io_service]]
|
||||
[def asio_buffer [@http://www.boost.org/doc/libs/release/doc/html/boost_asio/reference/buffer.html boost::asio::buffer]]
|
||||
[def asio_async_read [@http://www.boost.org/doc/libs/release/doc/html/boost_asio/reference/async_read.html boost::asio::async_read]]
|
||||
[def bp::environment [classref boost::process::v1::basic_environment bp::environment]]
|
||||
[def bp::native_environment [classref boost::process::v1::basic_native_environment bp::native_environment]]
|
||||
[def bp::environment [classref boost::process::basic_environment bp::environment]]
|
||||
[def bp::native_environment [classref boost::process::basic_native_environment bp::native_environment]]
|
||||
[def boost::this_process::environment [funcref boost::this_process::environment boost::this_process::environment]]
|
||||
[def std::chrono::seconds [@http://en.cppreference.com/w/cpp/chrono/duration std::chrono::seconds]]
|
||||
[def std::vector [@http://en.cppreference.com/w/cpp/container/vector std::vector]]
|
||||
|
||||
[def __wait_for__ [memberref boost::process::v1::child::wait_for wait_for]]
|
||||
[def __wait_until__ [memberref boost::process::v1::child::wait_until wait_until]]
|
||||
[def __detach__ [memberref boost::process::v1::child::detach detach]]
|
||||
[def __wait_for__ [memberref boost::process::child::wait_for wait_for]]
|
||||
[def __wait_until__ [memberref boost::process::child::wait_until wait_until]]
|
||||
[def __detach__ [memberref boost::process::child::detach detach]]
|
||||
|
||||
[def __reference__ [link process.reference reference]]
|
||||
[def __concepts__ [link boost_process.concepts concepts]]
|
||||
|
||||
[def boost::asio::yield_context [@http://www.boost.org/doc/libs/release/doc/html/boost_asio/reference/yield_context.html boost::asio::yield_context]]
|
||||
[def boost::asio::coroutine [@http://www.boost.org/doc/libs/release/doc/html/boost_asio/reference/coroutine.html boost::asio::coroutine]]
|
||||
[def bp::env [globalref boost::process::v1::env bp::env]]
|
||||
[def bp::env [globalref boost::process::env bp::env]]
|
||||
|
||||
[section:tutorial Tutorial]
|
||||
|
||||
@@ -82,10 +82,10 @@ int result = bp::system("/usr/bin/g++", "main.cpp");
|
||||
```
|
||||
|
||||
With that syntax we still have "g++" hard-coded, so let's assume we get the string
|
||||
from an external source as `boost::process::v1::filesystem::path`, we can do this too.
|
||||
from an external source as `boost::process::filesystem::path`, we can do this too.
|
||||
|
||||
```
|
||||
boost::process::v1::filesystem::path p = "/usr/bin/g++"; //or get it from somewhere else.
|
||||
boost::process::filesystem::path p = "/usr/bin/g++"; //or get it from somewhere else.
|
||||
int result = bp::system(p, "main.cpp");
|
||||
```
|
||||
|
||||
@@ -93,28 +93,28 @@ Now we might want to find the `g++` executable in the `PATH`-variable, as the `c
|
||||
`Boost.process` provides a function to this end: bp::search_path.
|
||||
|
||||
```
|
||||
boost::process::v1::filesystem::path p = bp::search_path("g++"); //or get it from somewhere else.
|
||||
boost::process::filesystem::path p = bp::search_path("g++"); //or get it from somewhere else.
|
||||
int result = bp::system(p, "main.cpp");
|
||||
```
|
||||
|
||||
[note [funcref boost::process::v1::search_path search_path] will search for any executable with that name.
|
||||
[note [funcref boost::process::search_path search_path] will search for any executable with that name.
|
||||
This also includes to add a file suffix on windows, such as `.exe` or `.bat`.]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:launch_mode Launch functions]
|
||||
|
||||
Given that our example used the [funcref boost::process::v1::system system] function,
|
||||
Given that our example used the [funcref boost::process::system system] function,
|
||||
our program will wait until the child process is completed. This may be unwanted,
|
||||
especially since compiling can take a while.
|
||||
|
||||
In order to avoid that, boost.process provides several ways to launch a process.
|
||||
Besides the already mentioned [funcref boost::process::v1::system system] function and its
|
||||
asynchronous version [funcref boost::process::v1::async_system async_system],
|
||||
we can also use the [funcref boost::process::v1::spawn spawn] function or the
|
||||
[classref boost::process::v1::child child] class.
|
||||
Besides the already mentioned [funcref boost::process::system system] function and its
|
||||
asynchronous version [funcref boost::process::async_system async_system],
|
||||
we can also use the [funcref boost::process::spawn spawn] function or the
|
||||
[classref boost::process::child child] class.
|
||||
|
||||
The [funcref boost::process::v1::spawn spawn] function launches a process and
|
||||
The [funcref boost::process::spawn spawn] function launches a process and
|
||||
immediately detaches it, so no handle will be returned and the process will be ignored.
|
||||
This is not what we need for compiling, but maybe we want to entertain the user,
|
||||
while compiling:
|
||||
@@ -124,7 +124,7 @@ bp::spawn(bp::search_path("chrome"), boost_org);
|
||||
```
|
||||
|
||||
Now for the more sensible approach for compiling: a non-blocking execution.
|
||||
To implement that, we directly call the constructor of [classref boost::process::v1::child child].
|
||||
To implement that, we directly call the constructor of [classref boost::process::child child].
|
||||
|
||||
```
|
||||
bp::child c(bp::search_path("g++"), "main.cpp");
|
||||
@@ -189,9 +189,9 @@ Now, let's take a more visual example for reading data.
|
||||
which reads the outline, i.e. a list of all entry points, of a binary.
|
||||
Every entry point will be put into a single line, and we will use a pipe to read it.
|
||||
At the end an empty line is appended, which we use as the indication to stop reading.
|
||||
Boost.process provides the pipestream ([classref boost::process::v1::ipstream ipstream],
|
||||
[classref boost::process::v1::opstream opstream], [classref boost::process::v1::pstream pstream]) to
|
||||
wrap around the [classref boost::process::v1::pipe pipe] and provide an implementation of the
|
||||
Boost.process provides the pipestream ([classref boost::process::ipstream ipstream],
|
||||
[classref boost::process::opstream opstream], [classref boost::process::pstream pstream]) to
|
||||
wrap around the [classref boost::process::pipe pipe] and provide an implementation of the
|
||||
[@http://en.cppreference.com/w/cpp/io/basic_istream std::istream],
|
||||
[@http://en.cppreference.com/w/cpp/io/basic_ostream std::ostream] and
|
||||
[@http://en.cppreference.com/w/cpp/io/basic_iostream std::iostream] interface.
|
||||
@@ -217,7 +217,7 @@ std::vector<std::string> read_outline(std::string & file)
|
||||
What this does is redirect the `stdout` of the process into a pipe and we read this
|
||||
synchronously.
|
||||
|
||||
[note You can do the same thing with [globalref boost::process::v1::std_err std_err].]
|
||||
[note You can do the same thing with [globalref boost::process::std_err std_err].]
|
||||
|
||||
Now we get the name from `nm` and we might want to demangle it, so we use input and output.
|
||||
`nm` has a demangle option, but for the sake of the example, we'll use
|
||||
@@ -267,8 +267,8 @@ This forwards the data from `nm` to `c++filt` without your process needing to do
|
||||
|
||||
Boost.process allows the usage of boost.asio to implement asynchronous I/O.
|
||||
If you are familiar with [@http://www.boost.org/doc/libs/release/libs/asio/ boost.asio] (which we highly recommend),
|
||||
you can use [classref boost::process::v1::async_pipe async_pipe] which is implemented
|
||||
as an I/O-Object and can be used like [classref boost::process::v1::pipe pipe] as shown above.
|
||||
you can use [classref boost::process::async_pipe async_pipe] which is implemented
|
||||
as an I/O-Object and can be used like [classref boost::process::pipe pipe] as shown above.
|
||||
|
||||
Now we get back to our compiling example. For `nm` we might analyze the output line by line,
|
||||
but the compiler output will just be put into one large buffer.
|
||||
@@ -304,7 +304,7 @@ int result = c.exit_code();
|
||||
```
|
||||
|
||||
[note Passing an instance of io_service to the launching function automatically cause it to wait asynchronously for the exit, so no call of
|
||||
[memberref boost::process::v1::child::wait wait] is needed.]
|
||||
[memberref boost::process::child::wait wait] is needed.]
|
||||
|
||||
To make it even easier, you can use [@http://en.cppreference.com/w/cpp/thread/future std::future] for asynchronous operations
|
||||
(you will still need to pass a reference to a io_service) to the launching function, unless you use bp::system or bp::async_system.
|
||||
@@ -348,7 +348,7 @@ and use the following code, the `gcc` process will still run afterwards:
|
||||
|
||||
```
|
||||
bp::child c("make");
|
||||
if (!c.child_wait_for(std::chrono::seconds(10))) //give it 10 seconds
|
||||
if (!c.child_wait_for(std::chrono::seconds(10)) //give it 10 seconds
|
||||
c.child_terminate(); //then terminate
|
||||
```
|
||||
|
||||
@@ -357,14 +357,14 @@ So in order to also terminate `gcc` we can use a group.
|
||||
```
|
||||
bp::group g;
|
||||
bp::child c("make", g);
|
||||
if (!g.group_wait_for(std::chrono::seconds(10)))
|
||||
if (!g.group_wait_for(std::chrono::seconds(10))
|
||||
g.group_terminate();
|
||||
|
||||
c.child_wait(); //to avoid a zombie process & get the exit code
|
||||
```
|
||||
|
||||
Now given the example, we still call child_wait to avoid a zombie process.
|
||||
An easier solution for that might be to use [funcref boost::process::v1::spawn spawn].
|
||||
An easier solution for that might be to use [funcref boost::process::spawn spawn].
|
||||
|
||||
|
||||
To put two processes into one group, the following code suffices. Spawn already
|
||||
@@ -412,7 +412,7 @@ bp::system("stuff", env_);
|
||||
```
|
||||
|
||||
A more convenient way to modify the environment for the child is the
|
||||
[globalref boost::process::v1::env env] property, which can be used in the example as following:
|
||||
[globalref boost::process::env env] property, which can be used in the example as following:
|
||||
|
||||
```
|
||||
bp::system("stuff", bp::env["VALUE_1"]="foo", bp::env["VALUE_2"]+={"bar1", "bar2"});
|
||||
11
doc/v1.qbk
11
doc/v1.qbk
@@ -1,11 +0,0 @@
|
||||
[section:v1 Process V1]
|
||||
|
||||
[include v1/introduction.qbk]
|
||||
[include v1/concepts.qbk]
|
||||
[include v1/tutorial.qbk]
|
||||
[include v1/design.qbk]
|
||||
[include v1/extend.qbk]
|
||||
[include v1/faq.qbk]
|
||||
[xinclude reference_v2.xml]
|
||||
|
||||
[endsect]
|
||||
@@ -1,60 +0,0 @@
|
||||
<?xml version="1.0" standalone="yes"?>
|
||||
<programlisting>
|
||||
for (auto & s : seq)
|
||||
s.<methodname alt="boost::process::v1::extend::handler::on_setup">on_setup</methodname>(*this);
|
||||
|
||||
if (<methodname alt="boost::process::v1::extend::posix_executor::error">error</methodname>())
|
||||
{
|
||||
for (auto & s : seq)
|
||||
s.<methodname alt="boost::process::v1::extend::handler::on_error">on_error</methodname>(*this, <methodname alt="boost::process::v1::extend::posix_executor::error">error</methodname>());
|
||||
return <classname alt="boost::process::v1::child">child</classname>();
|
||||
}
|
||||
|
||||
pid = <ulink url="http://pubs.opengroup.org/onlinepubs/009695399/functions/fork.html">fork()</ulink>
|
||||
<methodname alt="boost::process::v1::extend::handler::on_setup">on_setup</methodname>(*this);
|
||||
|
||||
if (pid == -1) //fork error
|
||||
{
|
||||
<methodname alt="boost::process::v1::extend::posix_executor::set_error">set_error</methodname>(<functionname alt="boost::process::v1::extend::get_last_error">get_last_error</functionname>());
|
||||
for (auto & s : seq)
|
||||
s.<methodname alt="boost::process::v1::extend::handler::on_fork_error">on_fork_error</methodname>(*this, <methodname alt="boost::process::v1::extend::posix_executor::error">error</methodname>());
|
||||
for (auto & s : seq)
|
||||
s.<methodname alt="boost::process::v1::extend::handler::on_error">on_error</methodname>(*this, <methodname alt="boost::process::v1::extend::posix_executor::error">error</methodname>());
|
||||
return <classname alt="boost::process::v1::child">child</classname>()
|
||||
}
|
||||
else if (pid == 0) //child process
|
||||
{
|
||||
for (auto & s : seq)
|
||||
s.<methodname alt="boost::process::v1::extend::handler::on_exec_setup">on_exec_setup</methodname>(*this);
|
||||
<ulink url="http://pubs.opengroup.org/onlinepubs/009695399/functions/exec.html">execve</ulink>(exe, cmd_line, env);
|
||||
auto ec = <functionname alt="boost::process::v1::extend::get_last_error">get_last_error</functionname>();
|
||||
for (auto & s : seq)
|
||||
s.<methodname alt="boost::process::v1::extend::handler::on_exec_error">on_exec_error</methodname>(*this);
|
||||
|
||||
<emphasis>unspecified();</emphasis>//here the error is sent to the father process internally
|
||||
|
||||
<ulink url="http://en.cppreference.com/w/cpp/utility/program/exit">std::exit</ulink>(<ulink url="http://en.cppreference.com/w/c/program/EXIT_status">EXIT_FAILURE</ulink>);
|
||||
return <classname alt="boost::process::v1::child">child</classname>(); //for C++ compliance
|
||||
}
|
||||
|
||||
<classname alt="boost::process::v1::child">child</classname> c(pid, exit_code);
|
||||
|
||||
<emphasis>unspecified();</emphasis>//here, we read the error from the child process
|
||||
|
||||
if (<methodname alt="boost::process::v1::extend::posix_executor::error">error</methodname>())
|
||||
for (auto & s : seq)
|
||||
s.<methodname alt="boost::process::v1::extend::handler::on_error">on_error</methodname>(*this, <methodname alt="boost::process::v1::extend::posix_executor::error">error</methodname>());
|
||||
else
|
||||
for (auto & s : seq)
|
||||
s.<methodname alt="boost::process::v1::extend::handler::on_error">on_success</methodname>(*this);
|
||||
|
||||
//now we check again, because an on_success handler might've errored.
|
||||
if (<methodname alt="boost::process::v1::extend::posix_executor::error">error</methodname>())
|
||||
{
|
||||
for (auto & s : seq)
|
||||
s.<methodname alt="boost::process::v1::extend::handler::on_error">on_error</methodname>(*this, <methodname alt="boost::process::v1::extend::posix_executor::error">error</methodname>());
|
||||
return <classname alt="boost::process::v1::child">child</classname>();
|
||||
}
|
||||
else
|
||||
return c;
|
||||
</programlisting>
|
||||
@@ -1,42 +0,0 @@
|
||||
<?xml version="1.0" standalone="yes"?>
|
||||
<programlisting>
|
||||
for (auto & s : seq)
|
||||
s.<methodname alt="boost::process::v1::extend::handler::on_setup">on_setup</methodname>(*this);
|
||||
|
||||
if (<methodname alt="boost::process::v1::extend::windows_executor::error">error</methodname>())
|
||||
{
|
||||
for (auto & s : seq)
|
||||
s.<methodname alt="boost::process::v1::extend::handler::on_error">on_error</methodname>(*this, <methodname alt="boost::process::v1::extend::windows_executor::error">error</methodname>());
|
||||
return <classname alt="boost::process::v1::child">child</classname>();
|
||||
}
|
||||
int err_code = <ulink url="https://msdn.microsoft.com/en-us/library/windows/desktop/ms682425.aspx">CreateProcess</ulink>(
|
||||
exe,
|
||||
cmd_line,
|
||||
proc_attrs,
|
||||
thread_attrs,
|
||||
creation_flags,
|
||||
env,
|
||||
work_dir,
|
||||
startup_info,
|
||||
proc_info);
|
||||
|
||||
<classname alt="boost::process::v1::child">child</classname> c(proc_info, exit_code);
|
||||
|
||||
if (<methodname alt="boost::process::v1::extend::windows_executor::error">error</methodname>())
|
||||
for (auto & s : seq)
|
||||
s.<methodname alt="boost::process::v1::extend::handler::on_error">on_error</methodname>(*this, <methodname alt="boost::process::v1::extend::windows_executor::error">error</methodname>());
|
||||
else
|
||||
for (auto & s : seq)
|
||||
s.<methodname alt="boost::process::v1::extend::handler::on_error">on_success</methodname>(*this);
|
||||
|
||||
//now we check again, because an on_success handler might've errored.
|
||||
if (<methodname alt="boost::process::v1::extend::windows_executor::error">error</methodname>())
|
||||
{
|
||||
for (auto & s : seq)
|
||||
s.<methodname alt="boost::process::v1::extend::handler::on_error">on_error</methodname>(*this, <methodname alt="boost::process::v1::extend::windows_executor::error">error</methodname>());
|
||||
return <classname alt="boost::process::v1::child">child</classname>();
|
||||
}
|
||||
else
|
||||
return c;
|
||||
|
||||
</programlisting>
|
||||
@@ -9,7 +9,7 @@ Additionally, environment can be lists separated by `:` or `;`; `environment::va
|
||||
`environment::value_view` can be used to iterate those.
|
||||
|
||||
Beyond that, the requirements on an environment are a low as possible;
|
||||
an environment is either a list of strings or a list of string-pairs. It is however recommended to use the environment types,
|
||||
an environment is either a list of strings or a list of string-pairs. It is however recommented to use the environment types,
|
||||
as to have the right value comparisons.
|
||||
|
||||
To note is the `find_executable` functions, which searches in an environment for an executable.
|
||||
@@ -20,8 +20,8 @@ To note is the `find_executable` functions, which searches in an environment for
|
||||
|
||||
std::unordered_map<environment::key, environment::value> my_env =
|
||||
{
|
||||
{"SECRET", "THIS_IS_A_TEST"},
|
||||
{"PATH", {"/bin", "/usr/bin"}}
|
||||
{"SECRET", "THIS_IS_A_TEST"}
|
||||
{"PATH", {"/bin", "/usr/bin"}
|
||||
};
|
||||
|
||||
auto other_exe = environment::find_executable("g++", my_env);
|
||||
@@ -35,10 +35,10 @@ The subprocess environment assignment follows the same constraints:
|
||||
asio::io_context ctx;
|
||||
std::unordered_map<environment::key, environment::value> my_env =
|
||||
{
|
||||
{"SECRET", "THIS_IS_A_TEST"},
|
||||
{"PATH", {"/bin", "/usr/bin"}}
|
||||
{"SECRET", "THIS_IS_A_TEST"}
|
||||
{"PATH", {"/bin", "/usr/bin"}
|
||||
};
|
||||
auto exe = find_executable("g++");
|
||||
auto exe = find_executable("g++"), my_env);
|
||||
process proc(ctx, exe, {"main.cpp"}, process_environment(my_env));
|
||||
process pro2(ctx, exe, {"test.cpp"}, process_environment(my_env));
|
||||
```
|
||||
|
||||
@@ -27,7 +27,7 @@ For process v2, the interfaces is simple:
|
||||
extern asio::io_context ctx;
|
||||
process proc(ctx, "./test", {"--help"}, process_io{nullptr, {}, {}}, process_environment(my_env));
|
||||
|
||||
Every initializer addresses one logical component (e.g. stdio) instead of multiple ones accumulating.
|
||||
Every initializer adresses one logical compoent (e.g. stdio) instead of multiple ones accumulating.
|
||||
Furthermore, every process has a path and arguments, instead of a confusing mixture of cmd-style and
|
||||
exe-args that can be randomly spread out.
|
||||
|
||||
@@ -57,7 +57,7 @@ file-handles for the subprocess.
|
||||
|
||||
Certain parts of boost.process were not as reliable as they should've been.
|
||||
|
||||
This concerns especially the `wait_for` and `wait_until` functions on the process.
|
||||
This concerns especially the `wait_for`` and `wait_until` functions on the process.
|
||||
The latter are easy to do on windows, but posix does not provide an API for this.
|
||||
Thus the wait_for used signals or fork, which was all but safe.
|
||||
Since process v2 is based on asio and thus supports cancellation,
|
||||
|
||||
@@ -21,7 +21,7 @@ A launcher is invoked through the call operator.
|
||||
```
|
||||
auto l = windows::as_user_launcher((HANDLE)0xDEADBEEF);
|
||||
asio::io_context ctx;
|
||||
boost::system::error_code ec;
|
||||
boost::system::eror_code ec;
|
||||
auto proc = l(ctx, ec, "C:\\User\\boost\\Downloads\\totally_not_a_virus.exe", {});
|
||||
```
|
||||
|
||||
@@ -38,7 +38,7 @@ Alternatively, the `vfork_launcher` can report errors directly back to the paren
|
||||
Thus some calls to the initializers occur after forking from the child process.
|
||||
|
||||
```
|
||||
struct custom_initializer
|
||||
struct custom_initalizer
|
||||
{
|
||||
// functions called from the parent process:
|
||||
|
||||
@@ -47,7 +47,7 @@ Thus some calls to the initializers occur after forking from the child process.
|
||||
template<typename Launcher>
|
||||
error_code on_setup(Launcher & launcher, const filesystem::path &executable, const char * const * (&cmd_line));
|
||||
|
||||
// called for every initializer if an error occurred during setup or process creation
|
||||
// called for every initializer if an error occured during setup or process creation
|
||||
template<typename Launcher>
|
||||
void on_error(Launcher & launcher, const filesystem::path &executable, const char * const * (&cmd_line),
|
||||
const error_code & ec);
|
||||
@@ -56,7 +56,7 @@ Thus some calls to the initializers occur after forking from the child process.
|
||||
template<typename Launcher>
|
||||
void on_success(Launcher & launcher, const filesystem::path &executable, const char * const * (&cmd_line));
|
||||
|
||||
// called for every initializer if an error occurred when forking, in addition to on_error.
|
||||
// called for every initializer if an error occured when forking, in addtion to on_error.
|
||||
template<typename Launcher>
|
||||
void on_fork_error(Launcher & launcher, const filesystem::path &executable, const char * const * (&cmd_line),
|
||||
const error_code & ec);
|
||||
@@ -94,7 +94,7 @@ The launcher will close all non-whitelisted file descriptors after `on_exec_setu
|
||||
|
||||
[section:windows Windows Launchers]
|
||||
|
||||
Windows launchers are pretty straight forward, they will call the following functions on the initializer if present.
|
||||
Windows launchers are pretty streight forward, they will call the following functions on the initializer if present.
|
||||
|
||||
```
|
||||
struct custom_initializer
|
||||
@@ -103,7 +103,7 @@ Windows launchers are pretty straight forward, they will call the following func
|
||||
template<typename Launcher>
|
||||
error_code on_setup(Launcher & launcher, const filesystem::path &executable, std::wstring &cmd_line);
|
||||
|
||||
// called for every initializer if an error occurred during setup or process creation
|
||||
// called for every initializer if an error occured during setup or process creation
|
||||
template<typename Launcher>
|
||||
void on_error(Launcher & launcher, const filesystem::path &executable, std::wstring &cmd_line,
|
||||
const error_code & ec);
|
||||
|
||||
@@ -32,7 +32,7 @@ also returned from `.wait()`.
|
||||
```
|
||||
|
||||
The normal exit-code is what the subprocess returned from `main`;
|
||||
posix will however add additional information about the process.
|
||||
posix will however add addtional information about the process.
|
||||
This is called the `native_exit_code`.
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ The `.running()` function can be used to detect if the process is still active.
|
||||
|
||||
[section:signal Signalling the subprocess]
|
||||
|
||||
The parent process can signal the subprocess demanding certain actions.
|
||||
The parent process can signal the subprocess demaning certain actions.
|
||||
|
||||
`.terminate` will cause the subprocess to exit immediately (`SIGKILL` on posix).
|
||||
This is the only reliable & portable way to end a subprocess.
|
||||
@@ -76,7 +76,7 @@ interpret as a signal to shutdown.
|
||||
|
||||
[section:execute Execute functions]
|
||||
|
||||
Process v2 provides `execute` and `async_execute` functions that can be used for managed executions.
|
||||
Process v2 provides `execute` and `async_execute` functons that can be used for managed executions.
|
||||
|
||||
```
|
||||
assert(execute(process("/bin/ls", {}) == 0));
|
||||
@@ -90,7 +90,7 @@ The async version supports cancellation and will forward cancellation types as f
|
||||
|
||||
```
|
||||
asio::io_context ctx;
|
||||
asio::steady_timer timeout{ctx, std::chrono::seconds(10)};
|
||||
asio::steady_timer timout{ctx, std::chrono::seconds(10)};
|
||||
|
||||
asio::cancellation_signal sig;
|
||||
async_execute(process("/usr/bin/g++", {"hello_world.cpp"}),
|
||||
@@ -114,6 +114,7 @@ The async version supports cancellation and will forward cancellation types as f
|
||||
if (!ec)
|
||||
sig.emit(asio::cancellation_type::terminal);
|
||||
});
|
||||
);
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
@@ -12,7 +12,7 @@ automatically connected and the other side will get assigned to the child proces
|
||||
|
||||
```
|
||||
asio::io_context ctx;
|
||||
asio::readable_pipe rp{ctx};
|
||||
asio::readable_pipe rp;
|
||||
|
||||
process proc(ctx, "/usr/bin/g++", {"--version"}, process_stdio{{ /* in to default */}, rp, { /* err to default */ }});
|
||||
std::string output;
|
||||
@@ -23,7 +23,7 @@ automatically connected and the other side will get assigned to the child proces
|
||||
proc.wait();
|
||||
```
|
||||
|
||||
readable pipes can be assigned to `out` an `err`, while writable_pipes can be assigned to `in`.
|
||||
readable pipes can be assigned to `out` an `err``, while writable_pipes can be assigned to `in`.
|
||||
|
||||
[endsect]
|
||||
|
||||
@@ -86,4 +86,4 @@ It starts a process and connects pipes for stdin and stdout, so that the popen o
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
[endsect]
|
||||
42
doc/windows_pseudocode.xml
Normal file
42
doc/windows_pseudocode.xml
Normal file
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" standalone="yes"?>
|
||||
<programlisting>
|
||||
for (auto & s : seq)
|
||||
s.<methodname alt="boost::process::extend::handler::on_setup">on_setup</methodname>(*this);
|
||||
|
||||
if (<methodname alt="boost::process::extend::windows_executor::error">error</methodname>())
|
||||
{
|
||||
for (auto & s : seq)
|
||||
s.<methodname alt="boost::process::extend::handler::on_error">on_error</methodname>(*this, <methodname alt="boost::process::extend::windows_executor::error">error</methodname>());
|
||||
return <classname alt="boost::process::child">child</classname>();
|
||||
}
|
||||
int err_code = <ulink url="https://msdn.microsoft.com/en-us/library/windows/desktop/ms682425.aspx">CreateProcess</ulink>(
|
||||
exe,
|
||||
cmd_line,
|
||||
proc_attrs,
|
||||
thread_attrs,
|
||||
creation_flags,
|
||||
env,
|
||||
work_dir,
|
||||
startup_info,
|
||||
proc_info);
|
||||
|
||||
<classname alt="boost::process::child">child</classname> c(proc_info, exit_code);
|
||||
|
||||
if (<methodname alt="boost::process::extend::windows_executor::error">error</methodname>())
|
||||
for (auto & s : seq)
|
||||
s.<methodname alt="boost::process::extend::handler::on_error">on_error</methodname>(*this, <methodname alt="boost::process::extend::windows_executor::error">error</methodname>());
|
||||
else
|
||||
for (auto & s : seq)
|
||||
s.<methodname alt="boost::process::extend::handler::on_error">on_success</methodname>(*this);
|
||||
|
||||
//now we check again, because a on_success handler might've errored.
|
||||
if (<methodname alt="boost::process::extend::windows_executor::error">error</methodname>())
|
||||
{
|
||||
for (auto & s : seq)
|
||||
s.<methodname alt="boost::process::extend::handler::on_error">on_error</methodname>(*this, <methodname alt="boost::process::extend::windows_executor::error">error</methodname>());
|
||||
return <classname alt="boost::process::child">child</classname>();
|
||||
}
|
||||
else
|
||||
return c;
|
||||
|
||||
</programlisting>
|
||||
@@ -22,7 +22,7 @@ int main()
|
||||
bp::std_in < bp::null //null in
|
||||
);
|
||||
|
||||
boost::process::v1::filesystem::path p = "input.txt";
|
||||
boost::process::filesystem::path p = "input.txt";
|
||||
|
||||
bp::system(
|
||||
"test.exe",
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/process.hpp>
|
||||
#include <boost/process/v1/posix.hpp>
|
||||
#include <boost/process/v1/extend.hpp>
|
||||
#include <boost/process/posix.hpp>
|
||||
#include <boost/process/extend.hpp>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <unistd.h>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/process.hpp>
|
||||
#include <boost/process/v1/filesystem.hpp>
|
||||
#include <boost/process/filesystem.hpp>
|
||||
|
||||
namespace bp = boost::process;
|
||||
|
||||
@@ -19,9 +19,9 @@ int main()
|
||||
bp::start_dir="../foo"
|
||||
);
|
||||
|
||||
boost::process::v1::filesystem::path exe = "test.exe";
|
||||
boost::process::filesystem::path exe = "test.exe";
|
||||
bp::system(
|
||||
boost::process::v1::filesystem::absolute(exe),
|
||||
boost::process::filesystem::absolute(exe),
|
||||
bp::start_dir="../foo"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2022 Klemens Morgenstern
|
||||
// Copyright (c) 2022Klemens Morgernstern
|
||||
//
|
||||
// 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)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2022Klemens Morgenstern
|
||||
// Copyright (c) 2022Klemens Morgernstern
|
||||
//
|
||||
// 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)
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/process.hpp>
|
||||
#include <boost/process/v1/extend.hpp>
|
||||
#include <boost/process/v1/windows.hpp>
|
||||
#include <boost/process/extend.hpp>
|
||||
#include <boost/process/windows.hpp>
|
||||
#include <iostream>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
@@ -19,16 +19,24 @@
|
||||
* boost.process header files.
|
||||
*/
|
||||
|
||||
#if !defined(BOOST_PROCESS_VERSION)
|
||||
#define BOOST_PROCESS_VERSION 1
|
||||
#endif
|
||||
|
||||
#if BOOST_PROCESS_VERSION == 1
|
||||
#include <boost/process/v1.hpp>
|
||||
#elif BOOST_PROCESS_VERSION == 2
|
||||
#include <boost/process/v2.hpp>
|
||||
#else
|
||||
#error "Unknown boost process version"
|
||||
#endif
|
||||
#include <boost/process/args.hpp>
|
||||
#include <boost/process/async.hpp>
|
||||
#include <boost/process/async_system.hpp>
|
||||
#include <boost/process/group.hpp>
|
||||
#include <boost/process/child.hpp>
|
||||
#include <boost/process/cmd.hpp>
|
||||
#include <boost/process/env.hpp>
|
||||
#include <boost/process/environment.hpp>
|
||||
#include <boost/process/error.hpp>
|
||||
#include <boost/process/exe.hpp>
|
||||
#include <boost/process/group.hpp>
|
||||
#include <boost/process/handles.hpp>
|
||||
#include <boost/process/io.hpp>
|
||||
#include <boost/process/pipe.hpp>
|
||||
#include <boost/process/shell.hpp>
|
||||
#include <boost/process/search_path.hpp>
|
||||
#include <boost/process/spawn.hpp>
|
||||
#include <boost/process/system.hpp>
|
||||
#include <boost/process/start_dir.hpp>
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,9 +1,279 @@
|
||||
// Copyright (c) 2024 Klemens D. Morgenstern
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
||||
// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
|
||||
// Copyright (c) 2009 Boris Schaeling
|
||||
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
|
||||
// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling
|
||||
// Copyright (c) 2016 Klemens D. Morgenstern
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_PROCESS_ARGS_HPP
|
||||
#define BOOST_PROCESS_ARGS_HPP
|
||||
|
||||
#include <boost/config/header_deprecated.hpp>
|
||||
BOOST_HEADER_DEPRECATED("<boost/process/v1/args.hpp>")
|
||||
#include <boost/process/v1/args.hpp>
|
||||
/** \file boost/process/args.hpp
|
||||
*
|
||||
* This header provides the \xmlonly <globalname alt="boost::process::args">args</globalname>\endxmlonly property. It also provides the
|
||||
* alternative name \xmlonly <globalname alt="boost::process::argv">argv</globalname>\endxmlonly .
|
||||
*
|
||||
*
|
||||
\xmlonly
|
||||
<programlisting>
|
||||
namespace boost {
|
||||
namespace process {
|
||||
<emphasis>unspecified</emphasis> <globalname alt="boost::process::args">args</globalname>;
|
||||
<emphasis>unspecified</emphasis> <globalname alt="boost::process::argv">argv</globalname>;
|
||||
}
|
||||
}
|
||||
</programlisting>
|
||||
\endxmlonly
|
||||
*/
|
||||
|
||||
|
||||
#include <boost/process/detail/basic_cmd.hpp>
|
||||
#include <iterator>
|
||||
|
||||
namespace boost { namespace process { namespace detail {
|
||||
|
||||
struct args_
|
||||
{
|
||||
template<typename T>
|
||||
using remove_reference_t = typename std::remove_reference<T>::type;
|
||||
template<typename T>
|
||||
using value_type = typename remove_reference_t<T>::value_type;
|
||||
|
||||
template<typename T>
|
||||
using vvalue_type = value_type<value_type<T>>;
|
||||
|
||||
template <class Range>
|
||||
arg_setter_<vvalue_type<Range>, true> operator()(Range &&range) const
|
||||
{
|
||||
return arg_setter_<vvalue_type<Range>, true>(std::forward<Range>(range));
|
||||
}
|
||||
template <class Range>
|
||||
arg_setter_<vvalue_type<Range>, true> operator+=(Range &&range) const
|
||||
{
|
||||
return arg_setter_<vvalue_type<Range>, true>(std::forward<Range>(range));
|
||||
}
|
||||
template <class Range>
|
||||
arg_setter_<vvalue_type<Range>, false> operator= (Range &&range) const
|
||||
{
|
||||
return arg_setter_<vvalue_type<Range>, false>(std::forward<Range>(range));
|
||||
}
|
||||
template<typename Char>
|
||||
arg_setter_<Char, true> operator()(std::basic_string<Char> && str) const
|
||||
{
|
||||
return arg_setter_<Char, true> (str);
|
||||
}
|
||||
template<typename Char>
|
||||
arg_setter_<Char, true> operator+=(std::basic_string<Char> && str) const
|
||||
{
|
||||
return arg_setter_<Char, true> (str);
|
||||
}
|
||||
template<typename Char>
|
||||
arg_setter_<Char, false> operator= (std::basic_string<Char> && str) const
|
||||
{
|
||||
return arg_setter_<Char, false>(str);
|
||||
}
|
||||
template<typename Char>
|
||||
arg_setter_<Char, true> operator()(const std::basic_string<Char> & str) const
|
||||
{
|
||||
return arg_setter_<Char, true> (str);
|
||||
}
|
||||
template<typename Char>
|
||||
arg_setter_<Char, true> operator+=(const std::basic_string<Char> & str) const
|
||||
{
|
||||
return arg_setter_<Char, true> (str);
|
||||
}
|
||||
template<typename Char>
|
||||
arg_setter_<Char, false> operator= (const std::basic_string<Char> & str) const
|
||||
{
|
||||
return arg_setter_<Char, false>(str);
|
||||
}
|
||||
template<typename Char>
|
||||
arg_setter_<Char, true> operator()(std::basic_string<Char> & str) const
|
||||
{
|
||||
return arg_setter_<Char, true> (str);
|
||||
}
|
||||
template<typename Char>
|
||||
arg_setter_<Char, true> operator+=(std::basic_string<Char> & str) const
|
||||
{
|
||||
return arg_setter_<Char, true> (str);
|
||||
}
|
||||
template<typename Char>
|
||||
arg_setter_<Char, false> operator= (std::basic_string<Char> & str) const
|
||||
{
|
||||
return arg_setter_<Char, false>(str);
|
||||
}
|
||||
template<typename Char>
|
||||
arg_setter_<Char, true> operator()(const Char* str) const
|
||||
{
|
||||
return arg_setter_<Char, true> (str);
|
||||
}
|
||||
template<typename Char>
|
||||
arg_setter_<Char, true> operator+=(const Char* str) const
|
||||
{
|
||||
return arg_setter_<Char, true> (str);
|
||||
}
|
||||
template<typename Char>
|
||||
arg_setter_<Char, false> operator= (const Char* str) const
|
||||
{
|
||||
return arg_setter_<Char, false>(str);
|
||||
}
|
||||
// template<typename Char, std::size_t Size>
|
||||
// arg_setter_<Char, true> operator()(const Char (&str) [Size]) const
|
||||
// {
|
||||
// return arg_setter_<Char, true> (str);
|
||||
// }
|
||||
// template<typename Char, std::size_t Size>
|
||||
// arg_setter_<Char, true> operator+=(const Char (&str) [Size]) const
|
||||
// {
|
||||
// return arg_setter_<Char, true> (str);
|
||||
// }
|
||||
// template<typename Char, std::size_t Size>
|
||||
// arg_setter_<Char, false> operator= (const Char (&str) [Size]) const
|
||||
// {
|
||||
// return arg_setter_<Char, false>(str);
|
||||
// }
|
||||
|
||||
arg_setter_<char, true> operator()(std::initializer_list<const char*> &&range) const
|
||||
{
|
||||
return arg_setter_<char, true>(range.begin(), range.end());
|
||||
}
|
||||
arg_setter_<char, true> operator+=(std::initializer_list<const char*> &&range) const
|
||||
{
|
||||
return arg_setter_<char, true>(range.begin(), range.end());
|
||||
}
|
||||
arg_setter_<char, false> operator= (std::initializer_list<const char*> &&range) const
|
||||
{
|
||||
return arg_setter_<char, false>(range.begin(), range.end());
|
||||
}
|
||||
arg_setter_<char, true> operator()(std::initializer_list<std::string> &&range) const
|
||||
{
|
||||
return arg_setter_<char, true>(range.begin(), range.end());
|
||||
}
|
||||
arg_setter_<char, true> operator+=(std::initializer_list<std::string> &&range) const
|
||||
{
|
||||
return arg_setter_<char, true>(range.begin(), range.end());
|
||||
}
|
||||
arg_setter_<char, false> operator= (std::initializer_list<std::string> &&range) const
|
||||
{
|
||||
return arg_setter_<char, false>(range.begin(), range.end());
|
||||
}
|
||||
|
||||
arg_setter_<wchar_t, true> operator()(std::initializer_list<const wchar_t*> &&range) const
|
||||
{
|
||||
return arg_setter_<wchar_t, true>(range.begin(), range.end());
|
||||
}
|
||||
arg_setter_<wchar_t, true> operator+=(std::initializer_list<const wchar_t*> &&range) const
|
||||
{
|
||||
return arg_setter_<wchar_t, true>(range.begin(), range.end());
|
||||
}
|
||||
arg_setter_<wchar_t, false> operator= (std::initializer_list<const wchar_t*> &&range) const
|
||||
{
|
||||
return arg_setter_<wchar_t, false>(range.begin(), range.end());
|
||||
}
|
||||
arg_setter_<wchar_t, true> operator()(std::initializer_list<std::wstring> &&range) const
|
||||
{
|
||||
return arg_setter_<wchar_t, true>(range.begin(), range.end());
|
||||
}
|
||||
arg_setter_<wchar_t, true> operator+=(std::initializer_list<std::wstring> &&range) const
|
||||
{
|
||||
return arg_setter_<wchar_t, true>(range.begin(), range.end());
|
||||
}
|
||||
arg_setter_<wchar_t, false> operator= (std::initializer_list<std::wstring> &&range) const
|
||||
{
|
||||
return arg_setter_<wchar_t, false>(range.begin(), range.end());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
/**
|
||||
|
||||
The `args` property allows to explicitly set arguments for the execution. The
|
||||
name of the executable will always be the first element in the arg-vector.
|
||||
|
||||
\section args_details Details
|
||||
|
||||
\subsection args_operations Operations
|
||||
|
||||
\subsubsection args_set_var Setting values
|
||||
|
||||
To set a the argument vector the following syntax can be used.
|
||||
|
||||
\code{.cpp}
|
||||
args = value;
|
||||
args(value);
|
||||
\endcode
|
||||
|
||||
`std::initializer_list` is among the allowed types, so the following syntax is also possible.
|
||||
|
||||
\code{.cpp}
|
||||
args = {value1, value2};
|
||||
args({value1, value2});
|
||||
\endcode
|
||||
|
||||
Below the possible types for `value` are listed, with `char_type` being either `char` or `wchar_t`.
|
||||
|
||||
\paragraph args_set_var_value value
|
||||
|
||||
- `std::basic_string<char_type>`
|
||||
- `const char_type * `
|
||||
- `std::initializer_list<const char_type *>`
|
||||
- `std::vector<std::basic_string<char_type>>`
|
||||
|
||||
Additionally any range of `std::basic_string<char_type>` can be passed.
|
||||
|
||||
\subsubsection args_append_var Appending values
|
||||
|
||||
To append a the argument vector the following syntax can be used.
|
||||
|
||||
\code{.cpp}
|
||||
args += value;
|
||||
\endcode
|
||||
|
||||
`std::initializer_list` is among the allowed types, so the following syntax is also possible.
|
||||
|
||||
\code{.cpp}
|
||||
args += {value1, value2};
|
||||
\endcode
|
||||
|
||||
Below the possible types for `value` are listed, with `char_type` being either `char` or `wchar_t`.
|
||||
|
||||
\paragraph args_append_var_value value
|
||||
|
||||
- `std::basic_string<char_type>`
|
||||
- `const char_type * `
|
||||
- `std::initializer_list<const char_type *>`
|
||||
- `std::vector<std::basic_string<char_type>>`
|
||||
|
||||
Additionally any range of `std::basic_string<char_type>` can be passed.
|
||||
|
||||
|
||||
\subsection args_example Example
|
||||
|
||||
The overload form is used when more than one string is passed, from the second one forward.
|
||||
I.e. the following expressions have the same results:
|
||||
|
||||
\code{.cpp}
|
||||
spawn("gcc", "--version");
|
||||
spawn("gcc", args ="--version");
|
||||
spawn("gcc", args+="--version");
|
||||
spawn("gcc", args ={"--version"});
|
||||
spawn("gcc", args+={"--version"});
|
||||
\endcode
|
||||
|
||||
\note A string will be parsed and set in quotes if it has none and contains spaces.
|
||||
|
||||
|
||||
*/
|
||||
constexpr boost::process::detail::args_ args{};
|
||||
|
||||
///Alias for \xmlonly <globalname alt="boost::process::args">args</globalname> \endxmlonly .
|
||||
constexpr boost::process::detail::args_ argv{};
|
||||
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,9 +1,132 @@
|
||||
// Copyright (c) 2024 Klemens D. Morgenstern
|
||||
// Copyright (c) 2016 Klemens D. Morgenstern
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
/** \file boost/process/async.hpp
|
||||
|
||||
#include <boost/config/header_deprecated.hpp>
|
||||
BOOST_HEADER_DEPRECATED("<boost/process/v1/async.hpp>")
|
||||
#include <boost/process/v1/async.hpp>
|
||||
The header which provides the basic asynchrounous features.
|
||||
It provides the on_exit property, which allows callbacks when the process exits.
|
||||
It also implements the necessary traits for passing an boost::asio::io_context,
|
||||
which is needed for asynchronous communication.
|
||||
|
||||
It also pulls the [boost::asio::buffer](http://www.boost.org/doc/libs/release/doc/html/boost_asio/reference/buffer.html)
|
||||
into the boost::process namespace for convenience.
|
||||
|
||||
\xmlonly
|
||||
<programlisting>
|
||||
namespace boost {
|
||||
namespace process {
|
||||
<emphasis>unspecified</emphasis> <ulink url="http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/buffer.html">buffer</ulink>;
|
||||
<emphasis>unspecified</emphasis> <globalname alt="boost::process::on_exit">on_exit</globalname>;
|
||||
}
|
||||
}
|
||||
</programlisting>
|
||||
|
||||
\endxmlonly
|
||||
*/
|
||||
|
||||
#ifndef BOOST_PROCESS_ASYNC_HPP_
|
||||
#define BOOST_PROCESS_ASYNC_HPP_
|
||||
|
||||
#include <boost/process/detail/traits.hpp>
|
||||
#include <boost/process/detail/on_exit.hpp>
|
||||
|
||||
#include <boost/asio/io_context.hpp>
|
||||
#include <boost/asio/streambuf.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <type_traits>
|
||||
#include <boost/fusion/iterator/deref.hpp>
|
||||
|
||||
#if defined(BOOST_POSIX_API)
|
||||
#include <boost/process/detail/posix/io_context_ref.hpp>
|
||||
#include <boost/process/detail/posix/async_in.hpp>
|
||||
#include <boost/process/detail/posix/async_out.hpp>
|
||||
#include <boost/process/detail/posix/on_exit.hpp>
|
||||
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
#include <boost/process/detail/windows/io_context_ref.hpp>
|
||||
#include <boost/process/detail/windows/async_in.hpp>
|
||||
#include <boost/process/detail/windows/async_out.hpp>
|
||||
#include <boost/process/detail/windows/on_exit.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost { namespace process { namespace detail {
|
||||
|
||||
struct async_tag;
|
||||
|
||||
template<typename T>
|
||||
struct is_io_context : std::false_type {};
|
||||
template<>
|
||||
struct is_io_context<api::io_context_ref> : std::true_type {};
|
||||
|
||||
template<typename Tuple>
|
||||
inline asio::io_context& get_io_context(const Tuple & tup)
|
||||
{
|
||||
auto& ref = *boost::fusion::find_if<is_io_context<boost::mpl::_>>(tup);
|
||||
return ref.get();
|
||||
}
|
||||
|
||||
struct async_builder
|
||||
{
|
||||
boost::asio::io_context * ios;
|
||||
|
||||
void operator()(boost::asio::io_context & ios_) {this->ios = &ios_;};
|
||||
|
||||
typedef api::io_context_ref result_type;
|
||||
api::io_context_ref get_initializer() {return api::io_context_ref (*ios);};
|
||||
};
|
||||
|
||||
|
||||
template<>
|
||||
struct initializer_builder<async_tag>
|
||||
{
|
||||
typedef async_builder type;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
using ::boost::asio::buffer;
|
||||
|
||||
|
||||
#if defined(BOOST_PROCESS_DOXYGEN)
|
||||
/** When an io_context is passed, the on_exit property can be used, to be notified
|
||||
when the child process exits.
|
||||
|
||||
|
||||
The following syntax is valid
|
||||
|
||||
\code{.cpp}
|
||||
on_exit=function;
|
||||
on_exit(function);
|
||||
\endcode
|
||||
|
||||
with `function` being a callable object with the signature `(int, const std::error_code&)` or an
|
||||
`std::future<int>`.
|
||||
|
||||
\par Example
|
||||
|
||||
\code{.cpp}
|
||||
io_context ios;
|
||||
|
||||
child c("ls", ios, on_exit=[](int exit, const std::error_code& ec_in){});
|
||||
|
||||
std::future<int> exit_code;
|
||||
chlid c2("ls", ios, on_exit=exit_code);
|
||||
|
||||
\endcode
|
||||
|
||||
\note The handler is not invoked when the launch fails.
|
||||
\warning When used \ref ignore_error it might get invoked on error.
|
||||
\warning `on_exit` uses `boost::asio::signal_set` to listen for `SIGCHLD` on posix, and so has the
|
||||
same restrictions as that class (do not register a handler for `SIGCHLD` except by using
|
||||
`boost::asio::signal_set`).
|
||||
*/
|
||||
constexpr static ::boost::process::detail::on_exit_ on_exit{};
|
||||
#endif
|
||||
|
||||
}}
|
||||
|
||||
|
||||
|
||||
#endif /* INCLUDE_BOOST_PROCESS_DETAIL_ASYNC_HPP_ */
|
||||
|
||||
@@ -1,9 +1,217 @@
|
||||
// Copyright (c) 2024 Klemens D. Morgenstern
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
||||
// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
|
||||
// Copyright (c) 2009 Boris Schaeling
|
||||
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
|
||||
// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling
|
||||
//
|
||||
// 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)
|
||||
|
||||
|
||||
#include <boost/config/header_deprecated.hpp>
|
||||
BOOST_HEADER_DEPRECATED("<boost/process/v1/async_pipe.hpp>")
|
||||
#include <boost/process/v1/async_pipe.hpp>
|
||||
#ifndef BOOST_PROCESS_ASYNC_PIPE_HPP
|
||||
#define BOOST_PROCESS_ASYNC_PIPE_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/process/detail/config.hpp>
|
||||
|
||||
#if defined(BOOST_POSIX_API)
|
||||
#include <boost/process/detail/posix/async_pipe.hpp>
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
#include <boost/process/detail/windows/async_pipe.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost { namespace process {
|
||||
|
||||
|
||||
#if defined(BOOST_PROCESS_DOXYGEN)
|
||||
|
||||
|
||||
/** Class implementing an asnychronous I/O-Object for use with boost.asio.
|
||||
* It is based on the corresponding I/O Object, that is either boost::asio::windows::stream_handle or
|
||||
* boost::asio::posix::stream_descriptor.
|
||||
*
|
||||
* It can be used directly with boost::asio::async_read or async_write.
|
||||
*
|
||||
* \note The object is copyable, but that does invoke a handle duplicate.
|
||||
*/
|
||||
class async_pipe
|
||||
{
|
||||
public:
|
||||
/** Typedef for the native handle representation.
|
||||
* \note This is the handle on the system, not the boost.asio class.
|
||||
*
|
||||
*/
|
||||
typedef platform_specific native_handle_type;
|
||||
/** Typedef for the handle representation of boost.asio.
|
||||
*
|
||||
*/
|
||||
typedef platform_specific handle_type;
|
||||
|
||||
typedef typename handle_type::executor_type executor_type;
|
||||
|
||||
/** Construct a new async_pipe, does automatically open the pipe.
|
||||
* Initializes source and sink with the same io_context.
|
||||
* @note Windows creates a named pipe here, where the name is automatically generated.
|
||||
*/
|
||||
inline async_pipe(boost::asio::io_context & ios);
|
||||
|
||||
/** Construct a new async_pipe, does automatically open the pipe.
|
||||
* @note Windows creates a named pipe here, where the name is automatically generated.
|
||||
*/
|
||||
inline async_pipe(boost::asio::io_context & ios_source,
|
||||
boost::asio::io_context & ios_sink);
|
||||
|
||||
/** Construct a new async_pipe, does automatically open.
|
||||
* Initializes source and sink with the same io_context.
|
||||
*
|
||||
* @note Windows restricts possible names.
|
||||
*/
|
||||
inline async_pipe(boost::asio::io_context & ios, const std::string & name);
|
||||
|
||||
|
||||
/** Construct a new async_pipe, does automatically open.
|
||||
*
|
||||
* @note Windows restricts possible names.
|
||||
*/
|
||||
inline async_pipe(boost::asio::io_context & ios_source,
|
||||
boost::asio::io_context & ios_sink, const std::string & name);
|
||||
|
||||
/** Copy-Constructor of the async pipe.
|
||||
* @note Windows requires a named pipe for this, if a the wrong type is used an exception is thrown.
|
||||
*
|
||||
*/
|
||||
async_pipe(const async_pipe& lhs);
|
||||
|
||||
/** Move-Constructor of the async pipe.
|
||||
*/
|
||||
async_pipe(async_pipe&& lhs);
|
||||
|
||||
/** Construct the async-pipe from a pipe.
|
||||
* @note Windows requires a named pipe for this, if a the wrong type is used an exception is thrown.
|
||||
*
|
||||
*/
|
||||
template<class CharT, class Traits = std::char_traits<CharT>>
|
||||
explicit async_pipe(boost::asio::io_context & ios, const basic_pipe<CharT, Traits> & p);
|
||||
|
||||
/** Construct the async-pipe from a pipe, with two different io_context objects.
|
||||
* @note Windows requires a named pipe for this, if a the wrong type is used an exception is thrown.
|
||||
*
|
||||
*/
|
||||
template<class CharT, class Traits = std::char_traits<CharT>>
|
||||
explicit async_pipe(boost::asio::io_context & ios_source,
|
||||
boost::asio::io_context & ios_sink,
|
||||
const basic_pipe<CharT, Traits> & p);
|
||||
|
||||
|
||||
/** Assign a basic_pipe.
|
||||
* @note Windows requires a named pipe for this, if a the wrong type is used an exception is thrown.
|
||||
*
|
||||
*/
|
||||
template<class CharT, class Traits = std::char_traits<CharT>>
|
||||
inline async_pipe& operator=(const basic_pipe<CharT, Traits>& p);
|
||||
|
||||
/** Copy Assign a pipe.
|
||||
* @note Duplicates the handles.
|
||||
*/
|
||||
async_pipe& operator=(const async_pipe& lhs);
|
||||
/** Move assign a pipe */
|
||||
async_pipe& operator=(async_pipe&& lhs);
|
||||
|
||||
/** Destructor. Closes the pipe handles. */
|
||||
~async_pipe();
|
||||
|
||||
/** Explicit cast to basic_pipe. */
|
||||
template<class CharT, class Traits = std::char_traits<CharT>>
|
||||
inline explicit operator basic_pipe<CharT, Traits>() const;
|
||||
|
||||
/** Cancel the current asynchronous operations. */
|
||||
void cancel();
|
||||
/** Close the pipe handles. */
|
||||
void close();
|
||||
/** Close the pipe handles. While passing an error_code
|
||||
*
|
||||
*/
|
||||
void close(std::error_code & ec);
|
||||
|
||||
/** Check if the pipes are open. */
|
||||
bool is_open() const;
|
||||
|
||||
/** Async close, i.e. close after current operation is completed.
|
||||
*
|
||||
* \note There is no guarantee that this will indeed read the entire pipe-buffer
|
||||
*/
|
||||
void async_close();
|
||||
|
||||
/** Read some data from the handle.
|
||||
|
||||
* See the boost.asio documentation for more details.
|
||||
*/
|
||||
template<typename MutableBufferSequence>
|
||||
std::size_t read_some(const MutableBufferSequence & buffers);
|
||||
|
||||
/** Write some data to the handle.
|
||||
|
||||
* See the boost.asio documentation for more details.
|
||||
*/
|
||||
template<typename MutableBufferSequence>
|
||||
std::size_t write_some(const MutableBufferSequence & buffers);
|
||||
|
||||
/** Get the native handle of the source. */
|
||||
native_handle native_source() const {return const_cast<boost::asio::windows::stream_handle&>(_source).native();}
|
||||
/** Get the native handle of the sink. */
|
||||
native_handle native_sink () const {return const_cast<boost::asio::windows::stream_handle&>(_sink ).native();}
|
||||
|
||||
/** Start an asynchronous read.
|
||||
*
|
||||
* See the [boost.asio documentation](http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/AsyncReadStream.html) for more details.
|
||||
*/
|
||||
template<typename MutableBufferSequence,
|
||||
typename ReadHandler>
|
||||
detail::dummy async_read_some(
|
||||
const MutableBufferSequence & buffers,
|
||||
ReadHandler &&handler);
|
||||
|
||||
/** Start an asynchronous write.
|
||||
|
||||
* See the [boost.asio documentation](http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/AsyncWriteStream.html) for more details.
|
||||
*/
|
||||
template<typename ConstBufferSequence,
|
||||
typename WriteHandler>
|
||||
detail::dummy async_write_some(
|
||||
const ConstBufferSequence & buffers,
|
||||
WriteHandler && handler);
|
||||
|
||||
///Get the asio handle of the pipe sink.
|
||||
const handle_type & sink () const &;
|
||||
///Get the asio handle of the pipe source.
|
||||
const handle_type & source() const &;
|
||||
|
||||
///Get the asio handle of the pipe sink. Qualified as rvalue
|
||||
handle_type && sink () &&;
|
||||
///Get the asio handle of the pipe source. Qualified as rvalue
|
||||
handle_type && source() &&;
|
||||
|
||||
/// Move the source out of this class and change the io_context. Qualified as rvalue. \attention Will always move.
|
||||
handle_type source(::boost::asio::io_context& ios) &&;
|
||||
/// Move the sink out of this class and change the io_context. Qualified as rvalue. \attention Will always move
|
||||
handle_type sink (::boost::asio::io_context& ios) &&;
|
||||
|
||||
/// Copy the source out of this class and change the io_context. \attention Will always copy.
|
||||
handle_type source(::boost::asio::io_context& ios) const &;
|
||||
/// Copy the sink out of this class and change the io_context. \attention Will always copy
|
||||
handle_type sink (::boost::asio::io_context& ios) const &;
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
#else
|
||||
using ::boost::process::detail::api::async_pipe;
|
||||
#endif
|
||||
|
||||
|
||||
}}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,9 +1,151 @@
|
||||
// Copyright (c) 2024 Klemens D. Morgenstern
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
||||
// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
|
||||
// Copyright (c) 2009 Boris Schaeling
|
||||
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
|
||||
// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling
|
||||
// Copyright (c) 2016 Klemens D. Morgenstern
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
/**
|
||||
* \file boost/process/async_system.hpp
|
||||
*
|
||||
* Defines the asynchrounous version of the system function.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_PROCESS_ASYNC_SYSTEM_HPP
|
||||
#define BOOST_PROCESS_ASYNC_SYSTEM_HPP
|
||||
|
||||
#include <boost/process/detail/config.hpp>
|
||||
#include <boost/process/async.hpp>
|
||||
#include <boost/process/child.hpp>
|
||||
#include <boost/process/detail/async_handler.hpp>
|
||||
#include <boost/process/detail/execute_impl.hpp>
|
||||
#include <type_traits>
|
||||
#include <memory>
|
||||
#include <boost/asio/async_result.hpp>
|
||||
#include <boost/asio/post.hpp>
|
||||
#include <boost/system/error_code.hpp>
|
||||
#include <tuple>
|
||||
|
||||
#if defined(BOOST_POSIX_API)
|
||||
#include <boost/process/posix.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace process {
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<typename Handler>
|
||||
struct async_system_handler : ::boost::process::detail::api::async_handler
|
||||
{
|
||||
boost::asio::io_context & ios;
|
||||
Handler handler;
|
||||
|
||||
#if defined(BOOST_POSIX_API)
|
||||
bool errored = false;
|
||||
#endif
|
||||
|
||||
template<typename ExitHandler_>
|
||||
async_system_handler(
|
||||
boost::asio::io_context & ios,
|
||||
ExitHandler_ && exit_handler) : ios(ios), handler(std::forward<ExitHandler_>(exit_handler))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
template<typename Exec>
|
||||
void on_error(Exec&, const std::error_code & ec)
|
||||
{
|
||||
#if defined(BOOST_POSIX_API)
|
||||
errored = true;
|
||||
#endif
|
||||
auto h = std::make_shared<Handler>(std::move(handler));
|
||||
boost::asio::post(
|
||||
ios.get_executor(),
|
||||
[h, ec]() mutable
|
||||
{
|
||||
(*h)(boost::system::error_code(ec.value(), boost::system::system_category()), -1);
|
||||
});
|
||||
}
|
||||
|
||||
template<typename Executor>
|
||||
std::function<void(int, const std::error_code&)> on_exit_handler(Executor&)
|
||||
{
|
||||
#if defined(BOOST_POSIX_API)
|
||||
if (errored)
|
||||
return [](int , const std::error_code &){};
|
||||
#endif
|
||||
auto h = std::make_shared<Handler>(std::move(handler));
|
||||
return [h](int exit_code, const std::error_code & ec) mutable
|
||||
{
|
||||
(*h)(boost::system::error_code(ec.value(), boost::system::system_category()), exit_code);
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename ExitHandler>
|
||||
struct is_error_handler<async_system_handler<ExitHandler>> : std::true_type {};
|
||||
|
||||
}
|
||||
|
||||
/** This function provides an asynchronous interface to process launching.
|
||||
|
||||
It uses the same properties and parameters as the other launching function,
|
||||
but is similar to the asynchronous functions in [boost.asio](http://www.boost.org/doc/libs/release/doc/html/boost_asio.html)
|
||||
|
||||
It uses [asio::async_result](http://www.boost.org/doc/libs/release/doc/html/boost_asio/reference/async_result.html) to determine
|
||||
the return value (from the second parameter, `exit_handler`).
|
||||
|
||||
\param ios A reference to an [io_context](http://www.boost.org/doc/libs/release/doc/html/boost_asio/reference.html)
|
||||
\param exit_handler The exit-handler for the signature `void(boost::system::error_code, int)`
|
||||
|
||||
\note This function does not allow custom error handling, since those are done through the `exit_handler`.
|
||||
|
||||
*/
|
||||
#if defined(BOOST_PROCESS_DOXYGEN)
|
||||
template<typename ExitHandler, typename ...Args>
|
||||
inline boost::process::detail::dummy
|
||||
async_system(boost::asio::io_context & ios, ExitHandler && exit_handler, Args && ...args);
|
||||
#endif
|
||||
|
||||
namespace detail
|
||||
{
|
||||
struct async_system_init_op
|
||||
{
|
||||
|
||||
template<typename Handler, typename ... Args>
|
||||
void operator()(Handler && handler, asio::io_context & ios, Args && ... args)
|
||||
{
|
||||
detail::async_system_handler<typename std::decay<Handler>::type> async_h{ios, std::forward<Handler>(handler)};
|
||||
child(ios, std::forward<Args>(args)..., async_h ).detach();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
template<typename ExitHandler, typename ...Args>
|
||||
inline BOOST_ASIO_INITFN_RESULT_TYPE(ExitHandler, void (boost::system::error_code, int))
|
||||
async_system(boost::asio::io_context & ios, ExitHandler && exit_handler, Args && ...args)
|
||||
{
|
||||
|
||||
typedef typename ::boost::process::detail::has_error_handler<boost::fusion::tuple<Args...>>::type
|
||||
has_err_handling;
|
||||
|
||||
static_assert(!has_err_handling::value, "async_system cannot have custom error handling");
|
||||
|
||||
return boost::asio::async_initiate<ExitHandler, void (boost::system::error_code, int)>(
|
||||
detail::async_system_init_op{}, exit_handler, ios, std::forward<Args>(args)...
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}}
|
||||
#endif
|
||||
|
||||
#include <boost/config/header_deprecated.hpp>
|
||||
BOOST_HEADER_DEPRECATED("<boost/process/v1/async_system.hpp>")
|
||||
#include <boost/process/v1/async_system.hpp>
|
||||
|
||||
@@ -1,9 +1,154 @@
|
||||
// Copyright (c) 2024 Klemens D. Morgenstern
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
||||
// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
|
||||
// Copyright (c) 2009 Boris Schaeling
|
||||
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
|
||||
// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling
|
||||
// Copyright (c) 2016 Klemens D. Morgenstern
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
/**
|
||||
* \file boost/process/child.hpp
|
||||
*
|
||||
* Defines a child process class.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_PROCESS_CHILD_HPP
|
||||
#define BOOST_PROCESS_CHILD_HPP
|
||||
|
||||
#include <boost/process/detail/config.hpp>
|
||||
#include <boost/process/detail/child_decl.hpp>
|
||||
#include <boost/process/detail/execute_impl.hpp>
|
||||
|
||||
#if defined(BOOST_POSIX_API)
|
||||
#include <boost/process/posix.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
///The main namespace of boost.process.
|
||||
namespace process {
|
||||
|
||||
template<typename ...Args>
|
||||
child::child(Args&&...args)
|
||||
: child(::boost::process::detail::execute_impl(std::forward<Args>(args)...)) {}
|
||||
|
||||
|
||||
///Typedef for the type of an pid_t
|
||||
typedef ::boost::process::detail::api::pid_t pid_t;
|
||||
|
||||
#if defined(BOOST_PROCESS_DOXYGEN)
|
||||
/** The main class to hold a child process. It is simliar to [std::thread](http://en.cppreference.com/w/cpp/thread/thread),
|
||||
* in that it has a join and detach function.
|
||||
*
|
||||
* @attention The destructor will call terminate on the process if not joined or detached without any warning.
|
||||
*
|
||||
*/
|
||||
|
||||
class child
|
||||
{
|
||||
/** Type definition for the native process handle. */
|
||||
typedef platform_specific native_handle_t;
|
||||
|
||||
/** Construct the child from a pid.
|
||||
*
|
||||
* @attention There is no guarantee that this will work. The process need the right access rights, which are very platform specific.
|
||||
*/
|
||||
explicit child(pid_t & pid) : _child_handle(pid) {};
|
||||
|
||||
/** Move-Constructor.*/
|
||||
child(child && lhs);
|
||||
|
||||
/** Construct a child from a property list and launch it
|
||||
* The standard version is to create a subprocess, which will spawn the process.
|
||||
*/
|
||||
template<typename ...Args>
|
||||
explicit child(Args&&...args);
|
||||
|
||||
/** Construct an empty child. */
|
||||
child() = default;
|
||||
|
||||
/** Move assign. */
|
||||
child& operator=(child && lhs);
|
||||
|
||||
/** Detach the child, i.e. let it run after this handle dies. */
|
||||
void detach();
|
||||
/** Join the child. This just calls wait, but that way the naming is similar to std::thread */
|
||||
void join();
|
||||
/** Check if the child is joinable. */
|
||||
bool joinable();
|
||||
|
||||
/** Destructor.
|
||||
* @attention Will call terminate (without warning) when the child was neither joined nor detached.
|
||||
*/
|
||||
~child();
|
||||
|
||||
/** Get the native handle for the child process. */
|
||||
native_handle_t native_handle() const;
|
||||
|
||||
/** Get the exit_code. The return value is without any meaning if the child wasn't waited for or if it was terminated. */
|
||||
int exit_code() const;
|
||||
/** Get the Process Identifier. */
|
||||
pid_t id() const;
|
||||
|
||||
/** Get the native, uninterpreted exit code. The return value is without any meaning if the child wasn't waited
|
||||
* for or if it was terminated. */
|
||||
int native_exit_code() const;
|
||||
|
||||
/** Check if the child process is running. */
|
||||
bool running();
|
||||
/** \overload void running() */
|
||||
bool running(std::error_code & ec) noexcept;
|
||||
|
||||
/** Wait for the child process to exit. */
|
||||
void wait();
|
||||
/** \overload void wait() */
|
||||
void wait(std::error_code & ec) noexcept;
|
||||
|
||||
/** Wait for the child process to exit for a period of time.
|
||||
* \return True if child exited while waiting.
|
||||
*/
|
||||
template< class Rep, class Period >
|
||||
bool wait_for (const std::chrono::duration<Rep, Period>& rel_time);
|
||||
/** \overload bool wait_for(const std::chrono::duration<Rep, Period>& rel_time) */
|
||||
bool wait_for (const std::chrono::duration<Rep, Period>& rel_time, std::error_code & ec) noexcept;
|
||||
|
||||
/** Wait for the child process to exit until a point in time.
|
||||
* \return True if child exited while waiting.*/
|
||||
template< class Clock, class Duration >
|
||||
bool wait_until(const std::chrono::time_point<Clock, Duration>& timeout_time );
|
||||
/** \overload bool wait_until(const std::chrono::time_point<Clock, Duration>& timeout_time )*/
|
||||
bool wait_until(const std::chrono::time_point<Clock, Duration>& timeout_time, std::error_code & ec) noexcept;
|
||||
|
||||
/** Check if this handle holds a child process.
|
||||
* @note That does not mean, that the process is still running. It only means, that the handle does or did exist.
|
||||
*/
|
||||
bool valid() const;
|
||||
/** Same as valid, for convenience. */
|
||||
explicit operator bool() const;
|
||||
|
||||
/** Check if the the chlid process is in any process group. */
|
||||
bool in_group() const;
|
||||
|
||||
/** \overload bool in_group() const */
|
||||
bool in_group(std::error_code & ec) const noexcept;
|
||||
|
||||
/** Terminate the child process.
|
||||
*
|
||||
* This function will cause the child process to unconditionally and immediately exit.
|
||||
* It is implement with [SIGKILL](http://pubs.opengroup.org/onlinepubs/009695399/functions/kill.html) on posix
|
||||
* and [TerminateProcess](https://technet.microsoft.com/en-us/library/ms686714.aspx) on windows.
|
||||
*
|
||||
*/
|
||||
void terminate();
|
||||
|
||||
/** \overload void terminate() */
|
||||
void terminate(std::error_code & ec) noexcept;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
}}
|
||||
#endif
|
||||
|
||||
#include <boost/config/header_deprecated.hpp>
|
||||
BOOST_HEADER_DEPRECATED("<boost/process/v1/child.hpp>")
|
||||
#include <boost/process/v1/child.hpp>
|
||||
|
||||
@@ -1,9 +1,122 @@
|
||||
// Copyright (c) 2024 Klemens D. Morgenstern
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
||||
// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
|
||||
// Copyright (c) 2009 Boris Schaeling
|
||||
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
|
||||
// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling
|
||||
// Copyright (c) 2016 Klemens D. Morgenstern
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_PROCESS_DETAIL_CMD_LINE_HPP
|
||||
#define BOOST_PROCESS_DETAIL_CMD_LINE_HPP
|
||||
|
||||
#include <boost/config/header_deprecated.hpp>
|
||||
BOOST_HEADER_DEPRECATED("<boost/process/v1/cmd.hpp>")
|
||||
#include <boost/process/v1/cmd.hpp>
|
||||
#include <boost/winapi/config.hpp>
|
||||
#include <boost/process/detail/config.hpp>
|
||||
#include <boost/process/detail/handler_base.hpp>
|
||||
#include <boost/process/detail/traits/cmd_or_exe.hpp>
|
||||
#include <boost/process/detail/traits/wchar_t.hpp>
|
||||
|
||||
#if defined(BOOST_POSIX_API)
|
||||
#include <boost/process/detail/posix/cmd.hpp>
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
#include <boost/process/detail/windows/cmd.hpp>
|
||||
#endif
|
||||
|
||||
/** \file boost/process/cmd.hpp
|
||||
*
|
||||
* This header provides the \xmlonly <globalname alt="boost::process::cmd">cmd</globalname>\endxmlonly property.
|
||||
*
|
||||
\xmlonly
|
||||
<programlisting>
|
||||
namespace boost {
|
||||
namespace process {
|
||||
<emphasis>unspecified</emphasis> <globalname alt="boost::process::cmd">cmd</globalname>;
|
||||
}
|
||||
}
|
||||
</programlisting>
|
||||
\endxmlonly
|
||||
*/
|
||||
|
||||
namespace boost { namespace process { namespace detail {
|
||||
|
||||
|
||||
struct cmd_
|
||||
{
|
||||
constexpr cmd_() = default;
|
||||
|
||||
template<typename Char>
|
||||
inline api::cmd_setter_<Char> operator()(const Char *s) const
|
||||
{
|
||||
return api::cmd_setter_<Char>(s);
|
||||
}
|
||||
template<typename Char>
|
||||
inline api::cmd_setter_<Char> operator= (const Char *s) const
|
||||
{
|
||||
return api::cmd_setter_<Char>(s);
|
||||
}
|
||||
|
||||
template<typename Char>
|
||||
inline api::cmd_setter_<Char> operator()(const std::basic_string<Char> &s) const
|
||||
{
|
||||
return api::cmd_setter_<Char>(s);
|
||||
}
|
||||
template<typename Char>
|
||||
inline api::cmd_setter_<Char> operator= (const std::basic_string<Char> &s) const
|
||||
{
|
||||
return api::cmd_setter_<Char>(s);
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct is_wchar_t<api::cmd_setter_<wchar_t>> : std::true_type {};
|
||||
|
||||
|
||||
|
||||
template<>
|
||||
struct char_converter<char, api::cmd_setter_<wchar_t>>
|
||||
{
|
||||
static api::cmd_setter_<char> conv(const api::cmd_setter_<wchar_t> & in)
|
||||
{
|
||||
return { ::boost::process::detail::convert(in.str()) };
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct char_converter<wchar_t, api::cmd_setter_<char>>
|
||||
{
|
||||
static api::cmd_setter_<wchar_t> conv(const api::cmd_setter_<char> & in)
|
||||
{
|
||||
return { ::boost::process::detail::convert(in.str()) };
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/** The cmd property allows to explicitly set commands for the execution.
|
||||
|
||||
The overload form applies when only one string is passed to a launching function.
|
||||
The string will be internally parsed and split at spaces.
|
||||
|
||||
The following expressions are valid, with `value` being either a C-String or
|
||||
a `std::basic_string` with `char` or `wchar_t`.
|
||||
|
||||
\code{.cpp}
|
||||
cmd="value";
|
||||
cmd(value);
|
||||
\endcode
|
||||
|
||||
The property can only be used for assignments.
|
||||
|
||||
|
||||
*/
|
||||
constexpr static ::boost::process::detail::cmd_ cmd;
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -11,26 +11,26 @@
|
||||
#include <type_traits>
|
||||
|
||||
#if defined(BOOST_POSIX_API)
|
||||
#include <boost/process/v1/posix.hpp>
|
||||
#include <boost/process/v1/detail/posix/async_handler.hpp>
|
||||
#include <boost/process/v1/detail/posix/asio_fwd.hpp>
|
||||
#include <boost/process/posix.hpp>
|
||||
#include <boost/process/detail/posix/async_handler.hpp>
|
||||
#include <boost/process/detail/posix/asio_fwd.hpp>
|
||||
#else
|
||||
#include <boost/process/v1/detail/windows/async_handler.hpp>
|
||||
#include <boost/process/v1/detail/windows/asio_fwd.hpp>
|
||||
#include <boost/process/detail/windows/async_handler.hpp>
|
||||
#include <boost/process/detail/windows/asio_fwd.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace process { BOOST_PROCESS_V1_INLINE namespace v1 {
|
||||
namespace process {
|
||||
|
||||
namespace detail {
|
||||
|
||||
#if defined(BOOST_POSIX_API)
|
||||
using ::boost::process::v1::detail::posix::is_async_handler;
|
||||
using ::boost::process::v1::detail::posix::does_require_io_context;
|
||||
using ::boost::process::detail::posix::is_async_handler;
|
||||
using ::boost::process::detail::posix::does_require_io_context;
|
||||
#else
|
||||
using ::boost::process::v1::detail::windows::is_async_handler;
|
||||
using ::boost::process::v1::detail::windows::does_require_io_context;
|
||||
using ::boost::process::detail::windows::is_async_handler;
|
||||
using ::boost::process::detail::windows::does_require_io_context;
|
||||
#endif
|
||||
|
||||
template<typename ...Args>
|
||||
@@ -112,7 +112,6 @@ boost::asio::io_context &get_io_context_var(First&, Args&...args)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif /* BOOST_PROCESS_DETAIL_ASYNC_HANDLER_HPP_ */
|
||||
@@ -7,26 +7,26 @@
|
||||
#ifndef BOOST_PROCESS_DETAIL_BASIC_CMD_HPP_
|
||||
#define BOOST_PROCESS_DETAIL_BASIC_CMD_HPP_
|
||||
|
||||
#include <boost/process/v1/detail/config.hpp>
|
||||
#include <boost/process/detail/config.hpp>
|
||||
|
||||
#include <boost/process/v1/detail/handler_base.hpp>
|
||||
#include <boost/process/v1/detail/traits/cmd_or_exe.hpp>
|
||||
#include <boost/process/v1/detail/traits/wchar_t.hpp>
|
||||
#include <boost/process/detail/handler_base.hpp>
|
||||
#include <boost/process/detail/traits/cmd_or_exe.hpp>
|
||||
#include <boost/process/detail/traits/wchar_t.hpp>
|
||||
|
||||
#if defined( BOOST_WINDOWS_API )
|
||||
#include <boost/process/v1/detail/windows/basic_cmd.hpp>
|
||||
#include <boost/process/v1/detail/windows/cmd.hpp>
|
||||
#include <boost/process/detail/windows/basic_cmd.hpp>
|
||||
#include <boost/process/detail/windows/cmd.hpp>
|
||||
#elif defined( BOOST_POSIX_API )
|
||||
#include <boost/process/v1/detail/posix/basic_cmd.hpp>
|
||||
#include <boost/process/v1/detail/posix/cmd.hpp>
|
||||
#include <boost/process/detail/posix/basic_cmd.hpp>
|
||||
#include <boost/process/detail/posix/cmd.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/process/v1/shell.hpp>
|
||||
#include <boost/process/shell.hpp>
|
||||
|
||||
#include <iterator>
|
||||
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail {
|
||||
namespace boost { namespace process { namespace detail {
|
||||
|
||||
template<typename Char>
|
||||
struct exe_setter_
|
||||
@@ -47,7 +47,7 @@ struct char_converter<char, exe_setter_<wchar_t>>
|
||||
{
|
||||
static exe_setter_<char> conv(const exe_setter_<wchar_t> & in)
|
||||
{
|
||||
return {::boost::process::v1::detail::convert(in.exe_)};
|
||||
return {::boost::process::detail::convert(in.exe_)};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -56,7 +56,7 @@ struct char_converter<wchar_t, exe_setter_<char>>
|
||||
{
|
||||
static exe_setter_<wchar_t> conv(const exe_setter_<char> & in)
|
||||
{
|
||||
return {::boost::process::v1::detail::convert(in.exe_)};
|
||||
return {::boost::process::detail::convert(in.exe_)};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -105,7 +105,7 @@ struct char_converter<char, arg_setter_<wchar_t, true>>
|
||||
std::transform(in._args.begin(), in._args.end(), vec.begin(),
|
||||
[](const std::wstring & ws)
|
||||
{
|
||||
return ::boost::process::v1::detail::convert(ws);
|
||||
return ::boost::process::detail::convert(ws);
|
||||
});
|
||||
return {vec};
|
||||
}
|
||||
@@ -120,7 +120,7 @@ struct char_converter<wchar_t, arg_setter_<char, true>>
|
||||
std::transform(in._args.begin(), in._args.end(), vec.begin(),
|
||||
[](const std::string & ws)
|
||||
{
|
||||
return ::boost::process::v1::detail::convert(ws);
|
||||
return ::boost::process::detail::convert(ws);
|
||||
});
|
||||
|
||||
return {vec};
|
||||
@@ -136,7 +136,7 @@ struct char_converter<char, arg_setter_<wchar_t, false>>
|
||||
std::transform(in._args.begin(), in._args.end(), vec.begin(),
|
||||
[](const std::wstring & ws)
|
||||
{
|
||||
return ::boost::process::v1::detail::convert(ws);
|
||||
return ::boost::process::detail::convert(ws);
|
||||
});
|
||||
return {vec}; }
|
||||
};
|
||||
@@ -150,7 +150,7 @@ struct char_converter<wchar_t, arg_setter_<char, false>>
|
||||
std::transform(in._args.begin(), in._args.end(), vec.begin(),
|
||||
[](const std::string & ws)
|
||||
{
|
||||
return ::boost::process::v1::detail::convert(ws);
|
||||
return ::boost::process::detail::convert(ws);
|
||||
});
|
||||
return {vec};
|
||||
}
|
||||
@@ -168,7 +168,7 @@ struct exe_builder
|
||||
string_type exe;
|
||||
std::vector<string_type> args;
|
||||
|
||||
void operator()(const boost::process::v1::filesystem::path & data)
|
||||
void operator()(const boost::process::filesystem::path & data)
|
||||
{
|
||||
not_cmd = true;
|
||||
if (exe.empty())
|
||||
@@ -285,7 +285,7 @@ struct initializer_builder<cmd_or_exe_tag<wchar_t>>
|
||||
typedef exe_builder<wchar_t> type;
|
||||
};
|
||||
|
||||
}}}}
|
||||
}}}
|
||||
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#ifndef BOOST_PROCESS_CHILD_DECL_HPP
|
||||
#define BOOST_PROCESS_CHILD_DECL_HPP
|
||||
|
||||
#include <boost/process/v1/detail/config.hpp>
|
||||
#include <boost/process/detail/config.hpp>
|
||||
#include <chrono>
|
||||
#include <memory>
|
||||
|
||||
@@ -25,36 +25,36 @@
|
||||
#include <atomic>
|
||||
|
||||
#if defined(BOOST_POSIX_API)
|
||||
#include <boost/process/v1/detail/posix/child_handle.hpp>
|
||||
#include <boost/process/v1/detail/posix/terminate.hpp>
|
||||
#include <boost/process/v1/detail/posix/wait_for_exit.hpp>
|
||||
#include <boost/process/v1/detail/posix/is_running.hpp>
|
||||
#include <boost/process/detail/posix/child_handle.hpp>
|
||||
#include <boost/process/detail/posix/terminate.hpp>
|
||||
#include <boost/process/detail/posix/wait_for_exit.hpp>
|
||||
#include <boost/process/detail/posix/is_running.hpp>
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
#include <boost/process/v1/detail/windows/child_handle.hpp>
|
||||
#include <boost/process/v1/detail/windows/terminate.hpp>
|
||||
#include <boost/process/v1/detail/windows/wait_for_exit.hpp>
|
||||
#include <boost/process/v1/detail/windows/is_running.hpp>
|
||||
#include <boost/process/detail/windows/child_handle.hpp>
|
||||
#include <boost/process/detail/windows/terminate.hpp>
|
||||
#include <boost/process/detail/windows/wait_for_exit.hpp>
|
||||
#include <boost/process/detail/windows/is_running.hpp>
|
||||
|
||||
#endif
|
||||
namespace boost {
|
||||
|
||||
namespace process { BOOST_PROCESS_V1_INLINE namespace v1 {
|
||||
namespace process {
|
||||
|
||||
using ::boost::process::v1::detail::api::pid_t;
|
||||
using ::boost::process::detail::api::pid_t;
|
||||
|
||||
class child
|
||||
{
|
||||
::boost::process::v1::detail::api::child_handle _child_handle;
|
||||
std::shared_ptr<std::atomic<int>> _exit_status = std::make_shared<std::atomic<int>>(::boost::process::v1::detail::api::still_active);
|
||||
::boost::process::detail::api::child_handle _child_handle;
|
||||
std::shared_ptr<std::atomic<int>> _exit_status = std::make_shared<std::atomic<int>>(::boost::process::detail::api::still_active);
|
||||
bool _attached = true;
|
||||
bool _terminated = false;
|
||||
|
||||
bool _exited()
|
||||
{
|
||||
return _terminated || !::boost::process::v1::detail::api::is_running(_exit_status->load());
|
||||
return _terminated || !::boost::process::detail::api::is_running(_exit_status->load());
|
||||
};
|
||||
public:
|
||||
typedef ::boost::process::v1::detail::api::child_handle child_handle;
|
||||
typedef ::boost::process::detail::api::child_handle child_handle;
|
||||
typedef child_handle::process_handle_t native_handle_t;
|
||||
explicit child(child_handle &&ch, std::shared_ptr<std::atomic<int>> &ptr) : _child_handle(std::move(ch)), _exit_status(ptr) {}
|
||||
explicit child(child_handle &&ch, const std::shared_ptr<std::atomic<int>> &ptr) : _child_handle(std::move(ch)), _exit_status(ptr) {}
|
||||
@@ -98,7 +98,7 @@ public:
|
||||
native_handle_t native_handle() const { return _child_handle.process_handle(); }
|
||||
|
||||
|
||||
int exit_code() const {return ::boost::process::v1::detail::api::eval_exit_status(_exit_status->load());}
|
||||
int exit_code() const {return ::boost::process::detail::api::eval_exit_status(_exit_status->load());}
|
||||
pid_t id() const {return _child_handle.id(); }
|
||||
|
||||
int native_exit_code() const {return _exit_status->load();}
|
||||
@@ -107,7 +107,7 @@ public:
|
||||
{
|
||||
std::error_code ec;
|
||||
bool b = running(ec);
|
||||
boost::process::v1::detail::throw_error(ec, "running error");
|
||||
boost::process::detail::throw_error(ec, "running error");
|
||||
return b;
|
||||
}
|
||||
|
||||
@@ -115,14 +115,14 @@ public:
|
||||
{
|
||||
std::error_code ec;
|
||||
terminate(ec);
|
||||
boost::process::v1::detail::throw_error(ec, "terminate error");
|
||||
boost::process::detail::throw_error(ec, "terminate error");
|
||||
}
|
||||
|
||||
void wait()
|
||||
{
|
||||
std::error_code ec;
|
||||
wait(ec);
|
||||
boost::process::v1::detail::throw_error(ec, "wait error");
|
||||
boost::process::detail::throw_error(ec, "wait error");
|
||||
}
|
||||
|
||||
#if !defined(BOOST_PROCESS_NO_DEPRECATED)
|
||||
@@ -133,7 +133,7 @@ public:
|
||||
{
|
||||
std::error_code ec;
|
||||
bool b = wait_for(rel_time, ec);
|
||||
boost::process::v1::detail::throw_error(ec, "wait_for error");
|
||||
boost::process::detail::throw_error(ec, "wait_for error");
|
||||
return b;
|
||||
}
|
||||
|
||||
@@ -143,7 +143,7 @@ public:
|
||||
{
|
||||
std::error_code ec;
|
||||
bool b = wait_until(timeout_time, ec);
|
||||
boost::process::v1::detail::throw_error(ec, "wait_until error");
|
||||
boost::process::detail::throw_error(ec, "wait_until error");
|
||||
return b;
|
||||
}
|
||||
#endif
|
||||
@@ -154,7 +154,7 @@ public:
|
||||
if (valid() && !_exited() && !ec)
|
||||
{
|
||||
int exit_code = 0;
|
||||
auto res = boost::process::v1::detail::api::is_running(_child_handle, exit_code, ec);
|
||||
auto res = boost::process::detail::api::is_running(_child_handle, exit_code, ec);
|
||||
if (!ec && !res && !_exited())
|
||||
_exit_status->store(exit_code);
|
||||
|
||||
@@ -166,7 +166,7 @@ public:
|
||||
void terminate(std::error_code & ec) noexcept
|
||||
{
|
||||
if (valid() && running(ec) && !ec)
|
||||
boost::process::v1::detail::api::terminate(_child_handle, ec);
|
||||
boost::process::detail::api::terminate(_child_handle, ec);
|
||||
|
||||
if (!ec)
|
||||
_terminated = true;
|
||||
@@ -177,7 +177,7 @@ public:
|
||||
if (!_exited() && valid())
|
||||
{
|
||||
int exit_code = 0;
|
||||
boost::process::v1::detail::api::wait(_child_handle, exit_code, ec);
|
||||
boost::process::detail::api::wait(_child_handle, exit_code, ec);
|
||||
if (!ec)
|
||||
_exit_status->store(exit_code);
|
||||
}
|
||||
@@ -198,7 +198,7 @@ public:
|
||||
if (!_exited())
|
||||
{
|
||||
int exit_code = 0;
|
||||
auto b = boost::process::v1::detail::api::wait_until(_child_handle, exit_code, timeout_time, ec);
|
||||
auto b = boost::process::detail::api::wait_until(_child_handle, exit_code, timeout_time, ec);
|
||||
if (!b || ec)
|
||||
return false;
|
||||
_exit_status->store(exit_code);
|
||||
@@ -225,7 +225,6 @@ public:
|
||||
|
||||
|
||||
|
||||
}}}
|
||||
|
||||
}}
|
||||
#endif
|
||||
|
||||
@@ -21,19 +21,7 @@
|
||||
#include <system_error>
|
||||
#include <boost/system/api_config.hpp>
|
||||
|
||||
#if !defined(BOOST_PROCESS_VERSION)
|
||||
#define BOOST_PROCESS_VERSION 1
|
||||
#endif
|
||||
|
||||
#if BOOST_PROCESS_VERSION == 1
|
||||
#define BOOST_PROCESS_V1_INLINE inline
|
||||
#else
|
||||
#define BOOST_PROCESS_V1_INLINE
|
||||
#endif
|
||||
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/process/v1/exception.hpp>
|
||||
#include <boost/assert/source_location.hpp>
|
||||
#include <boost/process/exception.hpp>
|
||||
|
||||
#if defined(BOOST_POSIX_API)
|
||||
#include <errno.h>
|
||||
@@ -48,9 +36,7 @@ extern char **environ;
|
||||
#error "System API not supported by boost.process"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail
|
||||
namespace boost { namespace process { namespace detail
|
||||
{
|
||||
|
||||
#if !defined(BOOST_PROCESS_PIPE_SIZE)
|
||||
@@ -85,33 +71,31 @@ inline std::error_code get_last_error() noexcept
|
||||
}
|
||||
#endif
|
||||
|
||||
inline void throw_last_error(const std::string & msg, boost::source_location const & loc = boost::source_location())
|
||||
inline void throw_last_error(const std::string & msg)
|
||||
{
|
||||
boost::throw_exception(process_error(get_last_error(), msg), loc);
|
||||
throw process_error(get_last_error(), msg);
|
||||
}
|
||||
|
||||
inline void throw_last_error(const char * msg, boost::source_location const & loc = boost::source_location())
|
||||
inline void throw_last_error(const char * msg)
|
||||
{
|
||||
boost::throw_exception(process_error(get_last_error(), msg), loc);
|
||||
throw process_error(get_last_error(), msg);
|
||||
}
|
||||
|
||||
inline void throw_last_error(boost::source_location const & loc = boost::source_location())
|
||||
inline void throw_last_error()
|
||||
{
|
||||
boost::throw_exception(process_error(get_last_error()), loc);
|
||||
throw process_error(get_last_error());
|
||||
}
|
||||
|
||||
inline void throw_error(const std::error_code& ec,
|
||||
boost::source_location const & loc = boost::source_location())
|
||||
inline void throw_error(const std::error_code& ec)
|
||||
{
|
||||
if (ec)
|
||||
boost::throw_exception(process_error(ec), loc);
|
||||
throw process_error(ec);
|
||||
}
|
||||
|
||||
inline void throw_error(const std::error_code& ec, const char* msg,
|
||||
boost::source_location const & loc = boost::source_location())
|
||||
inline void throw_error(const std::error_code& ec, const char* msg)
|
||||
{
|
||||
if (ec)
|
||||
boost::throw_exception(process_error(ec, msg), loc);
|
||||
throw process_error(ec, msg);
|
||||
}
|
||||
|
||||
template<typename Char> constexpr Char null_char();
|
||||
@@ -133,7 +117,5 @@ template<> constexpr wchar_t space_sign<wchar_t> () {return L' '; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
@@ -17,17 +17,17 @@
|
||||
#ifndef BOOST_PROCESS_EXECUTE_HPP
|
||||
#define BOOST_PROCESS_EXECUTE_HPP
|
||||
|
||||
#include <boost/process/v1/detail/config.hpp>
|
||||
#include <boost/process/v1/detail/traits.hpp>
|
||||
#include <boost/process/detail/config.hpp>
|
||||
#include <boost/process/detail/traits.hpp>
|
||||
|
||||
#if defined(BOOST_POSIX_API)
|
||||
#include <boost/process/v1/detail/posix/executor.hpp>
|
||||
#include <boost/process/detail/posix/executor.hpp>
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
#include <boost/process/v1/detail/windows/executor.hpp>
|
||||
#include <boost/process/detail/windows/executor.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/process/v1/detail/basic_cmd.hpp>
|
||||
#include <boost/process/v1/detail/handler.hpp>
|
||||
#include <boost/process/detail/basic_cmd.hpp>
|
||||
#include <boost/process/detail/handler.hpp>
|
||||
|
||||
#include <boost/fusion/view.hpp>
|
||||
#include <boost/fusion/container.hpp>
|
||||
@@ -40,7 +40,7 @@
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 {
|
||||
namespace boost { namespace process {
|
||||
|
||||
class child;
|
||||
|
||||
@@ -228,7 +228,7 @@ inline child basic_execute_impl(Args && ... args)
|
||||
boost::fusion::tuple<typename std::remove_reference<Args>::type&...> tup(args...);
|
||||
|
||||
auto inits = boost::fusion::filter_if<
|
||||
boost::process::v1::detail::is_initializer<
|
||||
boost::process::detail::is_initializer<
|
||||
typename std::remove_reference<
|
||||
boost::mpl::_
|
||||
>::type
|
||||
@@ -237,7 +237,7 @@ inline child basic_execute_impl(Args && ... args)
|
||||
|
||||
auto others = boost::fusion::filter_if<
|
||||
boost::mpl::not_<
|
||||
boost::process::v1::detail::is_initializer<
|
||||
boost::process::detail::is_initializer<
|
||||
typename std::remove_reference<
|
||||
boost::mpl::_
|
||||
>::type
|
||||
@@ -250,20 +250,20 @@ inline child basic_execute_impl(Args && ... args)
|
||||
//typedef typename boost::fusion::result_of::as_vector<decltype(inits)>::type inits_t;
|
||||
typedef typename boost::fusion::result_of::as_vector<decltype(others)>::type others_t;
|
||||
// typedef decltype(others) others_t;
|
||||
typedef typename ::boost::process::v1::detail::make_builders_from_view<
|
||||
typedef typename ::boost::process::detail::make_builders_from_view<
|
||||
typename boost::fusion::result_of::begin<others_t>::type,
|
||||
typename boost::fusion::result_of::end <others_t>::type>::type builder_t;
|
||||
|
||||
builder_t builders;
|
||||
::boost::process::v1::detail::builder_ref<builder_t> builder_ref(builders);
|
||||
::boost::process::detail::builder_ref<builder_t> builder_ref(builders);
|
||||
|
||||
boost::fusion::for_each(others, builder_ref);
|
||||
auto other_inits = ::boost::process::v1::detail::get_initializers(builders);
|
||||
auto other_inits = ::boost::process::detail::get_initializers(builders);
|
||||
|
||||
|
||||
boost::fusion::joint_view<decltype(other_inits), decltype(inits)> complete_inits(other_inits, inits);
|
||||
|
||||
auto exec = boost::process::v1::detail::api::make_executor<Char>(complete_inits);
|
||||
auto exec = boost::process::detail::api::make_executor<Char>(complete_inits);
|
||||
return exec();
|
||||
}
|
||||
|
||||
@@ -273,11 +273,12 @@ inline child execute_impl(Args&& ... args)
|
||||
typedef required_char_type_t<Args...> req_char_type;
|
||||
|
||||
return basic_execute_impl<req_char_type>(
|
||||
boost::process::v1::detail::char_converter_t<req_char_type, Args>::conv(
|
||||
boost::process::detail::char_converter_t<req_char_type, Args>::conv(
|
||||
std::forward<Args>(args))...
|
||||
);
|
||||
}
|
||||
|
||||
}}}}
|
||||
}}}
|
||||
|
||||
|
||||
#endif
|
||||
@@ -7,16 +7,16 @@
|
||||
#ifndef BOOST_PROCESS_DETAIL_HANDLER_HPP_
|
||||
#define BOOST_PROCESS_DETAIL_HANDLER_HPP_
|
||||
|
||||
#include <boost/process/v1/detail/config.hpp>
|
||||
#include <boost/process/detail/config.hpp>
|
||||
|
||||
#if defined(BOOST_POSIX_API)
|
||||
#include <boost/process/v1/detail/posix/handler.hpp>
|
||||
#include <boost/process/detail/posix/handler.hpp>
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
#include <boost/process/v1/detail/windows/handler.hpp>
|
||||
#include <boost/process/detail/windows/handler.hpp>
|
||||
#endif
|
||||
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail {
|
||||
namespace boost { namespace process { namespace detail {
|
||||
|
||||
//extended handler base.
|
||||
typedef api::handler_base_ext handler;
|
||||
@@ -68,6 +68,8 @@ private:
|
||||
|
||||
|
||||
|
||||
}}}
|
||||
}}
|
||||
|
||||
|
||||
|
||||
#endif /* BOOST_PROCESS_DETAIL_HANDLER_HPP_ */
|
||||
@@ -11,10 +11,9 @@
|
||||
#ifndef BOOST_PROCESS_DETAIL_HANDLER_BASE_HPP
|
||||
#define BOOST_PROCESS_DETAIL_HANDLER_BASE_HPP
|
||||
|
||||
#include <boost/process/v1/detail/config.hpp>
|
||||
#include <system_error>
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail {
|
||||
namespace boost { namespace process { namespace detail {
|
||||
|
||||
template<template <class> class Template>
|
||||
struct make_handler_t
|
||||
@@ -45,6 +44,6 @@ struct handler_base
|
||||
};
|
||||
|
||||
|
||||
}}}}
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -6,18 +6,18 @@
|
||||
#ifndef BOOST_PROCESS_DETAIL_ON_EXIT_HPP_
|
||||
#define BOOST_PROCESS_DETAIL_ON_EXIT_HPP_
|
||||
|
||||
#include <boost/process/v1/detail/config.hpp>
|
||||
#include <boost/process/detail/config.hpp>
|
||||
|
||||
#if defined(BOOST_POSIX_API)
|
||||
#include <boost/process/v1/detail/posix/on_exit.hpp>
|
||||
#include <boost/process/detail/posix/on_exit.hpp>
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
#include <boost/process/v1/detail/windows/on_exit.hpp>
|
||||
#include <boost/process/detail/windows/on_exit.hpp>
|
||||
#endif
|
||||
|
||||
#include <future>
|
||||
#include <memory>
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail {
|
||||
namespace boost { namespace process { namespace detail {
|
||||
|
||||
inline std::function<void(int, const std::error_code &)> on_exit_from_future(std::future<int> &f)
|
||||
{
|
||||
@@ -46,9 +46,8 @@ struct on_exit_
|
||||
|
||||
}
|
||||
|
||||
constexpr static ::boost::process::v1::detail::on_exit_ on_exit{};
|
||||
constexpr static ::boost::process::detail::on_exit_ on_exit{};
|
||||
|
||||
|
||||
}}}
|
||||
|
||||
}}
|
||||
#endif /* INCLUDE_BOOST_PROCESS_WINDOWS_ON_EXIT_HPP_ */
|
||||
@@ -38,7 +38,7 @@ typedef basic_stream_descriptor<any_io_executor> stream_descriptor;
|
||||
} //posix
|
||||
} //asio
|
||||
|
||||
namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail { namespace posix {
|
||||
namespace process { namespace detail { namespace posix {
|
||||
|
||||
class async_pipe;
|
||||
|
||||
@@ -54,9 +54,8 @@ struct async_out_future;
|
||||
} // posix
|
||||
} // detail
|
||||
|
||||
using ::boost::process::v1::detail::posix::async_pipe;
|
||||
using ::boost::process::detail::posix::async_pipe;
|
||||
|
||||
} // v1
|
||||
} // process
|
||||
} // boost
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
#ifndef BOOST_PROCESS_POSIX_ASYNC_HANDLER_HPP_
|
||||
#define BOOST_PROCESS_POSIX_ASYNC_HANDLER_HPP_
|
||||
|
||||
#include <boost/process/v1/detail/posix/handler.hpp>
|
||||
#include <boost/process/detail/posix/handler.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail { namespace posix {
|
||||
namespace boost { namespace process { namespace detail { namespace posix {
|
||||
|
||||
struct require_io_context {};
|
||||
|
||||
@@ -35,6 +35,6 @@ template<typename T>
|
||||
struct does_require_io_context<const T&> : std::is_base_of<require_io_context, T> {};
|
||||
|
||||
|
||||
}}}}}
|
||||
}}}}
|
||||
|
||||
#endif /* BOOST_PROCESS_WINDOWS_ASYNC_HANDLER_HPP_ */
|
||||
@@ -10,22 +10,22 @@
|
||||
#ifndef BOOST_PROCESS_DETAIL_POSIX_ASYNC_IN_HPP
|
||||
#define BOOST_PROCESS_DETAIL_POSIX_ASYNC_IN_HPP
|
||||
|
||||
#include <boost/process/v1/detail/handler_base.hpp>
|
||||
#include <boost/process/v1/detail/posix/async_handler.hpp>
|
||||
#include <boost/process/detail/handler_base.hpp>
|
||||
#include <boost/process/detail/posix/async_handler.hpp>
|
||||
#include <boost/asio/write.hpp>
|
||||
#include <boost/process/v1/async_pipe.hpp>
|
||||
#include <boost/process/async_pipe.hpp>
|
||||
#include <memory>
|
||||
#include <future>
|
||||
#include <boost/process/v1/detail/used_handles.hpp>
|
||||
#include <boost/process/detail/used_handles.hpp>
|
||||
#include <array>
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail { namespace posix {
|
||||
namespace boost { namespace process { namespace detail { namespace posix {
|
||||
|
||||
|
||||
template<typename Buffer>
|
||||
struct async_in_buffer : ::boost::process::v1::detail::posix::handler_base_ext,
|
||||
::boost::process::v1::detail::posix::require_io_context,
|
||||
::boost::process::v1::detail::uses_handles
|
||||
struct async_in_buffer : ::boost::process::detail::posix::handler_base_ext,
|
||||
::boost::process::detail::posix::require_io_context,
|
||||
::boost::process::detail::uses_handles
|
||||
{
|
||||
Buffer & buf;
|
||||
|
||||
@@ -37,7 +37,7 @@ struct async_in_buffer : ::boost::process::v1::detail::posix::handler_base_ext,
|
||||
}
|
||||
|
||||
|
||||
std::shared_ptr<boost::process::v1::async_pipe> pipe;
|
||||
std::shared_ptr<boost::process::async_pipe> pipe;
|
||||
|
||||
async_in_buffer(Buffer & buf) : buf(buf)
|
||||
{
|
||||
@@ -81,7 +81,7 @@ struct async_in_buffer : ::boost::process::v1::detail::posix::handler_base_ext,
|
||||
void on_setup(Executor & exec)
|
||||
{
|
||||
if (!pipe)
|
||||
pipe = std::make_shared<boost::process::v1::async_pipe>(get_io_context(exec.seq));
|
||||
pipe = std::make_shared<boost::process::async_pipe>(get_io_context(exec.seq));
|
||||
}
|
||||
|
||||
std::array<int, 3> get_used_handles()
|
||||
@@ -97,7 +97,7 @@ struct async_in_buffer : ::boost::process::v1::detail::posix::handler_base_ext,
|
||||
void on_exec_setup(Executor &exec)
|
||||
{
|
||||
if (::dup2(pipe->native_source(), STDIN_FILENO) == -1)
|
||||
exec.set_error(::boost::process::v1::detail::get_last_error(), "dup2() failed");
|
||||
exec.set_error(::boost::process::detail::get_last_error(), "dup2() failed");
|
||||
|
||||
if (pipe->native_source() != STDIN_FILENO)
|
||||
::close(pipe->native_source());
|
||||
@@ -106,6 +106,6 @@ struct async_in_buffer : ::boost::process::v1::detail::posix::handler_base_ext,
|
||||
};
|
||||
|
||||
|
||||
}}}}}
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
@@ -11,18 +11,18 @@
|
||||
#define BOOST_PROCESS_DETAIL_POSIX_ASYNC_OUT_HPP
|
||||
|
||||
|
||||
#include <boost/process/v1/detail/posix/handler.hpp>
|
||||
#include <boost/process/detail/posix/handler.hpp>
|
||||
#include <boost/asio/posix/stream_descriptor.hpp>
|
||||
#include <boost/asio/read.hpp>
|
||||
#include <boost/process/v1/async_pipe.hpp>
|
||||
#include <boost/process/async_pipe.hpp>
|
||||
#include <istream>
|
||||
#include <memory>
|
||||
#include <exception>
|
||||
#include <future>
|
||||
#include <array>
|
||||
#include <boost/process/v1/detail/used_handles.hpp>
|
||||
#include <boost/process/detail/used_handles.hpp>
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail { namespace posix {
|
||||
namespace boost { namespace process { namespace detail { namespace posix {
|
||||
|
||||
|
||||
inline int apply_out_handles(int handle, std::integral_constant<int, 1>, std::integral_constant<int, -1>)
|
||||
@@ -46,13 +46,13 @@ inline int apply_out_handles(int handle, std::integral_constant<int, 1>, std::in
|
||||
}
|
||||
|
||||
template<int p1, int p2, typename Buffer>
|
||||
struct async_out_buffer : ::boost::process::v1::detail::posix::handler_base_ext,
|
||||
::boost::process::v1::detail::posix::require_io_context,
|
||||
::boost::process::v1::detail::uses_handles
|
||||
struct async_out_buffer : ::boost::process::detail::posix::handler_base_ext,
|
||||
::boost::process::detail::posix::require_io_context,
|
||||
::boost::process::detail::uses_handles
|
||||
{
|
||||
Buffer & buf;
|
||||
|
||||
std::shared_ptr<boost::process::v1::async_pipe> pipe;
|
||||
std::shared_ptr<boost::process::async_pipe> pipe;
|
||||
|
||||
std::array<int, 4> get_used_handles()
|
||||
{
|
||||
@@ -71,7 +71,7 @@ struct async_out_buffer : ::boost::process::v1::detail::posix::handler_base_ext,
|
||||
}
|
||||
|
||||
template <typename Executor>
|
||||
inline void on_success(Executor &)
|
||||
inline void on_success(Executor &exec)
|
||||
{
|
||||
auto pipe = this->pipe;
|
||||
boost::asio::async_read(*pipe, buf,
|
||||
@@ -90,7 +90,7 @@ struct async_out_buffer : ::boost::process::v1::detail::posix::handler_base_ext,
|
||||
template<typename Executor>
|
||||
void on_setup(Executor & exec)
|
||||
{
|
||||
pipe = std::make_shared<boost::process::v1::async_pipe>(get_io_context(exec.seq));
|
||||
pipe = std::make_shared<boost::process::async_pipe>(get_io_context(exec.seq));
|
||||
}
|
||||
|
||||
|
||||
@@ -100,7 +100,7 @@ struct async_out_buffer : ::boost::process::v1::detail::posix::handler_base_ext,
|
||||
int res = apply_out_handles(pipe->native_sink(),
|
||||
std::integral_constant<int, p1>(), std::integral_constant<int, p2>());
|
||||
if (res == -1)
|
||||
exec.set_error(::boost::process::v1::detail::get_last_error(), "dup2() failed");
|
||||
exec.set_error(::boost::process::detail::get_last_error(), "dup2() failed");
|
||||
|
||||
::close(pipe->native_sink());
|
||||
::close(pipe->native_source());
|
||||
@@ -112,14 +112,14 @@ struct async_out_buffer : ::boost::process::v1::detail::posix::handler_base_ext,
|
||||
|
||||
|
||||
template<int p1, int p2, typename Type>
|
||||
struct async_out_future : ::boost::process::v1::detail::posix::handler_base_ext,
|
||||
::boost::process::v1::detail::posix::require_io_context
|
||||
struct async_out_future : ::boost::process::detail::posix::handler_base_ext,
|
||||
::boost::process::detail::posix::require_io_context
|
||||
{
|
||||
std::shared_ptr<std::promise<Type>> promise = std::make_shared<std::promise<Type>>();
|
||||
|
||||
std::shared_ptr<boost::asio::streambuf> buffer = std::make_shared<boost::asio::streambuf>();
|
||||
|
||||
std::shared_ptr<boost::process::v1::async_pipe> pipe;
|
||||
std::shared_ptr<boost::process::async_pipe> pipe;
|
||||
|
||||
async_out_future(std::future<Type> & fut)
|
||||
{
|
||||
@@ -167,7 +167,7 @@ struct async_out_future : ::boost::process::v1::detail::posix::handler_base_ext,
|
||||
template<typename Executor>
|
||||
void on_setup(Executor & exec)
|
||||
{
|
||||
pipe = std::make_shared<boost::process::v1::async_pipe>(get_io_context(exec.seq));
|
||||
pipe = std::make_shared<boost::process::async_pipe>(get_io_context(exec.seq));
|
||||
}
|
||||
|
||||
template <typename Executor>
|
||||
@@ -177,7 +177,7 @@ struct async_out_future : ::boost::process::v1::detail::posix::handler_base_ext,
|
||||
int res = apply_out_handles(pipe->native_sink(),
|
||||
std::integral_constant<int, p1>(), std::integral_constant<int, p2>());
|
||||
if (res == -1)
|
||||
exec.set_error(::boost::process::v1::detail::get_last_error(), "dup2() failed");
|
||||
exec.set_error(::boost::process::detail::get_last_error(), "dup2() failed");
|
||||
|
||||
::close(pipe->native_sink());
|
||||
::close(pipe->native_source());
|
||||
@@ -185,6 +185,6 @@ struct async_out_future : ::boost::process::v1::detail::posix::handler_base_ext,
|
||||
|
||||
};
|
||||
|
||||
}}}}}
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
@@ -7,14 +7,14 @@
|
||||
#define BOOST_PROCESS_DETAIL_POSIX_ASYNC_PIPE_HPP_
|
||||
|
||||
|
||||
#include <boost/process/v1/detail/posix/basic_pipe.hpp>
|
||||
#include <boost/process/detail/posix/basic_pipe.hpp>
|
||||
#include <boost/asio/posix/stream_descriptor.hpp>
|
||||
#include <boost/asio/post.hpp>
|
||||
#include <system_error>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail { namespace posix {
|
||||
namespace boost { namespace process { namespace detail { namespace posix {
|
||||
|
||||
class async_pipe
|
||||
{
|
||||
@@ -37,7 +37,7 @@ public:
|
||||
{
|
||||
int fds[2];
|
||||
if (::pipe(fds) == -1)
|
||||
boost::process::v1::detail::throw_last_error("pipe(2) failed");
|
||||
boost::process::detail::throw_last_error("pipe(2) failed");
|
||||
|
||||
_source.assign(fds[0]);
|
||||
_sink .assign(fds[1]);
|
||||
@@ -205,18 +205,18 @@ async_pipe::async_pipe(boost::asio::io_context & ios_source,
|
||||
auto fifo = mkfifo(name.c_str(), 0666 );
|
||||
|
||||
if (fifo != 0)
|
||||
boost::process::v1::detail::throw_last_error("mkfifo() failed");
|
||||
boost::process::detail::throw_last_error("mkfifo() failed");
|
||||
|
||||
|
||||
int read_fd = open(name.c_str(), O_RDWR);
|
||||
|
||||
if (read_fd == -1)
|
||||
boost::process::v1::detail::throw_last_error();
|
||||
boost::process::detail::throw_last_error();
|
||||
|
||||
int write_fd = dup(read_fd);
|
||||
|
||||
if (write_fd == -1)
|
||||
boost::process::v1::detail::throw_last_error();
|
||||
boost::process::detail::throw_last_error();
|
||||
|
||||
_source.assign(read_fd);
|
||||
_sink .assign(write_fd);
|
||||
@@ -236,7 +236,7 @@ async_pipe::async_pipe(const async_pipe & p) :
|
||||
{
|
||||
_source.assign(::dup(source_in));
|
||||
if (_source.native_handle()== -1)
|
||||
::boost::process::v1::detail::throw_last_error("dup()");
|
||||
::boost::process::detail::throw_last_error("dup()");
|
||||
}
|
||||
|
||||
if (sink_in == -1)
|
||||
@@ -245,7 +245,7 @@ async_pipe::async_pipe(const async_pipe & p) :
|
||||
{
|
||||
_sink.assign(::dup(sink_in));
|
||||
if (_sink.native_handle() == -1)
|
||||
::boost::process::v1::detail::throw_last_error("dup()");
|
||||
::boost::process::detail::throw_last_error("dup()");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -263,7 +263,7 @@ async_pipe& async_pipe::operator=(const async_pipe & p)
|
||||
{
|
||||
source = ::dup(source_in);
|
||||
if (source == -1)
|
||||
::boost::process::v1::detail::throw_last_error("dup()");
|
||||
::boost::process::detail::throw_last_error("dup()");
|
||||
}
|
||||
|
||||
if (sink_in == -1)
|
||||
@@ -272,7 +272,7 @@ async_pipe& async_pipe::operator=(const async_pipe & p)
|
||||
{
|
||||
sink = ::dup(sink_in);
|
||||
if (sink == -1)
|
||||
::boost::process::v1::detail::throw_last_error("dup()");
|
||||
::boost::process::detail::throw_last_error("dup()");
|
||||
}
|
||||
_source.assign(source);
|
||||
_sink. assign(sink);
|
||||
@@ -304,7 +304,7 @@ async_pipe::operator basic_pipe<CharT, Traits>() const
|
||||
{
|
||||
source = ::dup(source_in);
|
||||
if (source == -1)
|
||||
::boost::process::v1::detail::throw_last_error("dup()");
|
||||
::boost::process::detail::throw_last_error("dup()");
|
||||
}
|
||||
|
||||
if (sink_in == -1)
|
||||
@@ -313,7 +313,7 @@ async_pipe::operator basic_pipe<CharT, Traits>() const
|
||||
{
|
||||
sink = ::dup(sink_in);
|
||||
if (sink == -1)
|
||||
::boost::process::v1::detail::throw_last_error("dup()");
|
||||
::boost::process::detail::throw_last_error("dup()");
|
||||
}
|
||||
|
||||
return basic_pipe<CharT, Traits>{source, sink};
|
||||
@@ -360,6 +360,6 @@ inline bool operator!=(const basic_pipe<Char, Traits> & lhs, const async_pipe &
|
||||
!compare_handles(lhs.native_sink(), rhs.native_sink());
|
||||
}
|
||||
|
||||
}}}}}
|
||||
}}}}
|
||||
|
||||
#endif /* INCLUDE_BOOST_PIPE_DETAIL_WINDOWS_ASYNC_PIPE_HPP_ */
|
||||
@@ -7,11 +7,10 @@
|
||||
#ifndef BOOST_PROCESS_DETAIL_POSIX_BASIC_CMD_HPP_
|
||||
#define BOOST_PROCESS_DETAIL_POSIX_BASIC_CMD_HPP_
|
||||
|
||||
#include <boost/process/v1/detail/config.hpp>
|
||||
#include <boost/process/v1/detail/posix/handler.hpp>
|
||||
#include <boost/process/v1/detail/posix/cmd.hpp>
|
||||
#include <boost/process/detail/posix/handler.hpp>
|
||||
#include <boost/process/detail/posix/cmd.hpp>
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
#include <boost/process/v1/shell.hpp>
|
||||
#include <boost/process/shell.hpp>
|
||||
#include <boost/algorithm/string/trim.hpp>
|
||||
#include <boost/algorithm/string/join.hpp>
|
||||
#include <string>
|
||||
@@ -21,13 +20,12 @@ namespace boost
|
||||
{
|
||||
namespace process
|
||||
{
|
||||
BOOST_PROCESS_V1_INLINE namespace v1
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
namespace posix
|
||||
{
|
||||
|
||||
|
||||
inline std::string build_cmd_shell(const std::string & exe, std::vector<std::string> && data)
|
||||
{
|
||||
std::string st = exe;
|
||||
@@ -41,10 +39,10 @@ inline std::string build_cmd_shell(const std::string & exe, std::vector<std::str
|
||||
//the first one is put directly onto the output,
|
||||
//because then I don't have to copy the whole string
|
||||
arg.insert(arg.begin(), '"' );
|
||||
arg += '"'; //that is the post one.
|
||||
arg += '"'; //thats the post one.
|
||||
}
|
||||
|
||||
if (!st.empty())//first one does not need a preceding space
|
||||
if (!st.empty())//first one does not need a preceeding space
|
||||
st += ' ';
|
||||
|
||||
st += arg;
|
||||
@@ -103,7 +101,7 @@ template<typename Char>
|
||||
struct exe_cmd_init;
|
||||
|
||||
template<>
|
||||
struct exe_cmd_init<char> : boost::process::v1::detail::api::handler_base_ext
|
||||
struct exe_cmd_init<char> : boost::process::detail::api::handler_base_ext
|
||||
{
|
||||
exe_cmd_init(const exe_cmd_init & ) = delete;
|
||||
exe_cmd_init(exe_cmd_init && ) = default;
|
||||
@@ -114,10 +112,7 @@ struct exe_cmd_init<char> : boost::process::v1::detail::api::handler_base_ext
|
||||
{
|
||||
if (exe.empty()) //cmd style
|
||||
{
|
||||
if (args.empty())
|
||||
exec.exe = "";
|
||||
else
|
||||
exec.exe = args.front().c_str();
|
||||
exec.exe = args.front().c_str();
|
||||
exec.cmd_style = true;
|
||||
}
|
||||
else
|
||||
@@ -160,15 +155,13 @@ private:
|
||||
|
||||
std::vector<char*> exe_cmd_init<char>::make_cmd()
|
||||
{
|
||||
// any string must be writable.
|
||||
static char empty_string[1] = "";
|
||||
std::vector<char*> vec;
|
||||
if (!exe.empty())
|
||||
vec.push_back(exe.empty() ? empty_string : &exe.front());
|
||||
vec.push_back(&exe.front());
|
||||
|
||||
if (!args.empty()) {
|
||||
for (auto & v : args)
|
||||
vec.push_back(v.empty() ? empty_string : &v.front());
|
||||
vec.push_back(&v.front());
|
||||
}
|
||||
|
||||
vec.push_back(nullptr);
|
||||
@@ -177,6 +170,6 @@ std::vector<char*> exe_cmd_init<char>::make_cmd()
|
||||
}
|
||||
|
||||
|
||||
}}}}}
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
@@ -11,15 +11,15 @@
|
||||
#define BOOST_PROCESS_POSIX_PIPE_HPP
|
||||
|
||||
|
||||
#include <boost/process/v1/filesystem.hpp>
|
||||
#include <boost/process/v1/detail/posix/compare_handles.hpp>
|
||||
#include <boost/process/filesystem.hpp>
|
||||
#include <boost/process/detail/posix/compare_handles.hpp>
|
||||
#include <system_error>
|
||||
#include <array>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <memory>
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail { namespace posix {
|
||||
namespace boost { namespace process { namespace detail { namespace posix {
|
||||
|
||||
|
||||
template<class CharT, class Traits = std::char_traits<CharT>>
|
||||
@@ -41,7 +41,7 @@ public:
|
||||
{
|
||||
int fds[2];
|
||||
if (::pipe(fds) == -1)
|
||||
boost::process::v1::detail::throw_last_error("pipe(2) failed");
|
||||
boost::process::detail::throw_last_error("pipe(2) failed");
|
||||
|
||||
_source = fds[0];
|
||||
_sink = fds[1];
|
||||
@@ -77,29 +77,32 @@ public:
|
||||
void assign_source(native_handle_type h) { _source = h;}
|
||||
void assign_sink (native_handle_type h) { _sink = h;}
|
||||
|
||||
|
||||
|
||||
|
||||
int_type write(const char_type * data, int_type count)
|
||||
{
|
||||
ssize_t write_len;
|
||||
int_type write_len;
|
||||
while ((write_len = ::write(_sink, data, count * sizeof(char_type))) == -1)
|
||||
{
|
||||
//Try again if interrupted
|
||||
auto err = errno;
|
||||
if (err != EINTR)
|
||||
::boost::process::v1::detail::throw_last_error();
|
||||
::boost::process::detail::throw_last_error();
|
||||
}
|
||||
return static_cast<int_type>(write_len);
|
||||
return write_len;
|
||||
}
|
||||
int_type read(char_type * data, int_type count)
|
||||
{
|
||||
ssize_t read_len;
|
||||
while ((read_len = ::read(_source, data, count * sizeof(char_type))) == -1)
|
||||
int_type read_len;
|
||||
while ((read_len = static_cast<int_type>(::read(_source, data, count * sizeof(char_type)))) == -1)
|
||||
{
|
||||
//Try again if interrupted
|
||||
auto err = errno;
|
||||
if (err != EINTR)
|
||||
::boost::process::v1::detail::throw_last_error();
|
||||
::boost::process::detail::throw_last_error();
|
||||
}
|
||||
return static_cast<int_type>(read_len);
|
||||
return read_len;
|
||||
}
|
||||
|
||||
bool is_open() const
|
||||
@@ -126,13 +129,13 @@ basic_pipe<CharT, Traits>::basic_pipe(const basic_pipe & rhs)
|
||||
{
|
||||
_source = ::dup(rhs._source);
|
||||
if (_source == -1)
|
||||
::boost::process::v1::detail::throw_last_error("dup() failed");
|
||||
::boost::process::detail::throw_last_error("dup() failed");
|
||||
}
|
||||
if (rhs._sink != -1)
|
||||
{
|
||||
_sink = ::dup(rhs._sink);
|
||||
if (_sink == -1)
|
||||
::boost::process::v1::detail::throw_last_error("dup() failed");
|
||||
::boost::process::detail::throw_last_error("dup() failed");
|
||||
|
||||
}
|
||||
}
|
||||
@@ -144,13 +147,13 @@ basic_pipe<CharT, Traits> &basic_pipe<CharT, Traits>::operator=(const basic_pipe
|
||||
{
|
||||
_source = ::dup(rhs._source);
|
||||
if (_source == -1)
|
||||
::boost::process::v1::detail::throw_last_error("dup() failed");
|
||||
::boost::process::detail::throw_last_error("dup() failed");
|
||||
}
|
||||
if (rhs._sink != -1)
|
||||
{
|
||||
_sink = ::dup(rhs._sink);
|
||||
if (_sink == -1)
|
||||
::boost::process::v1::detail::throw_last_error("dup() failed");
|
||||
::boost::process::detail::throw_last_error("dup() failed");
|
||||
|
||||
}
|
||||
return *this;
|
||||
@@ -163,18 +166,18 @@ basic_pipe<CharT, Traits>::basic_pipe(const std::string & name)
|
||||
auto fifo = mkfifo(name.c_str(), 0666 );
|
||||
|
||||
if (fifo != 0)
|
||||
boost::process::v1::detail::throw_last_error("mkfifo() failed");
|
||||
boost::process::detail::throw_last_error("mkfifo() failed");
|
||||
|
||||
|
||||
int read_fd = open(name.c_str(), O_RDWR);
|
||||
|
||||
if (read_fd == -1)
|
||||
boost::process::v1::detail::throw_last_error();
|
||||
boost::process::detail::throw_last_error();
|
||||
|
||||
int write_fd = dup(read_fd);
|
||||
|
||||
if (write_fd == -1)
|
||||
boost::process::v1::detail::throw_last_error();
|
||||
boost::process::detail::throw_last_error();
|
||||
|
||||
_sink = write_fd;
|
||||
_source = read_fd;
|
||||
@@ -195,6 +198,6 @@ inline bool operator!=(const basic_pipe<Char, Traits> & lhs, const basic_pipe<Ch
|
||||
!compare_handles(lhs.native_sink(), rhs.native_sink());
|
||||
}
|
||||
|
||||
}}}}}
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
@@ -13,7 +13,7 @@
|
||||
#include <utility>
|
||||
#include <system_error>
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail { namespace posix {
|
||||
namespace boost { namespace process { namespace detail { namespace posix {
|
||||
|
||||
typedef ::pid_t pid_t;
|
||||
|
||||
@@ -55,6 +55,6 @@ struct child_handle
|
||||
}
|
||||
};
|
||||
|
||||
}}}}}
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
@@ -11,24 +11,24 @@
|
||||
#define BOOST_PROCESS_WINDOWS_INITIALIZERS_CLOSE_IN_HPP
|
||||
|
||||
|
||||
#include <boost/process/v1/detail/posix/handler.hpp>
|
||||
#include <boost/process/v1/detail/used_handles.hpp>
|
||||
#include <boost/process/detail/posix/handler.hpp>
|
||||
#include <boost/process/detail/used_handles.hpp>
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail { namespace posix {
|
||||
namespace boost { namespace process { namespace detail { namespace posix {
|
||||
|
||||
struct close_in : handler_base_ext, ::boost::process::v1::detail::uses_handles
|
||||
struct close_in : handler_base_ext, ::boost::process::detail::uses_handles
|
||||
{
|
||||
template <class Executor>
|
||||
void on_exec_setup(Executor &e) const
|
||||
{
|
||||
if (::close(STDIN_FILENO) == -1)
|
||||
e.set_error(::boost::process::v1::detail::get_last_error(), "close() failed");
|
||||
e.set_error(::boost::process::detail::get_last_error(), "close() failed");
|
||||
}
|
||||
|
||||
int get_used_handles() {return STDIN_FILENO;}
|
||||
|
||||
};
|
||||
|
||||
}}}}}
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
@@ -10,11 +10,11 @@
|
||||
#ifndef BOOST_PROCESS_DETAIL_POSIX_CLOSE_OUT_HPP
|
||||
#define BOOST_PROCESS_DETAIL_POSIX_CLOSE_OUT_HPP
|
||||
|
||||
#include <boost/process/v1/detail/used_handles.hpp>
|
||||
#include <boost/process/v1/detail/posix/handler.hpp>
|
||||
#include <boost/process/detail/used_handles.hpp>
|
||||
#include <boost/process/detail/posix/handler.hpp>
|
||||
#include <array>
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail { namespace posix {
|
||||
namespace boost { namespace process { namespace detail { namespace posix {
|
||||
|
||||
template<int p1, int p2>
|
||||
struct close_out : handler_base_ext
|
||||
@@ -30,7 +30,7 @@ template<typename Executor>
|
||||
void close_out<1,-1>::on_exec_setup(Executor &e) const
|
||||
{
|
||||
if (::close(STDOUT_FILENO) == -1)
|
||||
e.set_error(::boost::process::v1::detail::get_last_error(), "close() failed");
|
||||
e.set_error(::boost::process::detail::get_last_error(), "close() failed");
|
||||
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ template<typename Executor>
|
||||
void close_out<2,-1>::on_exec_setup(Executor &e) const
|
||||
{
|
||||
if (::close(STDERR_FILENO) == -1)
|
||||
e.set_error(::boost::process::v1::detail::get_last_error(), "close() failed");
|
||||
e.set_error(::boost::process::detail::get_last_error(), "close() failed");
|
||||
}
|
||||
|
||||
template<>
|
||||
@@ -47,12 +47,12 @@ template<typename Executor>
|
||||
void close_out<1,2>::on_exec_setup(Executor &e) const
|
||||
{
|
||||
if (::close(STDOUT_FILENO) == -1)
|
||||
e.set_error(::boost::process::v1::detail::get_last_error(), "close() failed");
|
||||
e.set_error(::boost::process::detail::get_last_error(), "close() failed");
|
||||
|
||||
if (::close(STDERR_FILENO) == -1)
|
||||
e.set_error(::boost::process::v1::detail::get_last_error(), "close() failed");
|
||||
e.set_error(::boost::process::detail::get_last_error(), "close() failed");
|
||||
}
|
||||
|
||||
}}}}}
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
@@ -7,8 +7,8 @@
|
||||
#ifndef BOOST_PROCESS_DETAIL_POSIX_CMD_HPP_
|
||||
#define BOOST_PROCESS_DETAIL_POSIX_CMD_HPP_
|
||||
|
||||
#include <boost/process/v1/detail/config.hpp>
|
||||
#include <boost/process/v1/detail/posix/handler.hpp>
|
||||
#include <boost/process/detail/config.hpp>
|
||||
#include <boost/process/detail/posix/handler.hpp>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -16,8 +16,6 @@ namespace boost
|
||||
{
|
||||
namespace process
|
||||
{
|
||||
BOOST_PROCESS_V1_INLINE namespace v1
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
namespace posix
|
||||
@@ -101,6 +99,6 @@ std::vector<Char*> cmd_setter_<Char>::make_cmd(std::vector<std::basic_string<Cha
|
||||
return vec;
|
||||
}
|
||||
|
||||
}}}}}
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
@@ -7,12 +7,12 @@
|
||||
#define BOOST_PROCESS_DETAIL_POSIX_COMPARE_HANDLES_HPP_
|
||||
|
||||
|
||||
#include <boost/process/v1/detail/config.hpp>
|
||||
#include <boost/process/detail/config.hpp>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail { namespace posix {
|
||||
namespace boost { namespace process { namespace detail { namespace posix {
|
||||
|
||||
|
||||
inline bool compare_handles(int lhs, int rhs)
|
||||
@@ -25,8 +25,8 @@ inline bool compare_handles(int lhs, int rhs)
|
||||
return true;
|
||||
|
||||
struct stat stat1, stat2;
|
||||
if(fstat(lhs, &stat1) < 0) ::boost::process::v1::detail::throw_last_error("fstat() failed");
|
||||
if(fstat(rhs, &stat2) < 0) ::boost::process::v1::detail::throw_last_error("fstat() failed");
|
||||
if(fstat(lhs, &stat1) < 0) ::boost::process::detail::throw_last_error("fstat() failed");
|
||||
if(fstat(rhs, &stat2) < 0) ::boost::process::detail::throw_last_error("fstat() failed");
|
||||
|
||||
return (stat1.st_dev == stat2.st_dev) && (stat1.st_ino == stat2.st_ino);
|
||||
}
|
||||
@@ -35,7 +35,7 @@ inline bool compare_handles(int lhs, int rhs)
|
||||
|
||||
|
||||
|
||||
}}}}}
|
||||
}}}}
|
||||
|
||||
|
||||
|
||||
@@ -8,11 +8,11 @@
|
||||
#define BOOST_PROCESS_DETAIL_POSIX_ENV_INIT_HPP_
|
||||
|
||||
|
||||
#include <boost/process/v1/detail/config.hpp>
|
||||
#include <boost/process/v1/detail/posix/handler.hpp>
|
||||
#include <boost/process/v1/environment.hpp>
|
||||
#include <boost/process/detail/config.hpp>
|
||||
#include <boost/process/detail/posix/handler.hpp>
|
||||
#include <boost/process/environment.hpp>
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail { namespace posix {
|
||||
namespace boost { namespace process { namespace detail { namespace posix {
|
||||
|
||||
template<typename Char>
|
||||
struct env_init;
|
||||
@@ -20,10 +20,10 @@ struct env_init;
|
||||
template<>
|
||||
struct env_init<char> : handler_base_ext
|
||||
{
|
||||
boost::process::v1::environment env;
|
||||
boost::process::environment env;
|
||||
|
||||
env_init(boost::process::v1::environment && env) : env(std::move(env)) {};
|
||||
env_init(const boost::process::v1::environment & env) : env(env) {};
|
||||
env_init(boost::process::environment && env) : env(std::move(env)) {};
|
||||
env_init(const boost::process::environment & env) : env(env) {};
|
||||
|
||||
|
||||
template <class Executor>
|
||||
@@ -34,7 +34,7 @@ struct env_init<char> : handler_base_ext
|
||||
|
||||
};
|
||||
|
||||
}}}}}
|
||||
}}}}
|
||||
|
||||
|
||||
|
||||
@@ -9,13 +9,13 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <boost/process/v1/detail/config.hpp>
|
||||
#include <boost/process/detail/config.hpp>
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <boost/process/v1/locale.hpp>
|
||||
#include <boost/process/locale.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail { namespace posix {
|
||||
namespace boost { namespace process { namespace detail { namespace posix {
|
||||
|
||||
template<typename Char>
|
||||
class native_environment_impl
|
||||
@@ -27,7 +27,7 @@ class native_environment_impl
|
||||
while (*p != nullptr)
|
||||
{
|
||||
std::string str = *p;
|
||||
val.push_back(::boost::process::v1::detail::convert(str));
|
||||
val.push_back(::boost::process::detail::convert(str));
|
||||
p++;
|
||||
}
|
||||
return val;
|
||||
@@ -68,24 +68,24 @@ public:
|
||||
|
||||
string_type get(const string_type & id)
|
||||
{
|
||||
std::string id_c = ::boost::process::v1::detail::convert(id);
|
||||
std::string id_c = ::boost::process::detail::convert(id);
|
||||
std::string g = ::getenv(id_c.c_str());
|
||||
return ::boost::process::v1::detail::convert(g.c_str());
|
||||
return ::boost::process::detail::convert(g.c_str());
|
||||
}
|
||||
void set(const string_type & id, const string_type & value)
|
||||
{
|
||||
std::string id_c = ::boost::process::v1::detail::convert(id.c_str());
|
||||
std::string value_c = ::boost::process::v1::detail::convert(value.c_str());
|
||||
std::string id_c = ::boost::process::detail::convert(id.c_str());
|
||||
std::string value_c = ::boost::process::detail::convert(value.c_str());
|
||||
auto res = ::setenv(id_c.c_str(), value_c.c_str(), true);
|
||||
if (res != 0)
|
||||
boost::process::v1::detail::throw_last_error();
|
||||
boost::process::detail::throw_last_error();
|
||||
}
|
||||
void reset(const string_type & id)
|
||||
{
|
||||
std::string id_c = ::boost::process::v1::detail::convert(id.c_str());
|
||||
std::string id_c = ::boost::process::detail::convert(id.c_str());
|
||||
auto res = ::unsetenv(id_c.c_str());
|
||||
if (res != 0)
|
||||
::boost::process::v1::detail::throw_last_error();
|
||||
::boost::process::detail::throw_last_error();
|
||||
}
|
||||
|
||||
native_environment_impl() = default;
|
||||
@@ -114,14 +114,14 @@ public:
|
||||
{
|
||||
auto res = ::setenv(id, value, 1);
|
||||
if (res != 0)
|
||||
boost::process::v1::detail::throw_last_error();
|
||||
boost::process::detail::throw_last_error();
|
||||
reload();
|
||||
}
|
||||
void reset(const pointer_type id)
|
||||
{
|
||||
auto res = ::unsetenv(id);
|
||||
if (res != 0)
|
||||
boost::process::v1::detail::throw_last_error();
|
||||
boost::process::detail::throw_last_error();
|
||||
reload();
|
||||
}
|
||||
|
||||
@@ -186,13 +186,13 @@ public:
|
||||
template<typename CharR>
|
||||
explicit inline basic_environment_impl(
|
||||
const basic_environment_impl<CharR>& rhs,
|
||||
const ::boost::process::v1::codecvt_type & cv = ::boost::process::v1::codecvt())
|
||||
const ::boost::process::codecvt_type & cv = ::boost::process::codecvt())
|
||||
: _data(rhs._data.size())
|
||||
{
|
||||
std::transform(rhs._data.begin(), rhs._data.end(), _data.begin(),
|
||||
[&](const std::basic_string<CharR> & st)
|
||||
{
|
||||
return ::boost::process::v1::detail::convert(st, cv);
|
||||
return ::boost::process::detail::convert(st, cv);
|
||||
}
|
||||
|
||||
);
|
||||
@@ -202,7 +202,7 @@ public:
|
||||
template<typename CharR>
|
||||
basic_environment_impl & operator=(const basic_environment_impl<CharR>& rhs)
|
||||
{
|
||||
_data = ::boost::process::v1::detail::convert(rhs._data);
|
||||
_data = ::boost::process::detail::convert(rhs._data);
|
||||
_env_arr = _load_var(&*_data.begin());
|
||||
_env_impl = &*_env_arr.begin();
|
||||
return *this;
|
||||
@@ -230,7 +230,7 @@ basic_environment_impl<Char>::basic_environment_impl(const native_environment_im
|
||||
template<typename Char>
|
||||
inline auto basic_environment_impl<Char>::get(const string_type &id) -> string_type
|
||||
{
|
||||
auto itr = std::find_if(_data.begin(), _data.end(),
|
||||
auto itr = std::find_if(_data.begin(), _data.end(),
|
||||
[&](const string_type & st) -> bool
|
||||
{
|
||||
if (st.size() <= id.size())
|
||||
@@ -250,7 +250,7 @@ inline auto basic_environment_impl<Char>::get(const string_type &id) -> string_t
|
||||
template<typename Char>
|
||||
inline void basic_environment_impl<Char>::set(const string_type &id, const string_type &value)
|
||||
{
|
||||
auto itr = std::find_if(_data.begin(), _data.end(),
|
||||
auto itr = std::find_if(_data.begin(), _data.end(),
|
||||
[&](const string_type & st) -> bool
|
||||
{
|
||||
if (st.size() <= id.size())
|
||||
@@ -261,7 +261,7 @@ inline void basic_environment_impl<Char>::set(const string_type &id, const strin
|
||||
|
||||
if (itr != _data.end())
|
||||
*itr = id + equal_sign<Char>() + value;
|
||||
else
|
||||
else
|
||||
_data.push_back(id + equal_sign<Char>() + value);
|
||||
|
||||
reload();
|
||||
@@ -270,7 +270,7 @@ inline void basic_environment_impl<Char>::set(const string_type &id, const strin
|
||||
template<typename Char>
|
||||
inline void basic_environment_impl<Char>::reset(const string_type &id)
|
||||
{
|
||||
auto itr = std::find_if(_data.begin(), _data.end(),
|
||||
auto itr = std::find_if(_data.begin(), _data.end(),
|
||||
[&](const string_type & st) -> bool
|
||||
{
|
||||
if (st.size() <= id.size())
|
||||
@@ -280,9 +280,9 @@ inline void basic_environment_impl<Char>::reset(const string_type &id)
|
||||
);
|
||||
if (itr != _data.end())
|
||||
{
|
||||
_data.erase(itr);//and remove it
|
||||
_data.erase(itr);//and remove it
|
||||
}
|
||||
|
||||
|
||||
reload();
|
||||
|
||||
|
||||
@@ -320,7 +320,7 @@ inline int native_handle() {return getpid(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -7,14 +7,11 @@
|
||||
#ifndef BOOST_PROCESS_DETAIL_POSIX_EXE_HPP_
|
||||
#define BOOST_PROCESS_DETAIL_POSIX_EXE_HPP_
|
||||
|
||||
#include <boost/process/v1/detail/config.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace process
|
||||
{
|
||||
BOOST_PROCESS_V1_INLINE namespace v1
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
namespace posix
|
||||
@@ -33,7 +30,7 @@ inline void apply_exe(const StringType & exe, Executor & e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* INCLUDE_BOOST_PROCESS_WINDOWS_ARGS_HPP_ */
|
||||
@@ -10,11 +10,11 @@
|
||||
#ifndef BOOST_PROCESS_DETAIL_POSIX_EXECUTOR_HPP
|
||||
#define BOOST_PROCESS_DETAIL_POSIX_EXECUTOR_HPP
|
||||
|
||||
#include <boost/process/v1/detail/child_decl.hpp>
|
||||
#include <boost/process/v1/error.hpp>
|
||||
#include <boost/process/v1/pipe.hpp>
|
||||
#include <boost/process/v1/detail/posix/basic_pipe.hpp>
|
||||
#include <boost/process/v1/detail/posix/use_vfork.hpp>
|
||||
#include <boost/process/detail/child_decl.hpp>
|
||||
#include <boost/process/error.hpp>
|
||||
#include <boost/process/pipe.hpp>
|
||||
#include <boost/process/detail/posix/basic_pipe.hpp>
|
||||
#include <boost/process/detail/posix/use_vfork.hpp>
|
||||
#include <boost/fusion/algorithm/iteration/for_each.hpp>
|
||||
#include <cstdlib>
|
||||
#include <sys/types.h>
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
#include <boost/core/ignore_unused.hpp>
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail { namespace posix {
|
||||
namespace boost { namespace process { namespace detail { namespace posix {
|
||||
|
||||
template<typename Executor>
|
||||
struct on_setup_t
|
||||
@@ -204,9 +204,9 @@ class executor
|
||||
throw process_error(_ec, _msg);
|
||||
}
|
||||
|
||||
typedef typename ::boost::process::v1::detail::has_error_handler<Sequence>::type has_error_handler;
|
||||
typedef typename ::boost::process::v1::detail::has_ignore_error <Sequence>::type has_ignore_error;
|
||||
typedef typename ::boost::process::v1::detail::posix::shall_use_vfork<Sequence>::type shall_use_vfork;
|
||||
typedef typename ::boost::process::detail::has_error_handler<Sequence>::type has_error_handler;
|
||||
typedef typename ::boost::process::detail::has_ignore_error <Sequence>::type has_ignore_error;
|
||||
typedef typename ::boost::process::detail::posix::shall_use_vfork<Sequence>::type shall_use_vfork;
|
||||
|
||||
inline child invoke(boost::mpl::true_ , boost::mpl::true_ );
|
||||
inline child invoke(boost::mpl::false_, boost::mpl::true_ );
|
||||
@@ -349,7 +349,7 @@ child executor<Sequence>::invoke(boost::mpl::true_, boost::mpl::false_) //ignore
|
||||
this->pid = ::fork();
|
||||
if (pid == -1)
|
||||
{
|
||||
auto ec = boost::process::v1::detail::get_last_error();
|
||||
auto ec = boost::process::detail::get_last_error();
|
||||
boost::fusion::for_each(seq, call_on_fork_error(*this, ec));
|
||||
return child();
|
||||
}
|
||||
@@ -357,7 +357,7 @@ child executor<Sequence>::invoke(boost::mpl::true_, boost::mpl::false_) //ignore
|
||||
{
|
||||
boost::fusion::for_each(seq, call_on_exec_setup(*this));
|
||||
::execve(exe, cmd_line, env);
|
||||
auto ec = boost::process::v1::detail::get_last_error();
|
||||
auto ec = boost::process::detail::get_last_error();
|
||||
boost::fusion::for_each(seq, call_on_exec_error(*this, ec));
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
@@ -389,25 +389,21 @@ child executor<Sequence>::invoke(boost::mpl::false_, boost::mpl::false_)
|
||||
|
||||
if (::pipe(p.p) == -1)
|
||||
{
|
||||
set_error(::boost::process::v1::detail::get_last_error(), "pipe(2) failed");
|
||||
set_error(::boost::process::detail::get_last_error(), "pipe(2) failed");
|
||||
return child();
|
||||
}
|
||||
if (::fcntl(p.p[1], F_SETFD, FD_CLOEXEC) == -1)
|
||||
{
|
||||
auto err = ::boost::process::v1::detail::get_last_error();
|
||||
auto err = ::boost::process::detail::get_last_error();
|
||||
set_error(err, "fcntl(2) failed");//this might throw, so we need to be sure our pipe is safe.
|
||||
return child();
|
||||
}
|
||||
|
||||
_pipe_sink = p.p[1];
|
||||
|
||||
_ec.clear();
|
||||
boost::fusion::for_each(seq, call_on_setup(*this));
|
||||
|
||||
if (_ec)
|
||||
{
|
||||
boost::fusion::for_each(seq, call_on_error(*this, _ec));
|
||||
_pipe_sink = -1;
|
||||
return child();
|
||||
}
|
||||
|
||||
@@ -417,20 +413,20 @@ child executor<Sequence>::invoke(boost::mpl::false_, boost::mpl::false_)
|
||||
this->pid = ::fork();
|
||||
if (pid == -1)
|
||||
{
|
||||
_ec = boost::process::v1::detail::get_last_error();
|
||||
_ec = boost::process::detail::get_last_error();
|
||||
_msg = "fork() failed";
|
||||
boost::fusion::for_each(seq, call_on_fork_error(*this, _ec));
|
||||
boost::fusion::for_each(seq, call_on_error(*this, _ec));
|
||||
_pipe_sink = -1;
|
||||
return child();
|
||||
}
|
||||
else if (pid == 0)
|
||||
{
|
||||
_pipe_sink = p.p[1];
|
||||
::close(p.p[0]);
|
||||
|
||||
boost::fusion::for_each(seq, call_on_exec_setup(*this));
|
||||
::execve(exe, cmd_line, env);
|
||||
_ec = boost::process::v1::detail::get_last_error();
|
||||
_ec = boost::process::detail::get_last_error();
|
||||
_msg = "execve failed";
|
||||
boost::fusion::for_each(seq, call_on_exec_error(*this, _ec));
|
||||
|
||||
@@ -443,13 +439,12 @@ child executor<Sequence>::invoke(boost::mpl::false_, boost::mpl::false_)
|
||||
|
||||
::close(p.p[1]);
|
||||
p.p[1] = -1;
|
||||
_pipe_sink = -1;
|
||||
_read_error(p.p[0]);
|
||||
|
||||
}
|
||||
if (_ec)
|
||||
{
|
||||
//if an error occurred we need to reap the child process
|
||||
//if an error occured we need to reap the child process
|
||||
::waitpid(this->pid, nullptr, WNOHANG);
|
||||
boost::fusion::for_each(seq, call_on_error(*this, _ec));
|
||||
return child();
|
||||
@@ -480,7 +475,7 @@ child executor<Sequence>::invoke(boost::mpl::true_, boost::mpl::true_) //ignore
|
||||
this->pid = ::vfork();
|
||||
if (pid == -1)
|
||||
{
|
||||
auto ec = boost::process::v1::detail::get_last_error();
|
||||
auto ec = boost::process::detail::get_last_error();
|
||||
boost::fusion::for_each(seq, call_on_fork_error(*this, ec));
|
||||
return child();
|
||||
}
|
||||
@@ -488,7 +483,7 @@ child executor<Sequence>::invoke(boost::mpl::true_, boost::mpl::true_) //ignore
|
||||
{
|
||||
boost::fusion::for_each(seq, call_on_exec_setup(*this));
|
||||
::execve(exe, cmd_line, env);
|
||||
auto ec = boost::process::v1::detail::get_last_error();
|
||||
auto ec = boost::process::detail::get_last_error();
|
||||
boost::fusion::for_each(seq, call_on_exec_error(*this, ec));
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
@@ -516,7 +511,7 @@ child executor<Sequence>::invoke(boost::mpl::false_, boost::mpl::true_)
|
||||
this->pid = ::vfork();
|
||||
if (pid == -1)
|
||||
{
|
||||
_ec = boost::process::v1::detail::get_last_error();
|
||||
_ec = boost::process::detail::get_last_error();
|
||||
_msg = "fork() failed";
|
||||
boost::fusion::for_each(seq, call_on_fork_error(*this, _ec));
|
||||
boost::fusion::for_each(seq, call_on_error(*this, _ec));
|
||||
@@ -529,7 +524,7 @@ child executor<Sequence>::invoke(boost::mpl::false_, boost::mpl::true_)
|
||||
|
||||
::execve(exe, cmd_line, env);
|
||||
|
||||
_ec = boost::process::v1::detail::get_last_error();
|
||||
_ec = boost::process::detail::get_last_error();
|
||||
_msg = "execve failed";
|
||||
boost::fusion::for_each(seq, call_on_exec_error(*this, _ec));
|
||||
|
||||
@@ -568,6 +563,6 @@ inline executor<Tup> make_executor(Tup & tup)
|
||||
return executor<Tup>(tup);
|
||||
}
|
||||
|
||||
}}}}}
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
@@ -10,15 +10,15 @@
|
||||
#ifndef BOOST_PROCESS_DETAIL_POSIX_FD_HPP
|
||||
#define BOOST_PROCESS_DETAIL_POSIX_FD_HPP
|
||||
|
||||
#include <boost/process/v1/detail/posix/handler.hpp>
|
||||
#include <boost/process/detail/posix/handler.hpp>
|
||||
#include <unistd.h>
|
||||
#include <boost/process/v1/detail/used_handles.hpp>
|
||||
#include <boost/process/detail/used_handles.hpp>
|
||||
#include <array>
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail { namespace posix {
|
||||
namespace boost { namespace process { namespace detail { namespace posix {
|
||||
|
||||
|
||||
struct close_fd_ : handler_base_ext, ::boost::process::v1::detail::uses_handles
|
||||
struct close_fd_ : handler_base_ext, ::boost::process::detail::uses_handles
|
||||
{
|
||||
close_fd_(int fd) : fd_(fd) {}
|
||||
|
||||
@@ -26,7 +26,7 @@ struct close_fd_ : handler_base_ext, ::boost::process::v1::detail::uses_handles
|
||||
void on_exec_setup(PosixExecutor& e) const
|
||||
{
|
||||
if (::close(fd_) == -1)
|
||||
e.set_error(::boost::process::v1::detail::get_last_error(), "close() failed");
|
||||
e.set_error(::boost::process::detail::get_last_error(), "close() failed");
|
||||
}
|
||||
|
||||
int get_used_handles() {return fd_;}
|
||||
@@ -37,7 +37,7 @@ private:
|
||||
};
|
||||
|
||||
template <class Range>
|
||||
struct close_fds_ : handler_base_ext, ::boost::process::v1::detail::uses_handles
|
||||
struct close_fds_ : handler_base_ext, ::boost::process::detail::uses_handles
|
||||
{
|
||||
public:
|
||||
close_fds_(const Range &fds) : fds_(fds) {}
|
||||
@@ -48,7 +48,7 @@ public:
|
||||
for (auto & fd_ : fds_)
|
||||
if (::close(fd_) == -1)
|
||||
{
|
||||
e.set_error(::boost::process::v1::detail::get_last_error(), "close() failed");
|
||||
e.set_error(::boost::process::detail::get_last_error(), "close() failed");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -62,7 +62,7 @@ private:
|
||||
|
||||
|
||||
template <class FileDescriptor>
|
||||
struct bind_fd_ : handler_base_ext, ::boost::process::v1::detail::uses_handles
|
||||
struct bind_fd_ : handler_base_ext, ::boost::process::detail::uses_handles
|
||||
{
|
||||
public:
|
||||
bind_fd_(int id, const FileDescriptor &fd) : id_(id), fd_(fd) {}
|
||||
@@ -71,7 +71,7 @@ public:
|
||||
void on_exec_setup(PosixExecutor& e) const
|
||||
{
|
||||
if (::dup2(fd_, id_) == -1)
|
||||
e.set_error(::boost::process::v1::detail::get_last_error(), "dup2() failed");
|
||||
e.set_error(::boost::process::detail::get_last_error(), "dup2() failed");
|
||||
}
|
||||
|
||||
std::array<int, 2> get_used_handles() {return {id_, fd_};}
|
||||
@@ -97,6 +97,6 @@ struct fd_
|
||||
};
|
||||
|
||||
|
||||
}}}}}
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
@@ -8,10 +8,10 @@
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <string>
|
||||
#include <boost/process/v1/filesystem.hpp>
|
||||
#include <boost/process/filesystem.hpp>
|
||||
#include <boost/core/exchange.hpp>
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail { namespace posix {
|
||||
namespace boost { namespace process { namespace detail { namespace posix {
|
||||
|
||||
struct file_descriptor
|
||||
{
|
||||
@@ -24,7 +24,7 @@ struct file_descriptor
|
||||
|
||||
|
||||
file_descriptor() = default;
|
||||
explicit file_descriptor(const boost::process::v1::filesystem::path& p, mode_t mode = read_write)
|
||||
explicit file_descriptor(const boost::process::filesystem::path& p, mode_t mode = read_write)
|
||||
: file_descriptor(p.native(), mode)
|
||||
{
|
||||
}
|
||||
@@ -84,6 +84,6 @@ private:
|
||||
int _handle = -1;
|
||||
};
|
||||
|
||||
}}}}}
|
||||
}}}}
|
||||
|
||||
#endif /* BOOST_PROCESS_DETAIL_WINDOWS_FILE_DESCRIPTOR_HPP_ */
|
||||
@@ -10,16 +10,16 @@
|
||||
#ifndef BOOST_PROCESS_DETAIL_POSIX_FILE_IN_HPP
|
||||
#define BOOST_PROCESS_DETAIL_POSIX_FILE_IN_HPP
|
||||
|
||||
#include <boost/process/v1/pipe.hpp>
|
||||
#include <boost/process/v1/detail/posix/handler.hpp>
|
||||
#include <boost/process/v1/detail/posix/file_descriptor.hpp>
|
||||
#include <boost/process/v1/detail/used_handles.hpp>
|
||||
#include <boost/process/pipe.hpp>
|
||||
#include <boost/process/detail/posix/handler.hpp>
|
||||
#include <boost/process/detail/posix/file_descriptor.hpp>
|
||||
#include <boost/process/detail/used_handles.hpp>
|
||||
#include <cstdio>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail { namespace posix {
|
||||
namespace boost { namespace process { namespace detail { namespace posix {
|
||||
|
||||
struct file_in : handler_base_ext, ::boost::process::v1::detail::uses_handles
|
||||
struct file_in : handler_base_ext, ::boost::process::detail::uses_handles
|
||||
{
|
||||
file_descriptor file;
|
||||
int handle = file.handle();
|
||||
@@ -37,10 +37,10 @@ struct file_in : handler_base_ext, ::boost::process::v1::detail::uses_handles
|
||||
void on_exec_setup(WindowsExecutor &e) const
|
||||
{
|
||||
if (::dup2(handle, STDIN_FILENO) == -1)
|
||||
e.set_error(::boost::process::v1::detail::get_last_error(), "dup2() failed");
|
||||
e.set_error(::boost::process::detail::get_last_error(), "dup2() failed");
|
||||
}
|
||||
};
|
||||
|
||||
}}}}}
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
@@ -11,15 +11,15 @@
|
||||
#ifndef BOOST_PROCESS_POSIX_FILE_OUT_HPP
|
||||
#define BOOST_PROCESS_POSIX_FILE_OUT_HPP
|
||||
|
||||
#include <boost/process/v1/detail/posix/handler.hpp>
|
||||
#include <boost/process/v1/detail/posix/file_descriptor.hpp>
|
||||
#include <boost/process/v1/detail/used_handles.hpp>
|
||||
#include <boost/process/detail/posix/handler.hpp>
|
||||
#include <boost/process/detail/posix/file_descriptor.hpp>
|
||||
#include <boost/process/detail/used_handles.hpp>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail { namespace posix {
|
||||
namespace boost { namespace process { namespace detail { namespace posix {
|
||||
|
||||
template<int p1, int p2>
|
||||
struct file_out : handler_base_ext, ::boost::process::v1::detail::uses_handles
|
||||
struct file_out : handler_base_ext, ::boost::process::detail::uses_handles
|
||||
{
|
||||
file_descriptor file;
|
||||
int handle = file.handle();
|
||||
@@ -45,7 +45,7 @@ template<typename Executor>
|
||||
void file_out<1,-1>::on_exec_setup(Executor &e) const
|
||||
{
|
||||
if (::dup2(handle, STDOUT_FILENO) == -1)
|
||||
e.set_error(::boost::process::v1::detail::get_last_error(), "dup2() failed");
|
||||
e.set_error(::boost::process::detail::get_last_error(), "dup2() failed");
|
||||
}
|
||||
|
||||
template<>
|
||||
@@ -53,7 +53,7 @@ template<typename Executor>
|
||||
void file_out<2,-1>::on_exec_setup(Executor &e) const
|
||||
{
|
||||
if (::dup2(handle, STDERR_FILENO) == -1)
|
||||
e.set_error(::boost::process::v1::detail::get_last_error(), "dup2() failed");
|
||||
e.set_error(::boost::process::detail::get_last_error(), "dup2() failed");
|
||||
}
|
||||
|
||||
template<>
|
||||
@@ -61,13 +61,13 @@ template<typename Executor>
|
||||
void file_out<1,2>::on_exec_setup(Executor &e) const
|
||||
{
|
||||
if (::dup2(handle, STDOUT_FILENO) == -1)
|
||||
e.set_error(::boost::process::v1::detail::get_last_error(), "dup2() failed");
|
||||
e.set_error(::boost::process::detail::get_last_error(), "dup2() failed");
|
||||
|
||||
if (::dup2(handle, STDERR_FILENO) == -1)
|
||||
e.set_error(::boost::process::v1::detail::get_last_error(), "dup2() failed");
|
||||
e.set_error(::boost::process::detail::get_last_error(), "dup2() failed");
|
||||
|
||||
}
|
||||
|
||||
}}}}}
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
@@ -6,12 +6,12 @@
|
||||
#ifndef BOOST_PROCESS_DETAIL_POSIX_GROUP_HPP_
|
||||
#define BOOST_PROCESS_DETAIL_POSIX_GROUP_HPP_
|
||||
|
||||
#include <boost/process/v1/detail/config.hpp>
|
||||
#include <boost/process/v1/detail/posix/child_handle.hpp>
|
||||
#include <boost/process/detail/config.hpp>
|
||||
#include <boost/process/detail/posix/child_handle.hpp>
|
||||
#include <system_error>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail { namespace posix {
|
||||
namespace boost { namespace process { namespace detail { namespace posix {
|
||||
|
||||
struct group_handle
|
||||
{
|
||||
@@ -70,7 +70,7 @@ struct group_handle
|
||||
inline void terminate(group_handle &p, std::error_code &ec) noexcept
|
||||
{
|
||||
if (::killpg(p.grp, SIGKILL) == -1)
|
||||
ec = boost::process::v1::detail::get_last_error();
|
||||
ec = boost::process::detail::get_last_error();
|
||||
else
|
||||
ec.clear();
|
||||
|
||||
@@ -81,7 +81,7 @@ inline void terminate(group_handle &p)
|
||||
{
|
||||
std::error_code ec;
|
||||
terminate(p, ec);
|
||||
boost::process::v1::detail::throw_error(ec, "killpg(2) failed in terminate");
|
||||
boost::process::detail::throw_error(ec, "killpg(2) failed in terminate");
|
||||
}
|
||||
|
||||
inline bool in_group()
|
||||
@@ -89,6 +89,6 @@ inline bool in_group()
|
||||
return true;
|
||||
}
|
||||
|
||||
}}}}}
|
||||
}}}}
|
||||
|
||||
#endif /* BOOST_PROCESS_DETAIL_WINDOWS_GROUP_HPP_ */
|
||||
@@ -6,13 +6,13 @@
|
||||
#ifndef BOOST_PROCESS_DETAIL_POSIX_GROUP_REF_HPP_
|
||||
#define BOOST_PROCESS_DETAIL_POSIX_GROUP_REF_HPP_
|
||||
|
||||
#include <boost/process/v1/detail/config.hpp>
|
||||
#include <boost/process/v1/detail/posix/group_handle.hpp>
|
||||
#include <boost/process/v1/detail/posix/handler.hpp>
|
||||
#include <boost/process/detail/config.hpp>
|
||||
#include <boost/process/detail/posix/group_handle.hpp>
|
||||
#include <boost/process/detail/posix/handler.hpp>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 {
|
||||
namespace boost { namespace process {
|
||||
|
||||
namespace detail { namespace posix {
|
||||
|
||||
@@ -46,7 +46,7 @@ struct group_ref : handler_base_ext
|
||||
|
||||
};
|
||||
|
||||
}}}}}
|
||||
}}}}
|
||||
|
||||
|
||||
#endif /* BOOST_PROCESS_DETAIL_POSIX_GROUP_REF_HPP_ */
|
||||
@@ -6,9 +6,9 @@
|
||||
#ifndef BOOST_PROCESS_DETAIL_POSIX_HANDLER_HPP_
|
||||
#define BOOST_PROCESS_DETAIL_POSIX_HANDLER_HPP_
|
||||
|
||||
#include <boost/process/v1/detail/handler_base.hpp>
|
||||
#include <boost/process/detail/handler_base.hpp>
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail { namespace posix {
|
||||
namespace boost { namespace process { namespace detail { namespace posix {
|
||||
|
||||
//does not extend anything.
|
||||
struct handler_base_ext : handler_base
|
||||
@@ -67,7 +67,7 @@ private:
|
||||
Handler handler_;
|
||||
};
|
||||
|
||||
}}}}}
|
||||
}}}}
|
||||
|
||||
|
||||
|
||||
@@ -13,9 +13,9 @@
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <cstdlib>
|
||||
#include <boost/process/v1/detail/posix/handler.hpp>
|
||||
#include <boost/process/detail/posix/handler.hpp>
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail { namespace posix {
|
||||
namespace boost { namespace process { namespace detail { namespace posix {
|
||||
|
||||
|
||||
using native_handle_type = int;
|
||||
@@ -27,13 +27,13 @@ inline std::vector<native_handle_type> get_handles(std::error_code & ec)
|
||||
std::unique_ptr<DIR, void(*)(DIR*)> dir{::opendir("/dev/fd"), +[](DIR* p){::closedir(p);}};
|
||||
if (!dir)
|
||||
{
|
||||
ec = ::boost::process::v1::detail::get_last_error();
|
||||
ec = ::boost::process::detail::get_last_error();
|
||||
return {};
|
||||
}
|
||||
else
|
||||
ec.clear();
|
||||
|
||||
auto my_fd = dirfd(dir.get());
|
||||
auto my_fd = ::dirfd(dir.get());
|
||||
|
||||
struct ::dirent * ent_p;
|
||||
|
||||
@@ -60,7 +60,7 @@ inline std::vector<native_handle_type> get_handles()
|
||||
|
||||
auto res = get_handles(ec);
|
||||
if (ec)
|
||||
boost::process::v1::detail::throw_error(ec, "open_dir(\"/dev/fd\") failed");
|
||||
boost::process::detail::throw_error(ec, "open_dir(\"/dev/fd\") failed");
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -72,7 +72,7 @@ inline bool is_stream_handle(native_handle_type handle, std::error_code & ec)
|
||||
|
||||
if (::fstat(handle, &stat_) != 0)
|
||||
{
|
||||
ec = ::boost::process::v1::detail::get_last_error();
|
||||
ec = ::boost::process::detail::get_last_error();
|
||||
}
|
||||
else
|
||||
ec.clear();
|
||||
@@ -90,7 +90,7 @@ inline bool is_stream_handle(native_handle_type handle)
|
||||
std::error_code ec;
|
||||
auto res = is_stream_handle(handle, ec);
|
||||
if (ec)
|
||||
boost::process::v1::detail::throw_error(ec, "fstat() failed");
|
||||
boost::process::detail::throw_error(ec, "fstat() failed");
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -113,11 +113,11 @@ struct limit_handles_ : handler_base_ext
|
||||
auto dir = ::opendir("/dev/fd");
|
||||
if (!dir)
|
||||
{
|
||||
exec.set_error(::boost::process::v1::detail::get_last_error(), "opendir(\"/dev/fd\")");
|
||||
exec.set_error(::boost::process::detail::get_last_error(), "opendir(\"/dev/fd\")");
|
||||
return;
|
||||
}
|
||||
|
||||
auto my_fd = dirfd(dir);
|
||||
auto my_fd = ::dirfd(dir);
|
||||
struct ::dirent * ent_p;
|
||||
|
||||
while ((ent_p = readdir(dir)) != nullptr)
|
||||
@@ -135,7 +135,7 @@ struct limit_handles_ : handler_base_ext
|
||||
|
||||
if (::close(conv) != 0)
|
||||
{
|
||||
exec.set_error(::boost::process::v1::detail::get_last_error(), "close() failed");
|
||||
exec.set_error(::boost::process::detail::get_last_error(), "close() failed");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -143,6 +143,6 @@ struct limit_handles_ : handler_base_ext
|
||||
}
|
||||
};
|
||||
|
||||
}}}}}
|
||||
}}}}
|
||||
|
||||
#endif //PROCESS_HANDLES_HPP
|
||||
@@ -6,8 +6,8 @@
|
||||
#ifndef BOOST_PROCESS_POSIX_IO_CONTEXT_REF_HPP_
|
||||
#define BOOST_PROCESS_POSIX_IO_CONTEXT_REF_HPP_
|
||||
|
||||
#include <boost/process/v1/detail/posix/handler.hpp>
|
||||
#include <boost/process/v1/detail/posix/async_handler.hpp>
|
||||
#include <boost/process/detail/posix/handler.hpp>
|
||||
#include <boost/process/detail/posix/async_handler.hpp>
|
||||
#include <boost/asio/io_context.hpp>
|
||||
|
||||
#include <boost/fusion/algorithm/iteration/for_each.hpp>
|
||||
@@ -17,8 +17,8 @@
|
||||
#include <boost/fusion/container/vector/convert.hpp>
|
||||
|
||||
|
||||
#include <boost/process/v1/detail/posix/sigchld_service.hpp>
|
||||
#include <boost/process/v1/detail/posix/is_running.hpp>
|
||||
#include <boost/process/detail/posix/sigchld_service.hpp>
|
||||
#include <boost/process/detail/posix/is_running.hpp>
|
||||
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
@@ -26,7 +26,7 @@
|
||||
#include <vector>
|
||||
#include <sys/wait.h>
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail { namespace posix {
|
||||
namespace boost { namespace process { namespace detail { namespace posix {
|
||||
|
||||
template<typename Executor>
|
||||
struct on_exit_handler_transformer
|
||||
@@ -80,7 +80,7 @@ struct io_context_ref : handler_base_ext
|
||||
void on_success(Executor& exec)
|
||||
{
|
||||
ios.notify_fork(boost::asio::io_context::fork_parent);
|
||||
//must be on the heap, so I can move it into the lambda.
|
||||
//must be on the heap so I can move it into the lambda.
|
||||
auto asyncs = boost::fusion::filter_if<
|
||||
is_async_handler<
|
||||
typename std::remove_reference< boost::mpl::_ > ::type
|
||||
@@ -100,7 +100,7 @@ struct io_context_ref : handler_base_ext
|
||||
{
|
||||
es->store(val);
|
||||
for (auto & func : funcs)
|
||||
func(::boost::process::v1::detail::posix::eval_exit_status(val), ec);
|
||||
func(::boost::process::detail::posix::eval_exit_status(val), ec);
|
||||
};
|
||||
|
||||
sigchld_service.async_wait(exec.pid, std::move(wh));
|
||||
@@ -117,9 +117,9 @@ struct io_context_ref : handler_base_ext
|
||||
|
||||
private:
|
||||
boost::asio::io_context &ios;
|
||||
boost::process::v1::detail::posix::sigchld_service &sigchld_service = boost::asio::use_service<boost::process::v1::detail::posix::sigchld_service>(ios);
|
||||
boost::process::detail::posix::sigchld_service &sigchld_service = boost::asio::use_service<boost::process::detail::posix::sigchld_service>(ios);
|
||||
};
|
||||
|
||||
}}}}}
|
||||
}}}}
|
||||
|
||||
#endif /* BOOST_PROCESS_WINDOWS_IO_CONTEXT_REF_HPP_ */
|
||||
@@ -6,12 +6,12 @@
|
||||
#ifndef BOOST_PROCESS_DETAIL_POSIX_IS_RUNNING_HPP
|
||||
#define BOOST_PROCESS_DETAIL_POSIX_IS_RUNNING_HPP
|
||||
|
||||
#include <boost/process/v1/detail/config.hpp>
|
||||
#include <boost/process/v1/detail/posix/child_handle.hpp>
|
||||
#include <boost/process/detail/config.hpp>
|
||||
#include <boost/process/detail/posix/child_handle.hpp>
|
||||
#include <system_error>
|
||||
#include <sys/wait.h>
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail { namespace posix {
|
||||
namespace boost { namespace process { namespace detail { namespace posix {
|
||||
|
||||
// Use the "stopped" state (WIFSTOPPED) to indicate "not terminated".
|
||||
// This bit arrangement of status codes is not guaranteed by POSIX, but (according to comments in
|
||||
@@ -34,8 +34,8 @@ inline bool is_running(const child_handle &p, int & exit_code, std::error_code &
|
||||
|
||||
if (ret == -1)
|
||||
{
|
||||
if (errno != ECHILD) //because it no child is running, then this one isn't either, obviously.
|
||||
ec = ::boost::process::v1::detail::get_last_error();
|
||||
if (errno != ECHILD) //because it no child is running, than this one isn't either, obviously.
|
||||
ec = ::boost::process::detail::get_last_error();
|
||||
return false;
|
||||
}
|
||||
else if (ret == 0)
|
||||
@@ -55,7 +55,7 @@ inline bool is_running(const child_handle &p, int & exit_code)
|
||||
{
|
||||
std::error_code ec;
|
||||
bool b = is_running(p, exit_code, ec);
|
||||
boost::process::v1::detail::throw_error(ec, "waitpid(2) failed in is_running");
|
||||
boost::process::detail::throw_error(ec, "waitpid(2) failed in is_running");
|
||||
return b;
|
||||
}
|
||||
|
||||
@@ -75,6 +75,6 @@ inline int eval_exit_status(int code)
|
||||
}
|
||||
}
|
||||
|
||||
}}}}}
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
@@ -10,16 +10,16 @@
|
||||
#ifndef BOOST_PROCESS_DETAIL_POSIX_NULL_IN_HPP
|
||||
#define BOOST_PROCESS_DETAIL_POSIX_NULL_IN_HPP
|
||||
|
||||
#include <boost/process/v1/pipe.hpp>
|
||||
#include <boost/process/v1/detail/posix/handler.hpp>
|
||||
#include <boost/process/v1/detail/posix/file_descriptor.hpp>
|
||||
#include <boost/process/pipe.hpp>
|
||||
#include <boost/process/detail/posix/handler.hpp>
|
||||
#include <boost/process/detail/posix/file_descriptor.hpp>
|
||||
#include <unistd.h>
|
||||
#include <boost/process/v1/detail/used_handles.hpp>
|
||||
#include <boost/process/detail/used_handles.hpp>
|
||||
#include <array>
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail { namespace posix {
|
||||
namespace boost { namespace process { namespace detail { namespace posix {
|
||||
|
||||
struct null_in : handler_base_ext, ::boost::process::v1::detail::uses_handles
|
||||
struct null_in : handler_base_ext, ::boost::process::detail::uses_handles
|
||||
{
|
||||
file_descriptor source{"/dev/null", file_descriptor::read};
|
||||
|
||||
@@ -34,10 +34,10 @@ public:
|
||||
void on_exec_setup(Executor &e) const
|
||||
{
|
||||
if (::dup2(source.handle(), STDIN_FILENO) == -1)
|
||||
e.set_error(::boost::process::v1::detail::get_last_error(), "dup2() failed");
|
||||
e.set_error(::boost::process::detail::get_last_error(), "dup2() failed");
|
||||
}
|
||||
};
|
||||
|
||||
}}}}}
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
@@ -11,16 +11,16 @@
|
||||
#ifndef BOOST_PROCESS_POSIX_PIPE_OUT_HPP
|
||||
#define BOOST_PROCESS_POSIX_PIPE_OUT_HPP
|
||||
|
||||
#include <boost/process/v1/detail/posix/handler.hpp>
|
||||
#include <boost/process/v1/detail/posix/file_descriptor.hpp>
|
||||
#include <boost/process/v1/detail/used_handles.hpp>
|
||||
#include <boost/process/detail/posix/handler.hpp>
|
||||
#include <boost/process/detail/posix/file_descriptor.hpp>
|
||||
#include <boost/process/detail/used_handles.hpp>
|
||||
#include <unistd.h>
|
||||
#include <array>
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail { namespace posix {
|
||||
namespace boost { namespace process { namespace detail { namespace posix {
|
||||
|
||||
template<int p1, int p2>
|
||||
struct null_out : handler_base_ext, ::boost::process::v1::detail::uses_handles
|
||||
struct null_out : handler_base_ext, ::boost::process::detail::uses_handles
|
||||
{
|
||||
file_descriptor sink{"/dev/null", file_descriptor::write};
|
||||
|
||||
@@ -41,7 +41,7 @@ template<typename Executor>
|
||||
void null_out<1,-1>::on_exec_setup(Executor &e) const
|
||||
{
|
||||
if (::dup2(sink.handle(), STDOUT_FILENO) == -1)
|
||||
e.set_error(::boost::process::v1::detail::get_last_error(), "dup2() failed");
|
||||
e.set_error(::boost::process::detail::get_last_error(), "dup2() failed");
|
||||
}
|
||||
|
||||
template<>
|
||||
@@ -49,7 +49,7 @@ template<typename Executor>
|
||||
void null_out<2,-1>::on_exec_setup(Executor &e) const
|
||||
{
|
||||
if (::dup2(sink.handle(), STDERR_FILENO) == -1)
|
||||
e.set_error(::boost::process::v1::detail::get_last_error(), "dup2() failed");
|
||||
e.set_error(::boost::process::detail::get_last_error(), "dup2() failed");
|
||||
}
|
||||
|
||||
template<>
|
||||
@@ -57,12 +57,12 @@ template<typename Executor>
|
||||
void null_out<1,2>::on_exec_setup(Executor &e) const
|
||||
{
|
||||
if (::dup2(sink.handle(), STDOUT_FILENO) == -1)
|
||||
e.set_error(::boost::process::v1::detail::get_last_error(), "dup2() failed");
|
||||
e.set_error(::boost::process::detail::get_last_error(), "dup2() failed");
|
||||
|
||||
if (::dup2(sink.handle(), STDERR_FILENO) == -1)
|
||||
e.set_error(::boost::process::v1::detail::get_last_error(), "dup2() failed");
|
||||
e.set_error(::boost::process::detail::get_last_error(), "dup2() failed");
|
||||
}
|
||||
|
||||
}}}}}
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
@@ -7,21 +7,21 @@
|
||||
#define BOOST_PROCESS_POSIX_ON_EXIT_HPP_
|
||||
|
||||
#include <boost/asio/execution.hpp>
|
||||
#include <boost/process/v1/async.hpp>
|
||||
#include <boost/process/v1/detail/config.hpp>
|
||||
#include <boost/process/v1/detail/handler_base.hpp>
|
||||
#include <boost/process/v1/detail/posix/async_handler.hpp>
|
||||
#include <boost/process/async.hpp>
|
||||
#include <boost/process/detail/config.hpp>
|
||||
#include <boost/process/detail/handler_base.hpp>
|
||||
#include <boost/process/detail/posix/async_handler.hpp>
|
||||
#include <system_error>
|
||||
#include <functional>
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail {
|
||||
namespace boost { namespace process { namespace detail {
|
||||
|
||||
template<typename Tuple>
|
||||
inline asio::io_context& get_io_context(const Tuple & tup);
|
||||
|
||||
namespace posix {
|
||||
|
||||
struct on_exit_ : boost::process::v1::detail::posix::async_handler
|
||||
struct on_exit_ : boost::process::detail::posix::async_handler
|
||||
{
|
||||
std::function<void(int, const std::error_code&)> handler;
|
||||
on_exit_(const std::function<void(int, const std::error_code&)> & handler) : handler(handler)
|
||||
@@ -31,7 +31,7 @@ struct on_exit_ : boost::process::v1::detail::posix::async_handler
|
||||
template<typename Executor>
|
||||
std::function<void(int, const std::error_code&)> on_exit_handler(Executor& exec)
|
||||
{
|
||||
auto v = boost::asio::prefer(boost::process::v1::detail::get_io_context(exec.seq).get_executor(),
|
||||
auto v = boost::asio::prefer(boost::process::detail::get_io_context(exec.seq).get_executor(),
|
||||
boost::asio::execution::outstanding_work.tracked);
|
||||
auto handler_ = this->handler;
|
||||
return
|
||||
@@ -44,5 +44,5 @@ struct on_exit_ : boost::process::v1::detail::posix::async_handler
|
||||
};
|
||||
|
||||
|
||||
}}}}}
|
||||
}}}}
|
||||
#endif /* BOOST_PROCESS_POSIX_ON_EXIT_HPP_ */
|
||||
@@ -10,15 +10,15 @@
|
||||
#ifndef BOOST_PROCESS_POSIX_PIPE_IN_HPP
|
||||
#define BOOST_PROCESS_POSIX_PIPE_IN_HPP
|
||||
|
||||
#include <boost/process/v1/pipe.hpp>
|
||||
#include <boost/process/v1/detail/posix/handler.hpp>
|
||||
#include <boost/process/pipe.hpp>
|
||||
#include <boost/process/detail/posix/handler.hpp>
|
||||
#include <unistd.h>
|
||||
#include <boost/process/v1/detail/used_handles.hpp>
|
||||
#include <boost/process/detail/used_handles.hpp>
|
||||
#include <array>
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail { namespace posix {
|
||||
namespace boost { namespace process { namespace detail { namespace posix {
|
||||
|
||||
struct pipe_in : handler_base_ext, ::boost::process::v1::detail::uses_handles
|
||||
struct pipe_in : handler_base_ext, ::boost::process::detail::uses_handles
|
||||
{
|
||||
int source;
|
||||
int sink; //opposite end
|
||||
@@ -53,7 +53,7 @@ struct pipe_in : handler_base_ext, ::boost::process::v1::detail::uses_handles
|
||||
void on_exec_setup(Executor &e) const
|
||||
{
|
||||
if (::dup2(source, STDIN_FILENO) == -1)
|
||||
e.set_error(::boost::process::v1::detail::get_last_error(), "dup2() failed");
|
||||
e.set_error(::boost::process::detail::get_last_error(), "dup2() failed");
|
||||
if (source != STDIN_FILENO)
|
||||
::close(source);
|
||||
|
||||
@@ -93,6 +93,6 @@ struct async_pipe_in : public pipe_in
|
||||
}
|
||||
};
|
||||
|
||||
}}}}}
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
@@ -11,28 +11,18 @@
|
||||
#ifndef BOOST_PROCESS_DETAIL_POSIX_PIPE_OUT_HPP
|
||||
#define BOOST_PROCESS_DETAIL_POSIX_PIPE_OUT_HPP
|
||||
|
||||
#include <boost/process/v1/pipe.hpp>
|
||||
#include <boost/process/v1/detail/posix/handler.hpp>
|
||||
#include <boost/process/pipe.hpp>
|
||||
#include <boost/process/detail/posix/handler.hpp>
|
||||
#include <unistd.h>
|
||||
#include <array>
|
||||
#include <boost/process/v1/detail/used_handles.hpp>
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail { namespace posix {
|
||||
namespace boost { namespace process { namespace detail { namespace posix {
|
||||
|
||||
template<int p1, int p2>
|
||||
struct pipe_out : handler_base_ext, ::boost::process::v1::detail::uses_handles
|
||||
struct pipe_out : handler_base_ext
|
||||
{
|
||||
int sink;
|
||||
int source; //opposite end
|
||||
|
||||
std::array<int, 4> get_used_handles()
|
||||
{
|
||||
const auto pp1 = p1 != -1 ? p1 : p2;
|
||||
const auto pp2 = p2 != -1 ? p2 : p1;
|
||||
|
||||
return {source, sink, pp1, pp2};
|
||||
}
|
||||
|
||||
pipe_out(int sink, int source) : sink(sink), source(source) {}
|
||||
|
||||
template<typename T>
|
||||
@@ -62,7 +52,7 @@ template<typename Executor>
|
||||
void pipe_out<1,-1>::on_exec_setup(Executor &e) const
|
||||
{
|
||||
if (::dup2(sink, STDOUT_FILENO) == -1)
|
||||
e.set_error(::boost::process::v1::detail::get_last_error(), "dup2() failed");
|
||||
e.set_error(::boost::process::detail::get_last_error(), "dup2() failed");
|
||||
|
||||
if (sink != STDOUT_FILENO)
|
||||
::close(sink);
|
||||
@@ -74,7 +64,7 @@ template<typename Executor>
|
||||
void pipe_out<2,-1>::on_exec_setup(Executor &e) const
|
||||
{
|
||||
if (::dup2(sink, STDERR_FILENO) == -1)
|
||||
e.set_error(::boost::process::v1::detail::get_last_error(), "dup2() failed");
|
||||
e.set_error(::boost::process::detail::get_last_error(), "dup2() failed");
|
||||
|
||||
if (sink != STDOUT_FILENO)
|
||||
::close(sink);
|
||||
@@ -86,12 +76,11 @@ template<typename Executor>
|
||||
void pipe_out<1,2>::on_exec_setup(Executor &e) const
|
||||
{
|
||||
if (::dup2(sink, STDOUT_FILENO) == -1)
|
||||
e.set_error(::boost::process::v1::detail::get_last_error(), "dup2() failed");
|
||||
e.set_error(::boost::process::detail::get_last_error(), "dup2() failed");
|
||||
if (::dup2(sink, STDERR_FILENO) == -1)
|
||||
e.set_error(::boost::process::v1::detail::get_last_error(), "dup2() failed");
|
||||
e.set_error(::boost::process::detail::get_last_error(), "dup2() failed");
|
||||
if ((sink != STDOUT_FILENO) && (sink != STDERR_FILENO))
|
||||
::close(sink);
|
||||
::close(source);
|
||||
}
|
||||
|
||||
class async_pipe;
|
||||
@@ -126,6 +115,6 @@ struct async_pipe_out : public pipe_out<p1, p2>
|
||||
};
|
||||
|
||||
|
||||
}}}}}
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
@@ -10,21 +10,21 @@
|
||||
#ifndef BOOST_PROCESS_POSIX_SEARCH_PATH_HPP
|
||||
#define BOOST_PROCESS_POSIX_SEARCH_PATH_HPP
|
||||
|
||||
#include <boost/process/v1/detail/config.hpp>
|
||||
#include <boost/process/v1/filesystem.hpp>
|
||||
#include <boost/process/detail/config.hpp>
|
||||
#include <boost/process/filesystem.hpp>
|
||||
#include <boost/tokenizer.hpp>
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail { namespace posix {
|
||||
namespace boost { namespace process { namespace detail { namespace posix {
|
||||
|
||||
inline boost::process::v1::filesystem::path search_path(
|
||||
const boost::process::v1::filesystem::path &filename,
|
||||
const std::vector<boost::process::v1::filesystem::path> &path)
|
||||
inline boost::process::filesystem::path search_path(
|
||||
const boost::process::filesystem::path &filename,
|
||||
const std::vector<boost::process::filesystem::path> &path)
|
||||
{
|
||||
for (const boost::process::v1::filesystem::path & pp : path)
|
||||
for (const boost::process::filesystem::path & pp : path)
|
||||
{
|
||||
auto p = pp / filename;
|
||||
#if defined(BOOST_PROCESS_USE_STD_FS)
|
||||
@@ -32,13 +32,13 @@ inline boost::process::v1::filesystem::path search_path(
|
||||
#else
|
||||
boost::system::error_code ec;
|
||||
#endif
|
||||
bool file = boost::process::v1::filesystem::is_regular_file(p, ec);
|
||||
bool file = boost::process::filesystem::is_regular_file(p, ec);
|
||||
if (!ec && file && ::access(p.c_str(), X_OK) == 0)
|
||||
return p;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
}}}}}
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
@@ -10,23 +10,23 @@
|
||||
#ifndef BOOST_PROCESS_POSIX_SHELL_PATH_HPP
|
||||
#define BOOST_PROCESS_POSIX_SHELL_PATH_HPP
|
||||
|
||||
#include <boost/process/v1/detail/config.hpp>
|
||||
#include <boost/process/detail/config.hpp>
|
||||
#include <boost/system/error_code.hpp>
|
||||
#include <boost/process/v1/filesystem.hpp>
|
||||
#include <boost/process/filesystem.hpp>
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail { namespace posix {
|
||||
namespace boost { namespace process { namespace detail { namespace posix {
|
||||
|
||||
inline boost::process::v1::filesystem::path shell_path()
|
||||
inline boost::process::filesystem::path shell_path()
|
||||
{
|
||||
return "/bin/sh";
|
||||
}
|
||||
|
||||
inline boost::process::v1::filesystem::path shell_path(std::error_code &ec)
|
||||
inline boost::process::filesystem::path shell_path(std::error_code &ec)
|
||||
{
|
||||
ec.clear();
|
||||
return "/bin/sh";
|
||||
}
|
||||
|
||||
}}}}}
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
@@ -7,11 +7,8 @@
|
||||
#ifndef BOOST_PROCESS_DETAIL_POSIX_SIGCHLD_SERVICE_HPP_
|
||||
#define BOOST_PROCESS_DETAIL_POSIX_SIGCHLD_SERVICE_HPP_
|
||||
|
||||
#include <boost/asio/bind_executor.hpp>
|
||||
#include <boost/asio/dispatch.hpp>
|
||||
#include <boost/asio/post.hpp>
|
||||
#include <boost/asio/consign.hpp>
|
||||
#include <boost/asio/append.hpp>
|
||||
#include <boost/asio/signal_set.hpp>
|
||||
#include <boost/asio/strand.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
@@ -20,7 +17,7 @@
|
||||
#include <sys/wait.h>
|
||||
#include <list>
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail { namespace posix {
|
||||
namespace boost { namespace process { namespace detail { namespace posix {
|
||||
|
||||
class sigchld_service : public boost::asio::detail::service_base<sigchld_service>
|
||||
{
|
||||
@@ -29,43 +26,6 @@ class sigchld_service : public boost::asio::detail::service_base<sigchld_service
|
||||
|
||||
std::list<std::pair<::pid_t, std::function<void(int, std::error_code)>>> _receivers;
|
||||
inline void _handle_signal(const boost::system::error_code & ec);
|
||||
|
||||
struct initiate_async_wait_op
|
||||
{
|
||||
sigchld_service * self;
|
||||
template<typename Initiation>
|
||||
void operator()(Initiation && init, ::pid_t pid)
|
||||
{
|
||||
// check if the child actually is running first
|
||||
int status;
|
||||
auto pid_res = ::waitpid(pid, &status, WNOHANG);
|
||||
if (pid_res < 0)
|
||||
{
|
||||
auto ec = get_last_error();
|
||||
boost::asio::post(
|
||||
self->_strand,
|
||||
asio::append(std::forward<Initiation>(init), pid_res, ec));
|
||||
}
|
||||
else if ((pid_res == pid) && (WIFEXITED(status) || WIFSIGNALED(status)))
|
||||
boost::asio::post(
|
||||
self->_strand,
|
||||
boost::asio::append(std::forward<Initiation>(init), status, std::error_code{}));
|
||||
else //still running
|
||||
{
|
||||
sigchld_service * self_ = self;
|
||||
if (self->_receivers.empty())
|
||||
self->_signal_set.async_wait(
|
||||
boost::asio::bind_executor(
|
||||
self->_strand,
|
||||
[self_](const boost::system::error_code &ec, int)
|
||||
{
|
||||
self_->_handle_signal(ec);
|
||||
}));
|
||||
self->_receivers.emplace_back(pid, init);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
sigchld_service(boost::asio::io_context & io_context)
|
||||
: boost::asio::detail::service_base<sigchld_service>(io_context)
|
||||
@@ -77,10 +37,47 @@ public:
|
||||
void (int, std::error_code))
|
||||
async_wait(::pid_t pid, SignalHandler && handler)
|
||||
{
|
||||
return boost::asio::async_initiate<
|
||||
SignalHandler,
|
||||
void(int, std::error_code)>(
|
||||
initiate_async_wait_op{this}, handler, pid);
|
||||
boost::asio::async_completion<
|
||||
SignalHandler, void(boost::system::error_code)> init{handler};
|
||||
|
||||
auto & h = init.completion_handler;
|
||||
boost::asio::dispatch(
|
||||
_strand,
|
||||
[this, pid, h]
|
||||
{
|
||||
//check if the child actually is running first
|
||||
int status;
|
||||
auto pid_res = ::waitpid(pid, &status, WNOHANG);
|
||||
if (pid_res < 0)
|
||||
{
|
||||
auto ec = get_last_error();
|
||||
boost::asio::post(
|
||||
_strand,
|
||||
[pid_res, ec, h]
|
||||
{
|
||||
h(pid_res, ec);
|
||||
});
|
||||
}
|
||||
else if ((pid_res == pid) && (WIFEXITED(status) || WIFSIGNALED(status)))
|
||||
boost::asio::post(
|
||||
_strand,
|
||||
[status, h]
|
||||
{
|
||||
h(status, {}); //successfully exited already
|
||||
});
|
||||
else //still running
|
||||
{
|
||||
if (_receivers.empty())
|
||||
_signal_set.async_wait(
|
||||
[this](const boost::system::error_code &ec, int)
|
||||
{
|
||||
boost::asio::dispatch(_strand, [this, ec]{this->_handle_signal(ec);});
|
||||
});
|
||||
_receivers.emplace_back(pid, h);
|
||||
}
|
||||
});
|
||||
|
||||
return init.result.get();
|
||||
}
|
||||
void shutdown() override
|
||||
{
|
||||
@@ -145,7 +142,7 @@ void sigchld_service::_handle_signal(const boost::system::error_code & ec)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -11,10 +11,10 @@
|
||||
#ifndef BOOST_PROCESS_POSIX_SIGNAL_HPP
|
||||
#define BOOST_PROCESS_POSIX_SIGNAL_HPP
|
||||
|
||||
#include <boost/process/v1/detail/posix/handler.hpp>
|
||||
#include <boost/process/detail/posix/handler.hpp>
|
||||
#include <signal.h>
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail { namespace posix {
|
||||
namespace boost { namespace process { namespace detail { namespace posix {
|
||||
|
||||
#if defined(__GLIBC__)
|
||||
using sighandler_t = ::sighandler_t;
|
||||
@@ -55,16 +55,16 @@ struct sig_init_ : handler_base_ext
|
||||
}
|
||||
private:
|
||||
bool _reset = false;
|
||||
::boost::process::v1::detail::posix::sighandler_t _old{0};
|
||||
::boost::process::v1::detail::posix::sighandler_t _handler{0};
|
||||
::boost::process::detail::posix::sighandler_t _old{0};
|
||||
::boost::process::detail::posix::sighandler_t _handler{0};
|
||||
};
|
||||
|
||||
struct sig_
|
||||
{
|
||||
constexpr sig_() {}
|
||||
|
||||
sig_init_ operator()(::boost::process::v1::detail::posix::sighandler_t h) const {return h;}
|
||||
sig_init_ operator= (::boost::process::v1::detail::posix::sighandler_t h) const {return h;}
|
||||
sig_init_ operator()(::boost::process::detail::posix::sighandler_t h) const {return h;}
|
||||
sig_init_ operator= (::boost::process::detail::posix::sighandler_t h) const {return h;}
|
||||
sig_init_ dfl() const {return SIG_DFL;}
|
||||
sig_init_ ign() const {return SIG_IGN;}
|
||||
|
||||
@@ -74,6 +74,6 @@ struct sig_
|
||||
|
||||
|
||||
|
||||
}}}}}
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
@@ -10,12 +10,12 @@
|
||||
#ifndef BOOST_PROCESS_DETAIL_POSIX_START_DIR_HPP
|
||||
#define BOOST_PROCESS_DETAIL_POSIX_START_DIR_HPP
|
||||
|
||||
#include <boost/process/v1/detail/posix/handler.hpp>
|
||||
#include <boost/process/detail/posix/handler.hpp>
|
||||
#include <string>
|
||||
#include <unistd.h>
|
||||
#include <boost/core/ignore_unused.hpp>
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail { namespace posix {
|
||||
namespace boost { namespace process { namespace detail { namespace posix {
|
||||
|
||||
template<typename Char>
|
||||
struct start_dir_init : handler_base_ext
|
||||
@@ -34,6 +34,6 @@ private:
|
||||
string_type s_;
|
||||
};
|
||||
|
||||
}}}}}
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
@@ -10,19 +10,19 @@
|
||||
#ifndef BOOST_PROCESS_DETAIL_POSIX_TERMINATE_HPP
|
||||
#define BOOST_PROCESS_DETAIL_POSIX_TERMINATE_HPP
|
||||
|
||||
#include <boost/process/v1/detail/config.hpp>
|
||||
#include <boost/process/v1/detail/posix/child_handle.hpp>
|
||||
#include <boost/process/detail/config.hpp>
|
||||
#include <boost/process/detail/posix/child_handle.hpp>
|
||||
#include <system_error>
|
||||
#include <signal.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail { namespace posix {
|
||||
namespace boost { namespace process { namespace detail { namespace posix {
|
||||
|
||||
inline void terminate(const child_handle &p, std::error_code &ec) noexcept
|
||||
{
|
||||
if (::kill(p.pid, SIGKILL) == -1)
|
||||
ec = boost::process::v1::detail::get_last_error();
|
||||
ec = boost::process::detail::get_last_error();
|
||||
else
|
||||
ec.clear();
|
||||
|
||||
@@ -34,9 +34,9 @@ inline void terminate(const child_handle &p)
|
||||
{
|
||||
std::error_code ec;
|
||||
terminate(p, ec);
|
||||
boost::process::v1::detail::throw_error(ec, "kill(2) failed");
|
||||
boost::process::detail::throw_error(ec, "kill(2) failed");
|
||||
}
|
||||
|
||||
}}}}}
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
@@ -9,11 +9,11 @@
|
||||
#define BOOST_PROCESS_DETAIL_POSIX_USE_VFORK_HPP_
|
||||
|
||||
|
||||
#include <boost/process/v1/detail/posix/handler.hpp>
|
||||
#include <boost/process/detail/posix/handler.hpp>
|
||||
#include <boost/fusion/sequence/intrinsic/has_key.hpp>
|
||||
#include <boost/fusion/container/set/convert.hpp>
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail { namespace posix {
|
||||
namespace boost { namespace process { namespace detail { namespace posix {
|
||||
|
||||
struct use_vfork_ : handler_base_ext
|
||||
{
|
||||
@@ -28,6 +28,6 @@ struct shall_use_vfork
|
||||
};
|
||||
|
||||
|
||||
}}}}}
|
||||
}}}}
|
||||
|
||||
#endif /* BOOST_PROCESS_DETAIL_POSIX_USE_VFORK_HPP_ */
|
||||
@@ -10,14 +10,14 @@
|
||||
#ifndef BOOST_PROCESS_DETAIL_POSIX_WAIT_FOR_EXIT_HPP
|
||||
#define BOOST_PROCESS_DETAIL_POSIX_WAIT_FOR_EXIT_HPP
|
||||
|
||||
#include <boost/process/v1/detail/config.hpp>
|
||||
#include <boost/process/v1/detail/posix/child_handle.hpp>
|
||||
#include <boost/process/detail/config.hpp>
|
||||
#include <boost/process/detail/posix/child_handle.hpp>
|
||||
#include <system_error>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail { namespace posix {
|
||||
namespace boost { namespace process { namespace detail { namespace posix {
|
||||
|
||||
inline void wait(const child_handle &p, int & exit_code, std::error_code &ec) noexcept
|
||||
{
|
||||
@@ -32,7 +32,7 @@ inline void wait(const child_handle &p, int & exit_code, std::error_code &ec) no
|
||||
(ret != -1 && !WIFEXITED(status) && !WIFSIGNALED(status)));
|
||||
|
||||
if (ret == -1)
|
||||
ec = boost::process::v1::detail::get_last_error();
|
||||
ec = boost::process::detail::get_last_error();
|
||||
else
|
||||
{
|
||||
ec.clear();
|
||||
@@ -44,7 +44,7 @@ inline void wait(const child_handle &p, int & exit_code) noexcept
|
||||
{
|
||||
std::error_code ec;
|
||||
wait(p, exit_code, ec);
|
||||
boost::process::v1::detail::throw_error(ec, "waitpid(2) failed in wait");
|
||||
boost::process::detail::throw_error(ec, "waitpid(2) failed in wait");
|
||||
}
|
||||
|
||||
template< class Clock, class Duration >
|
||||
@@ -131,7 +131,7 @@ inline bool wait_until(
|
||||
pid_t timeout_pid = ::fork();
|
||||
if (timeout_pid == -1)
|
||||
{
|
||||
ec = boost::process::v1::detail::get_last_error();
|
||||
ec = boost::process::detail::get_last_error();
|
||||
return true;
|
||||
}
|
||||
else if (timeout_pid == 0)
|
||||
@@ -192,7 +192,7 @@ inline bool wait_until(
|
||||
#endif
|
||||
|
||||
if (ret == -1)
|
||||
ec = boost::process::v1::detail::get_last_error();
|
||||
ec = boost::process::detail::get_last_error();
|
||||
else
|
||||
{
|
||||
ec.clear();
|
||||
@@ -210,7 +210,7 @@ inline bool wait_until(
|
||||
{
|
||||
std::error_code ec;
|
||||
bool b = wait_until(p, exit_code, time_out, ec);
|
||||
boost::process::v1::detail::throw_error(ec, "waitpid(2) failed in wait_until");
|
||||
boost::process::detail::throw_error(ec, "waitpid(2) failed in wait_until");
|
||||
return b;
|
||||
}
|
||||
|
||||
@@ -232,10 +232,10 @@ inline bool wait_for(
|
||||
{
|
||||
std::error_code ec;
|
||||
bool b = wait_for(p, exit_code, rel_time, ec);
|
||||
boost::process::v1::detail::throw_error(ec, "waitpid(2) failed in wait_for");
|
||||
boost::process::detail::throw_error(ec, "waitpid(2) failed in wait_for");
|
||||
return b;
|
||||
}
|
||||
|
||||
}}}}}
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
@@ -10,15 +10,15 @@
|
||||
#ifndef BOOST_PROCESS_DETAIL_POSIX_WAIT_GROUP_HPP
|
||||
#define BOOST_PROCESS_DETAIL_POSIX_WAIT_GROUP_HPP
|
||||
|
||||
#include <boost/process/v1/detail/config.hpp>
|
||||
#include <boost/process/v1/detail/posix/group_handle.hpp>
|
||||
#include <boost/process/detail/config.hpp>
|
||||
#include <boost/process/detail/posix/group_handle.hpp>
|
||||
#include <chrono>
|
||||
#include <system_error>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail { namespace posix {
|
||||
namespace boost { namespace process { namespace detail { namespace posix {
|
||||
|
||||
inline void wait(const group_handle &p, std::error_code &ec) noexcept
|
||||
{
|
||||
@@ -40,7 +40,7 @@ inline void wait(const group_handle &p, std::error_code &ec) noexcept
|
||||
while ((ret != -1) || (errno != ECHILD));
|
||||
|
||||
if (errno != ECHILD)
|
||||
ec = boost::process::v1::detail::get_last_error();
|
||||
ec = boost::process::detail::get_last_error();
|
||||
else
|
||||
ec.clear();
|
||||
}
|
||||
@@ -49,7 +49,7 @@ inline void wait(const group_handle &p) noexcept
|
||||
{
|
||||
std::error_code ec;
|
||||
wait(p, ec);
|
||||
boost::process::v1::detail::throw_error(ec, "waitpid(2) failed in wait");
|
||||
boost::process::detail::throw_error(ec, "waitpid(2) failed in wait");
|
||||
}
|
||||
|
||||
template< class Clock, class Duration >
|
||||
@@ -79,7 +79,7 @@ inline bool wait_until(
|
||||
ec.clear();
|
||||
return true;
|
||||
}
|
||||
ec = boost::process::v1::detail::get_last_error();
|
||||
ec = boost::process::detail::get_last_error();
|
||||
return false;
|
||||
}
|
||||
//we can wait, because unlike in the wait_for_exit, we have no race condition regarding eh exit code.
|
||||
@@ -95,7 +95,7 @@ inline bool wait_until(
|
||||
{
|
||||
std::error_code ec;
|
||||
bool b = wait_until(p, time_out, ec);
|
||||
boost::process::v1::detail::throw_error(ec, "waitpid(2) failed in wait_until");
|
||||
boost::process::detail::throw_error(ec, "waitpid(2) failed in wait_until");
|
||||
return b;
|
||||
}
|
||||
|
||||
@@ -115,10 +115,10 @@ inline bool wait_for(
|
||||
{
|
||||
std::error_code ec;
|
||||
bool b = wait_for(p, rel_time, ec);
|
||||
boost::process::v1::detail::throw_error(ec, "waitpid(2) failed in wait_for");
|
||||
boost::process::detail::throw_error(ec, "waitpid(2) failed in wait_for");
|
||||
return b;
|
||||
}
|
||||
|
||||
}}}}}
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
@@ -11,12 +11,12 @@
|
||||
#ifndef BOOST_PROCESS_DETAIL_INITIALIZERS_THROW_ON_ERROR_HPP
|
||||
#define BOOST_PROCESS_DETAIL_INITIALIZERS_THROW_ON_ERROR_HPP
|
||||
|
||||
#include <boost/process/v1/detail/config.hpp>
|
||||
#include <boost/process/v1/detail/handler_base.hpp>
|
||||
#include <boost/process/detail/config.hpp>
|
||||
#include <boost/process/detail/handler_base.hpp>
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail {
|
||||
namespace boost { namespace process { namespace detail {
|
||||
|
||||
struct throw_on_error_ : ::boost::process::v1::detail::handler
|
||||
struct throw_on_error_ : ::boost::process::detail::handler
|
||||
{
|
||||
template <class Executor>
|
||||
void on_error(Executor& exec, const std::error_code & ec) const
|
||||
@@ -29,8 +29,8 @@ struct throw_on_error_ : ::boost::process::v1::detail::handler
|
||||
|
||||
}
|
||||
|
||||
constexpr boost::process::v1::detail::throw_on_error_ throw_on_error;
|
||||
constexpr boost::process::detail::throw_on_error_ throw_on_error;
|
||||
|
||||
}}}
|
||||
}}
|
||||
|
||||
#endif
|
||||
17
include/boost/process/detail/traits.hpp
Normal file
17
include/boost/process/detail/traits.hpp
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright (c) 2016 Klemens D. Morgenstern
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
|
||||
#ifndef BOOST_PROCESS_TRAITS_HPP_
|
||||
#define BOOST_PROCESS_TRAITS_HPP_
|
||||
|
||||
#include <boost/process/detail/traits/decl.hpp>
|
||||
#include <boost/process/detail/traits/async.hpp>
|
||||
#include <boost/process/detail/traits/cmd_or_exe.hpp>
|
||||
#include <boost/process/detail/traits/env.hpp>
|
||||
#include <boost/process/detail/traits/error.hpp>
|
||||
#include <boost/process/detail/traits/wchar_t.hpp>
|
||||
|
||||
#endif /* BOOST_PROCESS_TRAITS_HPP_ */
|
||||
@@ -7,15 +7,15 @@
|
||||
#ifndef BOOST_PROCESS_DETAIL_TRAITS_ASYNC_HPP_
|
||||
#define BOOST_PROCESS_DETAIL_TRAITS_ASYNC_HPP_
|
||||
|
||||
#include <boost/process/v1/detail/config.hpp>
|
||||
#include <boost/process/v1/detail/traits/decl.hpp>
|
||||
#include <boost/process/detail/config.hpp>
|
||||
#include <boost/process/detail/traits/decl.hpp>
|
||||
|
||||
namespace boost { namespace asio {
|
||||
|
||||
class io_context;
|
||||
}}
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail {
|
||||
namespace boost { namespace process { namespace detail {
|
||||
|
||||
struct async_tag {};
|
||||
|
||||
@@ -27,6 +27,8 @@ template<> struct initializer_tag<::boost::asio::io_context> { typedef async_tag
|
||||
|
||||
|
||||
|
||||
}}}}
|
||||
}}}
|
||||
|
||||
|
||||
|
||||
#endif /* BOOST_PROCESS_DETAIL_HANDLER_HPP_ */
|
||||
@@ -11,11 +11,9 @@
|
||||
#include <vector>
|
||||
#include <type_traits>
|
||||
#include <initializer_list>
|
||||
#include <boost/process/v1/filesystem.hpp>
|
||||
#include <boost/process/v1/detail/traits/decl.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail {
|
||||
#include <boost/process/filesystem.hpp>
|
||||
#include <boost/process/detail/traits/decl.hpp>
|
||||
namespace boost { namespace process { namespace detail {
|
||||
|
||||
template<typename Char>
|
||||
struct cmd_or_exe_tag {};
|
||||
@@ -55,12 +53,12 @@ template<> struct initializer_tag<std::initializer_list<const wchar_t *>> { type
|
||||
|
||||
template<> struct initializer_tag<shell_>
|
||||
{
|
||||
typedef cmd_or_exe_tag<typename boost::process::v1::filesystem::path::value_type> type;
|
||||
typedef cmd_or_exe_tag<typename boost::process::filesystem::path::value_type> type;
|
||||
};
|
||||
|
||||
template<> struct initializer_tag<boost::process::v1::filesystem::path>
|
||||
template<> struct initializer_tag<boost::process::filesystem::path>
|
||||
{
|
||||
typedef cmd_or_exe_tag<typename boost::process::v1::filesystem::path::value_type> type;
|
||||
typedef cmd_or_exe_tag<typename boost::process::filesystem::path::value_type> type;
|
||||
};
|
||||
|
||||
template <typename Char>
|
||||
@@ -80,6 +78,8 @@ template<>
|
||||
struct initializer_builder<cmd_or_exe_tag<wchar_t>>;
|
||||
|
||||
|
||||
}}}}
|
||||
}}}
|
||||
|
||||
|
||||
|
||||
#endif /* BOOST_PROCESS_DETAIL_STRING_TRAITS_HPP_ */
|
||||
@@ -7,18 +7,18 @@
|
||||
#ifndef BOOST_PROCESS_DETAIL_TRAITS_DECL_HPP_
|
||||
#define BOOST_PROCESS_DETAIL_TRAITS_DECL_HPP_
|
||||
|
||||
#include <boost/process/v1/detail/config.hpp>
|
||||
#include <boost/process/detail/config.hpp>
|
||||
#include <boost/none.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
#if defined(BOOST_POSIX_API)
|
||||
#include <boost/process/v1/detail/posix/handler.hpp>
|
||||
#include <boost/process/detail/posix/handler.hpp>
|
||||
#elif defined(BOOST_WINDOWS_API)
|
||||
#include <boost/process/v1/detail/windows/handler.hpp>
|
||||
#include <boost/process/detail/windows/handler.hpp>
|
||||
#endif
|
||||
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail {
|
||||
namespace boost { namespace process { namespace detail {
|
||||
|
||||
|
||||
template<typename T>
|
||||
@@ -69,6 +69,8 @@ struct valid_argument_list
|
||||
|
||||
|
||||
|
||||
}}}}
|
||||
}}}
|
||||
|
||||
|
||||
|
||||
#endif /* BOOST_PROCESS_DETAIL_HANDLER_HPP_ */
|
||||
@@ -6,10 +6,11 @@
|
||||
#ifndef BOOST_PROCESS_DETAIL_TRAITS_ENV_HPP_
|
||||
#define BOOST_PROCESS_DETAIL_TRAITS_ENV_HPP_
|
||||
|
||||
#include <boost/process/v1/detail/config.hpp>
|
||||
#include <boost/process/v1/detail/traits/decl.hpp>
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 {
|
||||
#include <boost/process/detail/traits/decl.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace process {
|
||||
|
||||
template<typename Char>
|
||||
class basic_environment;
|
||||
@@ -22,6 +23,9 @@ namespace detail {
|
||||
template<typename Char>
|
||||
struct env_tag {};
|
||||
|
||||
|
||||
|
||||
|
||||
template<typename Char> struct env_set;
|
||||
template<typename Char> struct env_append;
|
||||
|
||||
@@ -35,8 +39,8 @@ template<typename Char> struct initializer_tag<env_append<Char>> { typedef env_t
|
||||
template<typename Char> struct initializer_tag<env_reset<Char>> { typedef env_tag<Char> type;};
|
||||
template<typename Char> struct initializer_tag<env_init <Char>> { typedef env_tag<Char> type;};
|
||||
|
||||
template<typename Char> struct initializer_tag<::boost::process::v1::basic_environment<Char>> { typedef env_tag<Char> type; };
|
||||
template<typename Char> struct initializer_tag<::boost::process::v1::basic_native_environment<Char>> { typedef env_tag<Char> type; };
|
||||
template<typename Char> struct initializer_tag<::boost::process::basic_environment<Char>> { typedef env_tag<Char> type; };
|
||||
template<typename Char> struct initializer_tag<::boost::process::basic_native_environment<Char>> { typedef env_tag<Char> type; };
|
||||
|
||||
template<> struct initializer_builder<env_tag<char>>;
|
||||
template<> struct initializer_builder<env_tag<wchar_t>>;
|
||||
@@ -44,5 +48,6 @@ template<> struct initializer_builder<env_tag<wchar_t>>;
|
||||
}
|
||||
|
||||
|
||||
}}}
|
||||
}}
|
||||
|
||||
#endif /* INCLUDE_BOOST_PROCESS_DETAIL_ENV_HPP_ */
|
||||
@@ -7,19 +7,21 @@
|
||||
#ifndef BOOST_PROCESS_DETAIL_TRAITS_ERROR_HPP_
|
||||
#define BOOST_PROCESS_DETAIL_TRAITS_ERROR_HPP_
|
||||
|
||||
#include <boost/process/v1/detail/config.hpp>
|
||||
#include <boost/process/detail/config.hpp>
|
||||
#include <system_error>
|
||||
#include <boost/process/v1/detail/traits/decl.hpp>
|
||||
#include <boost/process/detail/traits/decl.hpp>
|
||||
|
||||
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail {
|
||||
namespace boost { namespace process { namespace detail {
|
||||
|
||||
struct error_tag;
|
||||
|
||||
template<>
|
||||
struct initializer_tag<std::error_code>;
|
||||
|
||||
}}}}
|
||||
}}}
|
||||
|
||||
|
||||
|
||||
#endif /* BOOST_PROCESS_DETAIL_HANDLER_HPP_ */
|
||||
@@ -7,12 +7,12 @@
|
||||
#ifndef BOOST_PROCESS_DETAIL_TRAITS_GROUP_HPP_
|
||||
#define BOOST_PROCESS_DETAIL_TRAITS_GROUP_HPP_
|
||||
|
||||
#include <boost/process/v1/detail/config.hpp>
|
||||
#include <boost/process/v1/detail/traits/decl.hpp>
|
||||
#include <boost/process/detail/config.hpp>
|
||||
#include <boost/process/detail/traits/decl.hpp>
|
||||
|
||||
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 {
|
||||
namespace boost { namespace process {
|
||||
|
||||
struct group;
|
||||
|
||||
@@ -25,12 +25,12 @@ template<>
|
||||
struct make_initializer_t<group_tag>;
|
||||
|
||||
|
||||
template<> struct initializer_tag_t<::boost::process::v1::group> { typedef group_tag type;};
|
||||
template<> struct initializer_tag_t<::boost::process::group> { typedef group_tag type;};
|
||||
|
||||
|
||||
|
||||
|
||||
}}}}
|
||||
}}}
|
||||
|
||||
|
||||
|
||||
@@ -9,18 +9,18 @@
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <boost/process/v1/detail/traits/decl.hpp>
|
||||
#include <boost/process/v1/detail/traits/cmd_or_exe.hpp>
|
||||
#include <boost/process/v1/detail/traits/env.hpp>
|
||||
#include <boost/process/v1/locale.hpp>
|
||||
#include <boost/process/detail/traits/decl.hpp>
|
||||
#include <boost/process/detail/traits/cmd_or_exe.hpp>
|
||||
#include <boost/process/detail/traits/env.hpp>
|
||||
#include <boost/process/locale.hpp>
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail {
|
||||
namespace boost { namespace process { namespace detail {
|
||||
|
||||
//template
|
||||
|
||||
template<typename T> struct is_wchar_t : std::false_type {};
|
||||
|
||||
template<> struct is_wchar_t<boost::process::v1::filesystem::path> : std::is_same<typename boost::process::v1::filesystem::path::value_type, wchar_t>
|
||||
template<> struct is_wchar_t<boost::process::filesystem::path> : std::is_same<typename boost::process::filesystem::path::value_type, wchar_t>
|
||||
{
|
||||
};
|
||||
|
||||
@@ -68,7 +68,7 @@ struct char_converter<char, const wchar_t*>
|
||||
{
|
||||
std::size_t size = 0;
|
||||
while (in[size] != L'\0') size++;
|
||||
return ::boost::process::v1::detail::convert(in, in + size);
|
||||
return ::boost::process::detail::convert(in, in + size);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -79,7 +79,7 @@ struct char_converter<char, wchar_t*>
|
||||
{
|
||||
std::size_t size = 0;
|
||||
while (in[size] != L'\0') size++;
|
||||
return ::boost::process::v1::detail::convert(in, in + size);
|
||||
return ::boost::process::detail::convert(in, in + size);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -88,7 +88,7 @@ struct char_converter<char, wchar_t[Size]>
|
||||
{
|
||||
static std::string conv(const wchar_t(&in)[Size])
|
||||
{
|
||||
return ::boost::process::v1::detail::convert(in, in + Size -1);
|
||||
return ::boost::process::detail::convert(in, in + Size -1);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -99,7 +99,7 @@ struct char_converter<wchar_t, const char*>
|
||||
{
|
||||
std::size_t size = 0;
|
||||
while (in[size] != '\0') size++;
|
||||
return ::boost::process::v1::detail::convert(in, in + size);
|
||||
return ::boost::process::detail::convert(in, in + size);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -110,7 +110,7 @@ struct char_converter<wchar_t, char*>
|
||||
{
|
||||
std::size_t size = 0;
|
||||
while (in[size] != '\0') size++;
|
||||
return ::boost::process::v1::detail::convert(in, in + size);
|
||||
return ::boost::process::detail::convert(in, in + size);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -120,7 +120,7 @@ struct char_converter<wchar_t, char[Size]>
|
||||
{
|
||||
static std::wstring conv(const char(&in)[Size])
|
||||
{
|
||||
return ::boost::process::v1::detail::convert(in, in + Size -1);
|
||||
return ::boost::process::detail::convert(in, in + Size -1);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -130,7 +130,7 @@ struct char_converter<wchar_t, std::string>
|
||||
{
|
||||
static std::wstring conv(const std::string & in)
|
||||
{
|
||||
return ::boost::process::v1::detail::convert(in);
|
||||
return ::boost::process::detail::convert(in);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -139,7 +139,7 @@ struct char_converter<char, std::wstring>
|
||||
{
|
||||
static std::string conv(const std::wstring & in)
|
||||
{
|
||||
return ::boost::process::v1::detail::convert(in);
|
||||
return ::boost::process::detail::convert(in);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -272,5 +272,5 @@ struct char_converter<char, std::initializer_list<wchar_t * >>
|
||||
};
|
||||
|
||||
|
||||
}}}}
|
||||
}}}
|
||||
#endif /* BOOST_PROCESS_DETAIL_TRAITS_WCHAR_T_HPP_ */
|
||||
@@ -11,14 +11,14 @@
|
||||
#include <boost/fusion/include/for_each.hpp>
|
||||
|
||||
#if defined(BOOST_POSIX_API)
|
||||
#include <boost/process/v1/detail/posix/handles.hpp>
|
||||
#include <boost/process/v1/detail/posix/asio_fwd.hpp>
|
||||
#include <boost/process/detail/posix/handles.hpp>
|
||||
#include <boost/process/detail/posix/asio_fwd.hpp>
|
||||
#else
|
||||
#include <boost/process/v1/detail/windows/handles.hpp>
|
||||
#include <boost/process/v1/detail/windows/asio_fwd.hpp>
|
||||
#include <boost/process/detail/windows/handles.hpp>
|
||||
#include <boost/process/detail/windows/asio_fwd.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail {
|
||||
namespace boost { namespace process { namespace detail {
|
||||
|
||||
struct uses_handles
|
||||
{
|
||||
@@ -52,7 +52,7 @@ struct foreach_handle_invocator
|
||||
func(handle_);
|
||||
|
||||
}
|
||||
void invoke(::boost::process::v1::detail::api::native_handle_type handle) const {func(handle);};
|
||||
void invoke(::boost::process::detail::api::native_handle_type handle) const {func(handle);};
|
||||
|
||||
template<typename T>
|
||||
void operator()(T & val) const {invoke(val.get_used_handles());}
|
||||
@@ -66,16 +66,16 @@ void foreach_used_handle(Executor &exec, Function &&func)
|
||||
}
|
||||
|
||||
template<typename Executor>
|
||||
std::vector<::boost::process::v1::detail::api::native_handle_type>
|
||||
std::vector<::boost::process::detail::api::native_handle_type>
|
||||
get_used_handles(Executor &exec)
|
||||
{
|
||||
std::vector<::boost::process::v1::detail::api::native_handle_type> res = exec.get_used_handles();
|
||||
foreach_used_handle(exec, [&](::boost::process::v1::detail::api::native_handle_type handle){res.push_back(handle);});
|
||||
std::vector<::boost::process::detail::api::native_handle_type> res = exec.get_used_handles();
|
||||
foreach_used_handle(exec, [&](::boost::process::detail::api::native_handle_type handle){res.push_back(handle);});
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}}}}
|
||||
}}}
|
||||
|
||||
#endif /* BOOST_PROCESS_DETAIL_USED_HANDLES_HPP_ */
|
||||
@@ -6,9 +6,8 @@
|
||||
#ifndef BOOST_PROCESS_DETAIL_WINDOWS_ASIO_FWD_HPP_
|
||||
#define BOOST_PROCESS_DETAIL_WINDOWS_ASIO_FWD_HPP_
|
||||
|
||||
#include <boost/process/v1/detail/config.hpp>
|
||||
#include <boost/asio/ts/netfwd.hpp>
|
||||
#include <memory>
|
||||
#include <boost/asio/ts/netfwd.hpp>
|
||||
|
||||
namespace boost { namespace asio {
|
||||
|
||||
@@ -38,7 +37,7 @@ typedef basic_object_handle<any_io_executor> object_handle;
|
||||
} //windows
|
||||
} //asio
|
||||
|
||||
namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail { namespace windows {
|
||||
namespace process { namespace detail { namespace windows {
|
||||
|
||||
class async_pipe;
|
||||
|
||||
@@ -54,9 +53,8 @@ struct async_out_future;
|
||||
} // windows
|
||||
} // detail
|
||||
|
||||
using ::boost::process::v1::detail::windows::async_pipe;
|
||||
using ::boost::process::detail::windows::async_pipe;
|
||||
|
||||
} // v1
|
||||
} // process
|
||||
} // boost
|
||||
|
||||
@@ -7,11 +7,10 @@
|
||||
#ifndef BOOST_PROCESS_WINDOWS_ASYNC_HANDLER_HPP_
|
||||
#define BOOST_PROCESS_WINDOWS_ASYNC_HANDLER_HPP_
|
||||
|
||||
#include <boost/process/v1/detail/config.hpp>
|
||||
#include <boost/process/v1/detail/windows/handler.hpp>
|
||||
#include <boost/process/detail/windows/handler.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail { namespace windows {
|
||||
namespace boost { namespace process { namespace detail { namespace windows {
|
||||
|
||||
struct require_io_context {};
|
||||
|
||||
@@ -36,6 +35,6 @@ template<typename T>
|
||||
struct does_require_io_context<const T&> : std::is_base_of<require_io_context, T> {};
|
||||
|
||||
|
||||
}}}}}
|
||||
}}}}
|
||||
|
||||
#endif /* BOOST_PROCESS_WINDOWS_ASYNC_HANDLER_HPP_ */
|
||||
@@ -16,21 +16,21 @@
|
||||
#include <boost/winapi/error_codes.hpp>
|
||||
|
||||
#include <boost/asio/write.hpp>
|
||||
#include <boost/process/v1/detail/handler_base.hpp>
|
||||
#include <boost/process/v1/detail/used_handles.hpp>
|
||||
#include <boost/process/v1/detail/windows/async_handler.hpp>
|
||||
#include <boost/process/v1/detail/windows/asio_fwd.hpp>
|
||||
#include <boost/process/v1/async_pipe.hpp>
|
||||
#include <boost/process/detail/handler_base.hpp>
|
||||
#include <boost/process/detail/used_handles.hpp>
|
||||
#include <boost/process/detail/windows/async_handler.hpp>
|
||||
#include <boost/process/detail/windows/asio_fwd.hpp>
|
||||
#include <boost/process/async_pipe.hpp>
|
||||
#include <memory>
|
||||
#include <future>
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail { namespace windows {
|
||||
namespace boost { namespace process { namespace detail { namespace windows {
|
||||
|
||||
|
||||
template<typename Buffer>
|
||||
struct async_in_buffer : ::boost::process::v1::detail::windows::handler_base_ext,
|
||||
::boost::process::v1::detail::windows::require_io_context,
|
||||
::boost::process::v1::detail::uses_handles
|
||||
struct async_in_buffer : ::boost::process::detail::windows::handler_base_ext,
|
||||
::boost::process::detail::windows::require_io_context,
|
||||
::boost::process::detail::uses_handles
|
||||
{
|
||||
Buffer & buf;
|
||||
|
||||
@@ -41,7 +41,7 @@ struct async_in_buffer : ::boost::process::v1::detail::windows::handler_base_ext
|
||||
fut = promise->get_future(); return std::move(*this);
|
||||
}
|
||||
|
||||
std::shared_ptr<boost::process::v1::async_pipe> pipe;
|
||||
std::shared_ptr<boost::process::async_pipe> pipe;
|
||||
|
||||
::boost::winapi::HANDLE_ get_used_handles() const
|
||||
{
|
||||
@@ -91,7 +91,7 @@ struct async_in_buffer : ::boost::process::v1::detail::windows::handler_base_ext
|
||||
void on_setup(WindowsExecutor &exec)
|
||||
{
|
||||
if (!pipe)
|
||||
pipe = std::make_shared<boost::process::v1::async_pipe>(get_io_context(exec.seq));
|
||||
pipe = std::make_shared<boost::process::async_pipe>(get_io_context(exec.seq));
|
||||
|
||||
::boost::winapi::HANDLE_ source_handle = std::move(*pipe).source().native_handle();
|
||||
|
||||
@@ -106,6 +106,6 @@ struct async_in_buffer : ::boost::process::v1::detail::windows::handler_base_ext
|
||||
};
|
||||
|
||||
|
||||
}}}}}
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
@@ -15,9 +15,9 @@
|
||||
#include <boost/winapi/handle_info.hpp>
|
||||
#include <boost/winapi/error_codes.hpp>
|
||||
#include <boost/asio/read.hpp>
|
||||
#include <boost/process/v1/detail/handler_base.hpp>
|
||||
#include <boost/process/v1/detail/used_handles.hpp>
|
||||
#include <boost/process/v1/detail/windows/asio_fwd.hpp>
|
||||
#include <boost/process/detail/handler_base.hpp>
|
||||
#include <boost/process/detail/used_handles.hpp>
|
||||
#include <boost/process/detail/windows/asio_fwd.hpp>
|
||||
|
||||
#include <istream>
|
||||
#include <memory>
|
||||
@@ -25,7 +25,7 @@
|
||||
#include <future>
|
||||
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail { namespace windows {
|
||||
namespace boost { namespace process { namespace detail { namespace windows {
|
||||
|
||||
|
||||
template <typename Executor>
|
||||
@@ -67,12 +67,12 @@ inline void apply_out_handles(Executor &e, void* handle, std::integral_constant<
|
||||
}
|
||||
|
||||
template<int p1, int p2, typename Buffer>
|
||||
struct async_out_buffer : ::boost::process::v1::detail::windows::handler_base_ext,
|
||||
::boost::process::v1::detail::windows::require_io_context
|
||||
struct async_out_buffer : ::boost::process::detail::windows::handler_base_ext,
|
||||
::boost::process::detail::windows::require_io_context
|
||||
{
|
||||
Buffer & buf;
|
||||
|
||||
std::shared_ptr<boost::process::v1::async_pipe> pipe;
|
||||
std::shared_ptr<boost::process::async_pipe> pipe;
|
||||
|
||||
|
||||
async_out_buffer(Buffer & buf) : buf(buf)
|
||||
@@ -99,7 +99,7 @@ struct async_out_buffer : ::boost::process::v1::detail::windows::handler_base_ex
|
||||
void on_setup(WindowsExecutor &exec)
|
||||
{
|
||||
if (!pipe)
|
||||
pipe = std::make_shared<boost::process::v1::async_pipe>(get_io_context(exec.seq));
|
||||
pipe = std::make_shared<boost::process::async_pipe>(get_io_context(exec.seq));
|
||||
apply_out_handles(exec, std::move(*pipe).sink().native_handle(),
|
||||
std::integral_constant<int, p1>(), std::integral_constant<int, p2>());
|
||||
}
|
||||
@@ -108,11 +108,11 @@ struct async_out_buffer : ::boost::process::v1::detail::windows::handler_base_ex
|
||||
|
||||
|
||||
template<int p1, int p2, typename Type>
|
||||
struct async_out_future : ::boost::process::v1::detail::windows::handler_base_ext,
|
||||
::boost::process::v1::detail::windows::require_io_context,
|
||||
::boost::process::v1::detail::uses_handles
|
||||
struct async_out_future : ::boost::process::detail::windows::handler_base_ext,
|
||||
::boost::process::detail::windows::require_io_context,
|
||||
::boost::process::detail::uses_handles
|
||||
{
|
||||
std::shared_ptr<boost::process::v1::async_pipe> pipe;
|
||||
std::shared_ptr<boost::process::async_pipe> pipe;
|
||||
std::shared_ptr<std::promise<Type>> promise = std::make_shared<std::promise<Type>>();
|
||||
std::shared_ptr<boost::asio::streambuf> buffer = std::make_shared<boost::asio::streambuf>();
|
||||
|
||||
@@ -173,7 +173,7 @@ struct async_out_future : ::boost::process::v1::detail::windows::handler_base_ex
|
||||
void on_setup(WindowsExecutor &exec)
|
||||
{
|
||||
if (!pipe)
|
||||
pipe = std::make_shared<boost::process::v1::async_pipe>(get_io_context(exec.seq));
|
||||
pipe = std::make_shared<boost::process::async_pipe>(get_io_context(exec.seq));
|
||||
|
||||
apply_out_handles(exec, std::move(*pipe).sink().native_handle(),
|
||||
std::integral_constant<int, p1>(), std::integral_constant<int, p2>());
|
||||
@@ -181,6 +181,6 @@ struct async_out_future : ::boost::process::v1::detail::windows::handler_base_ex
|
||||
};
|
||||
|
||||
|
||||
}}}}}
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
@@ -13,14 +13,14 @@
|
||||
#include <boost/winapi/get_last_error.hpp>
|
||||
#include <boost/winapi/access_rights.hpp>
|
||||
#include <boost/winapi/process.hpp>
|
||||
#include <boost/process/v1/detail/windows/basic_pipe.hpp>
|
||||
#include <boost/process/detail/windows/basic_pipe.hpp>
|
||||
#include <boost/asio/post.hpp>
|
||||
#include <boost/asio/windows/stream_handle.hpp>
|
||||
#include <atomic>
|
||||
#include <system_error>
|
||||
#include <string>
|
||||
|
||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail { namespace windows {
|
||||
namespace boost { namespace process { namespace detail { namespace windows {
|
||||
|
||||
inline std::string make_pipe_name()
|
||||
{
|
||||
@@ -290,7 +290,7 @@ async_pipe::async_pipe(boost::asio::io_context & ios_source,
|
||||
|
||||
::boost::winapi::HANDLE_ source = ::boost::winapi::create_named_pipe(
|
||||
#if defined(BOOST_NO_ANSI_APIS)
|
||||
::boost::process::v1::detail::convert(name).c_str(),
|
||||
::boost::process::detail::convert(name).c_str(),
|
||||
#else
|
||||
name.c_str(),
|
||||
#endif
|
||||
@@ -300,13 +300,13 @@ async_pipe::async_pipe(boost::asio::io_context & ios_source,
|
||||
|
||||
|
||||
if (source == boost::winapi::INVALID_HANDLE_VALUE_)
|
||||
::boost::process::v1::detail::throw_last_error("create_named_pipe(" + name + ") failed");
|
||||
::boost::process::detail::throw_last_error("create_named_pipe(" + name + ") failed");
|
||||
|
||||
_source.assign(source);
|
||||
|
||||
::boost::winapi::HANDLE_ sink = boost::winapi::create_file(
|
||||
#if defined(BOOST_NO_ANSI_APIS)
|
||||
::boost::process::v1::detail::convert(name).c_str(),
|
||||
::boost::process::detail::convert(name).c_str(),
|
||||
#else
|
||||
name.c_str(),
|
||||
#endif
|
||||
@@ -316,7 +316,7 @@ async_pipe::async_pipe(boost::asio::io_context & ios_source,
|
||||
nullptr);
|
||||
|
||||
if (sink == ::boost::winapi::INVALID_HANDLE_VALUE_)
|
||||
::boost::process::v1::detail::throw_last_error("create_file() failed");
|
||||
::boost::process::detail::throw_last_error("create_file() failed");
|
||||
|
||||
_sink.assign(sink);
|
||||
}
|
||||
@@ -480,6 +480,6 @@ inline bool operator!=(const basic_pipe<Char, Traits> & lhs, const async_pipe &
|
||||
!compare_handles(lhs.native_sink(), rhs.native_sink());
|
||||
}
|
||||
|
||||
}}}}}
|
||||
}}}}
|
||||
|
||||
#endif /* INCLUDE_BOOST_PIPE_DETAIL_WINDOWS_ASYNC_PIPE_HPP_ */
|
||||
@@ -9,8 +9,8 @@
|
||||
|
||||
#include <boost/algorithm/string/trim.hpp>
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
#include <boost/process/v1/shell.hpp>
|
||||
#include <boost/process/v1/detail/windows/handler.hpp>
|
||||
#include <boost/process/shell.hpp>
|
||||
#include <boost/process/detail/windows/handler.hpp>
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
@@ -21,8 +21,6 @@ namespace boost
|
||||
{
|
||||
namespace process
|
||||
{
|
||||
BOOST_PROCESS_V1_INLINE namespace v1
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
namespace windows
|
||||
@@ -63,12 +61,8 @@ inline std::string build_args(const std::string & exe, std::vector<std::string>
|
||||
arg += '"';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
arg = "\"\"";
|
||||
}
|
||||
|
||||
if (!st.empty())//first one does not need a preceding space
|
||||
if (!st.empty())//first one does not need a preceeding space
|
||||
st += ' ';
|
||||
|
||||
st += arg;
|
||||
@@ -111,12 +105,8 @@ inline std::wstring build_args(const std::wstring & exe, std::vector<std::wstrin
|
||||
arg += '"';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
arg = L"\"\"";
|
||||
}
|
||||
|
||||
if (!st.empty())//first one does not need a preceding space
|
||||
if (!st.empty())//first one does not need a preceeding space
|
||||
st += L' ';
|
||||
|
||||
st += arg;
|
||||
@@ -199,7 +189,7 @@ private:
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* INCLUDE_BOOST_PROCESS_WINDOWS_ARGS_HPP_ */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user