mirror of
https://github.com/boostorg/process.git
synced 2026-01-22 17:32:42 +00:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
080f885353 | ||
|
|
0bd32a19e0 | ||
|
|
9ddac91341 |
@@ -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("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("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("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",
|
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),
|
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:
|
# A set of jobs based on the earlier .travis.yml configuration:
|
||||||
|
|||||||
@@ -26,7 +26,9 @@ set B2_TARGETS=libs/!SELF!/test
|
|||||||
cd !BOOST_ROOT!
|
cd !BOOST_ROOT!
|
||||||
call bootstrap.bat
|
call bootstrap.bat
|
||||||
b2 headers
|
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" (
|
) else if "%DRONE_JOB_BUILDTYPE%" == "standalone-windows" (
|
||||||
|
|
||||||
REM not used
|
REM not used
|
||||||
|
|||||||
211
.github/workflows/ci.yml
vendored
211
.github/workflows/ci.yml
vendored
@@ -17,6 +17,10 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
|
- toolset: gcc-4.8
|
||||||
|
cxxstd: "11"
|
||||||
|
os: ubuntu-18.04
|
||||||
|
install: g++-4.8
|
||||||
- toolset: gcc-5
|
- toolset: gcc-5
|
||||||
cxxstd: "11,14,1z"
|
cxxstd: "11,14,1z"
|
||||||
os: ubuntu-18.04
|
os: ubuntu-18.04
|
||||||
@@ -28,10 +32,21 @@ jobs:
|
|||||||
- toolset: gcc-7
|
- toolset: gcc-7
|
||||||
cxxstd: "11,14,17"
|
cxxstd: "11,14,17"
|
||||||
os: ubuntu-18.04
|
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
|
- toolset: gcc-10
|
||||||
cxxstd: "11,14,17,2a"
|
cxxstd: "11,14,17,2a"
|
||||||
os: ubuntu-20.04
|
os: ubuntu-20.04
|
||||||
install: g++-10
|
install: g++-10
|
||||||
|
- toolset: gcc-11
|
||||||
|
cxxstd: "11,14,17,2a"
|
||||||
|
os: ubuntu-20.04
|
||||||
|
install: g++-11
|
||||||
- toolset: gcc-12
|
- toolset: gcc-12
|
||||||
cxxstd: "11,14,17,20,2b"
|
cxxstd: "11,14,17,20,2b"
|
||||||
os: ubuntu-22.04
|
os: ubuntu-22.04
|
||||||
@@ -141,43 +156,6 @@ jobs:
|
|||||||
cd ../boost-root
|
cd ../boost-root
|
||||||
./b2 -j3 libs/$LIBRARY/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} variant=debug,release
|
./b2 -j3 libs/$LIBRARY/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} variant=debug,release
|
||||||
|
|
||||||
alpine-linux:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
container:
|
|
||||||
image: alpine:3.20.1
|
|
||||||
steps:
|
|
||||||
- name: Install packages
|
|
||||||
run: apk add g++ git python3 linux-headers
|
|
||||||
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Setup Boost
|
|
||||||
run: |
|
|
||||||
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
|
|
||||||
LIBRARY=${GITHUB_REPOSITORY#*/}
|
|
||||||
echo LIBRARY: $LIBRARY
|
|
||||||
echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV
|
|
||||||
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
|
|
||||||
echo GITHUB_REF: $GITHUB_REF
|
|
||||||
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
|
|
||||||
REF=${REF#refs/heads/}
|
|
||||||
echo REF: $REF
|
|
||||||
BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true
|
|
||||||
echo BOOST_BRANCH: $BOOST_BRANCH
|
|
||||||
cd ..
|
|
||||||
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
|
|
||||||
cd boost-root
|
|
||||||
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
|
|
||||||
git submodule update --init tools/boostdep
|
|
||||||
python3 tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY
|
|
||||||
./bootstrap.sh
|
|
||||||
./b2 -d0 headers
|
|
||||||
|
|
||||||
- name: Run tests
|
|
||||||
run: |
|
|
||||||
cd ../boost-root
|
|
||||||
./b2 -j3 libs/$LIBRARY/test toolset=gcc cxxstd=23 variant=debug,release
|
|
||||||
|
|
||||||
windows:
|
windows:
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
@@ -236,3 +214,162 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
cd ../boost-root
|
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
|
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)
|
project(boost_process VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX)
|
||||||
|
|
||||||
add_library(boost_process
|
add_library(boost_process INTERFACE)
|
||||||
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 ALIAS boost_process)
|
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
|
target_link_libraries(boost_process
|
||||||
PUBLIC
|
INTERFACE
|
||||||
Boost::algorithm
|
Boost::algorithm
|
||||||
Boost::asio
|
Boost::asio
|
||||||
Boost::config
|
Boost::config
|
||||||
@@ -46,27 +28,9 @@ target_link_libraries(boost_process
|
|||||||
Boost::winapi
|
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")
|
if(BUILD_TESTING AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test/CMakeLists.txt")
|
||||||
|
|
||||||
add_subdirectory(test)
|
add_subdirectory(test)
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|||||||
47
build.jam
47
build.jam
@@ -1,47 +0,0 @@
|
|||||||
# Copyright René Ferdinand Rivera Morell 2024
|
|
||||||
# Distributed under the Boost Software License, Version 1.0.
|
|
||||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
|
||||||
# http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
require-b2 5.2 ;
|
|
||||||
|
|
||||||
import feature : feature ;
|
|
||||||
|
|
||||||
feature boost.process.fs : boost std : optional propagated ;
|
|
||||||
feature boost.process.disable-close-range : on off : optional ;
|
|
||||||
|
|
||||||
constant boost_dependencies :
|
|
||||||
/boost/algorithm//boost_algorithm
|
|
||||||
/boost/asio//boost_asio
|
|
||||||
/boost/assert//boost_assert
|
|
||||||
/boost/config//boost_config
|
|
||||||
/boost/core//boost_core
|
|
||||||
/boost/fusion//boost_fusion
|
|
||||||
/boost/io//boost_io
|
|
||||||
/boost/iterator//boost_iterator
|
|
||||||
/boost/move//boost_move
|
|
||||||
/boost/optional//boost_optional
|
|
||||||
/boost/system//boost_system
|
|
||||||
/boost/throw_exception//boost_throw_exception
|
|
||||||
/boost/tokenizer//boost_tokenizer
|
|
||||||
/boost/type_index//boost_type_index
|
|
||||||
/boost/type_traits//boost_type_traits
|
|
||||||
/boost/utility//boost_utility
|
|
||||||
/boost/winapi//boost_winapi ;
|
|
||||||
|
|
||||||
project /boost/process
|
|
||||||
: common-requirements
|
|
||||||
<include>include
|
|
||||||
: default-build
|
|
||||||
<boost.process.fs>boost
|
|
||||||
;
|
|
||||||
|
|
||||||
explicit
|
|
||||||
[ alias boost_process : build//boost_process ]
|
|
||||||
[ alias all : boost_process example example/v2 test ]
|
|
||||||
;
|
|
||||||
|
|
||||||
call-if : boost-library process
|
|
||||||
: install boost_process
|
|
||||||
;
|
|
||||||
|
|
||||||
@@ -1,73 +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-search /boost/config/checks ;
|
|
||||||
import 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
|
|
||||||
: common-requirements
|
|
||||||
<library>$(boost_dependencies)
|
|
||||||
<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
|
|
||||||
;
|
|
||||||
|
|
||||||
lib shell32 ;
|
|
||||||
lib advapi32 ;
|
|
||||||
lib ntdll ;
|
|
||||||
lib user32 ;
|
|
||||||
lib ws2_32 ;
|
|
||||||
|
|
||||||
lib kvm ;
|
|
||||||
lib procstat ;
|
|
||||||
|
|
||||||
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//boost_filesystem
|
|
||||||
<boost.process.disable-close-range>on:<define>BOOST_PROCESS_V2_POSIX_FORCE_DISABLE_CLOSE_RANGE=1
|
|
||||||
<target-os>windows:<library>shell32
|
|
||||||
<target-os>windows:<library>user32
|
|
||||||
<target-os>windows:<library>ntdll
|
|
||||||
<target-os>windows:<library>advapi32
|
|
||||||
<target-os>windows:<library>ws2_32
|
|
||||||
<target-os>bsd:<library>kvm
|
|
||||||
<target-os>freebsd:<library>kvm
|
|
||||||
<target-os>freebsd:<library>procstat
|
|
||||||
<target-os>netbsd:<library>kvm
|
|
||||||
<target-os>openbsd:<library>kvm
|
|
||||||
<target-os>solaris:<library>kvm
|
|
||||||
: usage-requirements
|
|
||||||
<link>shared:<define>BOOST_PROCESS_DYN_LINK=1
|
|
||||||
<boost.process.fs>boost:<library>/boost/filesystem//boost_filesystem
|
|
||||||
;
|
|
||||||
@@ -14,28 +14,25 @@ using doxygen ;
|
|||||||
|
|
||||||
local images = [ glob images/*.svg ] ;
|
local images = [ glob images/*.svg ] ;
|
||||||
install images : $(images) : <location>html/boost_process ;
|
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 ;
|
import type ;
|
||||||
type.register XMLPROCESSWORKAROUND : : XML ;
|
type.register XMLPROCESSWORKAROUND : : XML ;
|
||||||
import generators ;
|
import generators ;
|
||||||
generators.register-standard common.copy : XML : XMLPROCESSWORKAROUND ;
|
generators.register-standard common.copy : XML : XMLPROCESSWORKAROUND ;
|
||||||
|
|
||||||
xmlprocessworkaround posix_pseudocode : v1/posix_pseudocode.xml ;
|
xmlprocessworkaround posix_pseudocode : posix_pseudocode.xml ;
|
||||||
xmlprocessworkaround windows_pseudocode : v1/windows_pseudocode.xml ;
|
xmlprocessworkaround windows_pseudocode : windows_pseudocode.xml ;
|
||||||
|
|
||||||
path-constant INCLUDES : ../include ;
|
path-constant INCLUDES : ../../.. ;
|
||||||
|
|
||||||
doxygen reference_v1
|
doxygen autodoc
|
||||||
:
|
:
|
||||||
$(INCLUDES)/boost/process/v1.hpp
|
$(INCLUDES)/boost/process.hpp
|
||||||
[ glob $(INCLUDES)/boost/process/v1/*.hpp ]
|
[ glob $(INCLUDES)/boost/process/*.hpp ]
|
||||||
:
|
:
|
||||||
<doxygen:param>EXCLUDE_SYMBOLS=BOOST_ASIO_INITFN_RESULT_TYPE
|
<doxygen:param>EXCLUDE_SYMBOLS=BOOST_ASIO_INITFN_RESULT_TYPE
|
||||||
<doxygen:param>"PREDEFINED=\\
|
<doxygen:param>PREDEFINED=BOOST_PROCESS_DOXYGEN
|
||||||
BOOST_PROCESS_DOXYGEN=1 \\
|
|
||||||
BOOST_PROCESS_V1_INLINE=
|
|
||||||
"
|
|
||||||
<doxygen:param>HIDE_UNDOC_CLASSES=YES
|
<doxygen:param>HIDE_UNDOC_CLASSES=YES
|
||||||
<doxygen:param>HIDE_UNDOC_MEMBERS=YES
|
<doxygen:param>HIDE_UNDOC_MEMBERS=YES
|
||||||
<doxygen:param>EXAMPLE_PATH=.
|
<doxygen:param>EXAMPLE_PATH=.
|
||||||
@@ -63,13 +60,13 @@ doxygen reference_v2
|
|||||||
\"BOOST_PROCESS_V2_END_NAMESPACE= } } }\" \\
|
\"BOOST_PROCESS_V2_END_NAMESPACE= } } }\" \\
|
||||||
BOOST_PROCESS_V2_NAMESPACE=boost::process::v2 \\
|
BOOST_PROCESS_V2_NAMESPACE=boost::process::v2 \\
|
||||||
BOOST_PROCESS_V2_DECL \\
|
BOOST_PROCESS_V2_DECL \\
|
||||||
|
BOOST_PROCESS_V2_SOURCE \\
|
||||||
BOOST_PROCESS_V2_INITFN_AUTO_RESULT_TYPE(x,y)=deduced \\
|
BOOST_PROCESS_V2_INITFN_AUTO_RESULT_TYPE(x,y)=deduced \\
|
||||||
BOOST_PROCESS_V2_COMPLETION_TOKEN_FOR(X)=Token \\
|
BOOST_PROCESS_V2_COMPLETION_TOKEN_FOR(X)=Token \\
|
||||||
BOOST_PROCESS_V2_DEFAULT_COMPLETION_TOKEN_TYPE(E)=DEFAULT_TYPE \\
|
BOOST_PROCESS_V2_DEFAULT_COMPLETION_TOKEN_TYPE(E)=DEFAULT_TYPE \\
|
||||||
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN=DEFAULT \\
|
BOOST_ASIO_DEFAULT_COMPLETION_TOKEN=DEFAULT \\
|
||||||
BOOST_CONSTEXPR=constexpr \\
|
BOOST_CONSTEXPR=constexpr \\
|
||||||
BOOST_CXX14_CONSTEXPR=constexpr \\
|
BOOST_CXX14_CONSTEXPR=constexpr \\
|
||||||
BOOST_PROCESS_V2_INLINE= \\
|
|
||||||
BOOST_ATTRIBUTE_NODISCARD=[[nodiscard]]
|
BOOST_ATTRIBUTE_NODISCARD=[[nodiscard]]
|
||||||
"
|
"
|
||||||
<doxygen.doxproc.id>reference_v2
|
<doxygen.doxproc.id>reference_v2
|
||||||
@@ -87,7 +84,7 @@ boostbook standalone
|
|||||||
:
|
:
|
||||||
process.qbk
|
process.qbk
|
||||||
:
|
:
|
||||||
<dependency>reference_v1
|
<dependency>autodoc
|
||||||
<dependency>reference_v2
|
<dependency>reference_v2
|
||||||
<dependency>images
|
<dependency>images
|
||||||
<dependency>images_glob
|
<dependency>images_glob
|
||||||
@@ -98,7 +95,7 @@ boostbook standalone
|
|||||||
###############################################################################
|
###############################################################################
|
||||||
alias boostdoc
|
alias boostdoc
|
||||||
: standalone/<format>docbook
|
: standalone/<format>docbook
|
||||||
:
|
:
|
||||||
: <dependency>images_glob
|
: <dependency>images_glob
|
||||||
: ;
|
: ;
|
||||||
explicit boostdoc ;
|
explicit boostdoc ;
|
||||||
|
|||||||
@@ -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
|
As the name suggests, named pipes have a string identifier. This means that a
|
||||||
handle to them can be obtained with the identifier, too.
|
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.
|
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],
|
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.
|
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]
|
[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
|
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:
|
will be called on the respective events on process launching. The names are:
|
||||||
|
|
||||||
*`boost::process::v1::on_setup`
|
*`boost::process::on_setup`
|
||||||
*`boost::process::v1::on_error`
|
*`boost::process::on_error`
|
||||||
*`boost::process::v1::on_success`
|
*`boost::process::on_success`
|
||||||
|
|
||||||
|
|
||||||
As an example:
|
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_exit__ [globalref boost::process::on_exit on_exit]]
|
||||||
[def __on_success__ [globalref boost::process::v1::extend::on_success ex::on_success]]
|
[def __on_success__ [globalref boost::process::extend::on_success ex::on_success]]
|
||||||
[def __child__ [classref boost::process::v1::child child]]
|
[def __child__ [classref boost::process::child child]]
|
||||||
[def __handler__ [classref boost::process::v1::extend::handler handler]]
|
[def __handler__ [classref boost::process::extend::handler handler]]
|
||||||
[def __on_success__ [memberref boost::process::v1::extend::handler::on_success on_success]]
|
[def __on_success__ [memberref boost::process::extend::handler::on_success on_success]]
|
||||||
[def __posix_executor__ [classref boost::process::v1::extend::posix_executor ex::posix_executor]]
|
[def __posix_executor__ [classref boost::process::extend::posix_executor ex::posix_executor]]
|
||||||
[def __windows_executor__ [classref boost::process::v1::extend::windows_executor ex::windows_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 __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 __require_io_context__ [classref boost::process::extend::require_io_context ex::require_io_context]]
|
||||||
[def __async_handler__ [classref boost::process::v1::extend::async_handler ex::async_handler]]
|
[def __async_handler__ [classref boost::process::extend::async_handler ex::async_handler]]
|
||||||
[def __get_io_context__ [funcref boost::process::v1::extend::get_io_context ex::get_io_context]]
|
[def __get_io_context__ [funcref boost::process::extend::get_io_context ex::get_io_context]]
|
||||||
|
|
||||||
[section:extend Extensions]
|
[section:extend Extensions]
|
||||||
To extend the library, the header [headerref boost/process/extend.hpp extend] is provided.
|
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.
|
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.
|
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.
|
the executor gets passed.
|
||||||
|
|
||||||
[section:structure Structure]
|
[section:structure Structure]
|
||||||
@@ -24,9 +24,9 @@ the executor gets passed.
|
|||||||
The executor calls different handlers of the initializers during the process launch.
|
The executor calls different handlers of the initializers during the process launch.
|
||||||
The basic structure consists of three functions, as given below:
|
The basic structure consists of three functions, as given below:
|
||||||
|
|
||||||
* [globalref boost::process::v1::extend::on_setup on_setup]
|
* [globalref boost::process::extend::on_setup on_setup]
|
||||||
* [globalref boost::process::v1::extend::on_error on_error]
|
* [globalref boost::process::extend::on_error on_error]
|
||||||
* [globalref boost::process::v1::extend::on_success on_success]
|
* [globalref boost::process::extend::on_success on_success]
|
||||||
|
|
||||||
'''
|
'''
|
||||||
<imagedata fileref="boost_process/windows_exec.svg"/>
|
<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:
|
Additionally posix provides three more handlers, listed below:
|
||||||
|
|
||||||
* [globalref boost::process::v1::extend::on_fork_error on_fork_error]
|
* [globalref boost::process::extend::on_fork_error on_fork_error]
|
||||||
* [globalref boost::process::v1::extend::on_exec_setup on_exec_setup]
|
* [globalref boost::process::extend::on_exec_setup on_exec_setup]
|
||||||
* [globalref boost::process::v1::extend::on_exec_error on_exec_error]
|
* [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]
|
[endsect]
|
||||||
[section:simple Simple extensions]
|
[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.
|
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]
|
To see which members the executor has, refer to [classref boost::process::extend::windows_executor windows_executor]
|
||||||
and [classref boost::process::v1::extend::posix_executor posix_executor].
|
and [classref boost::process::extend::posix_executor posix_executor].
|
||||||
|
|
||||||
[note Combined with __on_exit__ this can also handle the process exit.]
|
[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]
|
[section:handler Handler Types]
|
||||||
|
|
||||||
Since the previous example is in a functional style, it is not very reusable.
|
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.
|
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.]
|
[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]
|
[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__.
|
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__
|
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). ]
|
[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);
|
__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]
|
[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:
|
Here's a simple example of how to start a program with Boost.Process:
|
||||||
|
|
||||||
[def ipstream [classref boost::process::v1::ipstream ipstream]]
|
[def ipstream [classref boost::process::ipstream ipstream]]
|
||||||
[def system [funcref boost::process::v1::system system]]
|
[def system [funcref boost::process::system system]]
|
||||||
[def std_out [globalref boost::process::v1::std_out std_out]]
|
[def std_out [globalref boost::process::std_out std_out]]
|
||||||
[def child [globalref boost::process::v1::child child]]
|
[def child [globalref boost::process::child child]]
|
||||||
[def boost/process.hpp [headerref boost/process.hpp boost/process.hpp]]
|
[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::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]]
|
[def std::getline [@http://en.cppreference.com/w/cpp/string/basic_string/getline std::getline]]
|
||||||
|
|
||||||
[import ../../example/intro.cpp]
|
[import ../example/intro.cpp]
|
||||||
[intro]
|
[intro]
|
||||||
|
|
||||||
[endsect]
|
[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 introduction.qbk]
|
||||||
[include v2.qbk]
|
[include concepts.qbk]
|
||||||
|
[include tutorial.qbk]
|
||||||
|
[include design.qbk]
|
||||||
|
[include extend.qbk]
|
||||||
|
[include faq.qbk]
|
||||||
|
[xinclude autodoc.xml]
|
||||||
[include acknowledgements.qbk]
|
[include acknowledgements.qbk]
|
||||||
|
[include v2.qbk]
|
||||||
@@ -1,49 +1,49 @@
|
|||||||
[def bp::system [funcref boost::process::v1::system bp::system]]
|
[def bp::system [funcref boost::process::system bp::system]]
|
||||||
[def bp::async_system [funcref boost::process::v1::async_system bp::async_system]]
|
[def bp::async_system [funcref boost::process::async_system bp::async_system]]
|
||||||
[def bp::spawn [funcref boost::process::v1::spawn bp::spawn]]
|
[def bp::spawn [funcref boost::process::spawn bp::spawn]]
|
||||||
[def bp::child [classref boost::process::v1::child bp::child]]
|
[def bp::child [classref boost::process::child bp::child]]
|
||||||
[def bp::cmd [classref boost::process::v1::cmd bp::cmd]]
|
[def bp::cmd [classref boost::process::cmd bp::cmd]]
|
||||||
[def bp::group [classref boost::process::v1::group bp::group]]
|
[def bp::group [classref boost::process::group bp::group]]
|
||||||
[def bp::ipstream [classref boost::process::v1::ipstream bp::ipstream]]
|
[def bp::ipstream [classref boost::process::ipstream bp::ipstream]]
|
||||||
[def bp::opstream [classref boost::process::v1::opstream bp::opstream]]
|
[def bp::opstream [classref boost::process::opstream bp::opstream]]
|
||||||
[def bp::pstream [classref boost::process::v1::pstream bp::pstream]]
|
[def bp::pstream [classref boost::process::pstream bp::pstream]]
|
||||||
[def bp::pipe [classref boost::process::v1::pipe bp::pipe]]
|
[def bp::pipe [classref boost::process::pipe bp::pipe]]
|
||||||
[def bp::async_pipe [classref boost::process::v1::async_pipe bp::async_pipe]]
|
[def bp::async_pipe [classref boost::process::async_pipe bp::async_pipe]]
|
||||||
[def bp::search_path [funcref boost::process::v1::search_path bp::search_path]]
|
[def bp::search_path [funcref boost::process::search_path bp::search_path]]
|
||||||
[def boost_org [@www.boost.org "www.boost.org"]]
|
[def boost_org [@www.boost.org "www.boost.org"]]
|
||||||
[def std::system [@http://en.cppreference.com/w/cpp/utility/program/system std::system]]
|
[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_running [memberref boost::process::child::running running]]
|
||||||
[def child_wait [memberref boost::process::v1::child::wait wait]]
|
[def child_wait [memberref boost::process::child::wait wait]]
|
||||||
[def child_wait_for [memberref boost::process::v1::child::wait_for wait_for]]
|
[def child_wait_for [memberref boost::process::child::wait_for wait_for]]
|
||||||
[def child_exit_code [memberref boost::process::v1::child::exit_code exit_code]]
|
[def child_exit_code [memberref boost::process::child::exit_code exit_code]]
|
||||||
[def group_wait_for [memberref boost::process::v1::group::wait_for wait_for]]
|
[def group_wait_for [memberref boost::process::group::wait_for wait_for]]
|
||||||
[def bp::on_exit [globalref boost::process::v1::on_exit bp::on_exit]]
|
[def bp::on_exit [globalref boost::process::on_exit bp::on_exit]]
|
||||||
[def bp::null [globalref boost::process::v1::null bp::null]]
|
[def bp::null [globalref boost::process::null bp::null]]
|
||||||
[def child_terminate [memberref boost::process::v1::child::terminate terminate]]
|
[def child_terminate [memberref boost::process::child::terminate terminate]]
|
||||||
[def group_terminate [memberref boost::process::v1::group::terminate terminate]]
|
[def group_terminate [memberref boost::process::group::terminate terminate]]
|
||||||
[def group_wait [memberref boost::process::v1::group::wait wait]]
|
[def group_wait [memberref boost::process::group::wait wait]]
|
||||||
[def bp::std_in [globalref boost::process::v1::std_in bp::std_in]]
|
[def bp::std_in [globalref boost::process::std_in bp::std_in]]
|
||||||
[def bp::std_out [globalref boost::process::v1::std_out bp::std_out]]
|
[def bp::std_out [globalref boost::process::std_out bp::std_out]]
|
||||||
[def bp::std_err [globalref boost::process::v1::std_err bp::std_err]]
|
[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 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_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 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::environment [classref boost::process::basic_environment bp::environment]]
|
||||||
[def bp::native_environment [classref boost::process::v1::basic_native_environment bp::native_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 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::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 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_for__ [memberref boost::process::child::wait_for wait_for]]
|
||||||
[def __wait_until__ [memberref boost::process::v1::child::wait_until wait_until]]
|
[def __wait_until__ [memberref boost::process::child::wait_until wait_until]]
|
||||||
[def __detach__ [memberref boost::process::v1::child::detach detach]]
|
[def __detach__ [memberref boost::process::child::detach detach]]
|
||||||
|
|
||||||
[def __reference__ [link process.reference reference]]
|
[def __reference__ [link process.reference reference]]
|
||||||
[def __concepts__ [link boost_process.concepts concepts]]
|
[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::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 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]
|
[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
|
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");
|
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` 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");
|
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`.]
|
This also includes to add a file suffix on windows, such as `.exe` or `.bat`.]
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
[section:launch_mode Launch functions]
|
[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,
|
our program will wait until the child process is completed. This may be unwanted,
|
||||||
especially since compiling can take a while.
|
especially since compiling can take a while.
|
||||||
|
|
||||||
In order to avoid that, boost.process provides several ways to launch a process.
|
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
|
Besides the already mentioned [funcref boost::process::system system] function and its
|
||||||
asynchronous version [funcref boost::process::v1::async_system async_system],
|
asynchronous version [funcref boost::process::async_system async_system],
|
||||||
we can also use the [funcref boost::process::v1::spawn spawn] function or the
|
we can also use the [funcref boost::process::spawn spawn] function or the
|
||||||
[classref boost::process::v1::child child] class.
|
[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.
|
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,
|
This is not what we need for compiling, but maybe we want to entertain the user,
|
||||||
while compiling:
|
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.
|
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");
|
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.
|
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.
|
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.
|
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],
|
Boost.process provides the pipestream ([classref boost::process::ipstream ipstream],
|
||||||
[classref boost::process::v1::opstream opstream], [classref boost::process::v1::pstream pstream]) to
|
[classref boost::process::opstream opstream], [classref boost::process::pstream pstream]) to
|
||||||
wrap around the [classref boost::process::v1::pipe pipe] and provide an implementation of the
|
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_istream std::istream],
|
||||||
[@http://en.cppreference.com/w/cpp/io/basic_ostream std::ostream] and
|
[@http://en.cppreference.com/w/cpp/io/basic_ostream std::ostream] and
|
||||||
[@http://en.cppreference.com/w/cpp/io/basic_iostream std::iostream] interface.
|
[@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
|
What this does is redirect the `stdout` of the process into a pipe and we read this
|
||||||
synchronously.
|
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.
|
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
|
`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.
|
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),
|
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
|
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::v1::pipe pipe] as shown above.
|
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,
|
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.
|
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
|
[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
|
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.
|
(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");
|
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
|
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::group g;
|
||||||
bp::child c("make", 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();
|
g.group_terminate();
|
||||||
|
|
||||||
c.child_wait(); //to avoid a zombie process & get the exit code
|
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.
|
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
|
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
|
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"});
|
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.
|
`environment::value_view` can be used to iterate those.
|
||||||
|
|
||||||
Beyond that, the requirements on an environment are a low as possible;
|
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.
|
as to have the right value comparisons.
|
||||||
|
|
||||||
To note is the `find_executable` functions, which searches in an environment for an executable.
|
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 =
|
std::unordered_map<environment::key, environment::value> my_env =
|
||||||
{
|
{
|
||||||
{"SECRET", "THIS_IS_A_TEST"},
|
{"SECRET", "THIS_IS_A_TEST"}
|
||||||
{"PATH", {"/bin", "/usr/bin"}}
|
{"PATH", {"/bin", "/usr/bin"}
|
||||||
};
|
};
|
||||||
|
|
||||||
auto other_exe = environment::find_executable("g++", my_env);
|
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;
|
asio::io_context ctx;
|
||||||
std::unordered_map<environment::key, environment::value> my_env =
|
std::unordered_map<environment::key, environment::value> my_env =
|
||||||
{
|
{
|
||||||
{"SECRET", "THIS_IS_A_TEST"},
|
{"SECRET", "THIS_IS_A_TEST"}
|
||||||
{"PATH", {"/bin", "/usr/bin"}}
|
{"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 proc(ctx, exe, {"main.cpp"}, process_environment(my_env));
|
||||||
process pro2(ctx, exe, {"test.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;
|
extern asio::io_context ctx;
|
||||||
process proc(ctx, "./test", {"--help"}, process_io{nullptr, {}, {}}, process_environment(my_env));
|
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
|
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.
|
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.
|
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.
|
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.
|
Thus the wait_for used signals or fork, which was all but safe.
|
||||||
Since process v2 is based on asio and thus supports cancellation,
|
Since process v2 is based on asio and thus supports cancellation,
|
||||||
@@ -73,6 +73,14 @@ Instead of using ascii-APIs on windows, process V2 just assumes UTF-8 everywhere
|
|||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
|
[section:src Separate compilation]
|
||||||
|
|
||||||
|
Boost.process v2 supports separate compilation similar to other boost libraries.
|
||||||
|
It can be achieved by defining `BOOST_PROCESS_V2_SEPARATE_COMPILATION` and including
|
||||||
|
`<process/v2/src.hpp>` in a single compile unit.
|
||||||
|
|
||||||
|
[endsect]
|
||||||
|
|
||||||
[section:limit_fd Fd safe by default]
|
[section:limit_fd Fd safe by default]
|
||||||
|
|
||||||
While not a problem on windows (since HANDLEs get manually enabled for inheritance),
|
While not a problem on windows (since HANDLEs get manually enabled for inheritance),
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ A launcher is invoked through the call operator.
|
|||||||
```
|
```
|
||||||
auto l = windows::as_user_launcher((HANDLE)0xDEADBEEF);
|
auto l = windows::as_user_launcher((HANDLE)0xDEADBEEF);
|
||||||
asio::io_context ctx;
|
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", {});
|
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.
|
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:
|
// 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>
|
template<typename Launcher>
|
||||||
error_code on_setup(Launcher & launcher, const filesystem::path &executable, const char * const * (&cmd_line));
|
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>
|
template<typename Launcher>
|
||||||
void on_error(Launcher & launcher, const filesystem::path &executable, const char * const * (&cmd_line),
|
void on_error(Launcher & launcher, const filesystem::path &executable, const char * const * (&cmd_line),
|
||||||
const error_code & ec);
|
const error_code & ec);
|
||||||
@@ -56,7 +56,7 @@ Thus some calls to the initializers occur after forking from the child process.
|
|||||||
template<typename Launcher>
|
template<typename Launcher>
|
||||||
void on_success(Launcher & launcher, const filesystem::path &executable, const char * const * (&cmd_line));
|
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>
|
template<typename Launcher>
|
||||||
void on_fork_error(Launcher & launcher, const filesystem::path &executable, const char * const * (&cmd_line),
|
void on_fork_error(Launcher & launcher, const filesystem::path &executable, const char * const * (&cmd_line),
|
||||||
const error_code & ec);
|
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]
|
[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
|
struct custom_initializer
|
||||||
@@ -103,7 +103,7 @@ Windows launchers are pretty straight forward, they will call the following func
|
|||||||
template<typename Launcher>
|
template<typename Launcher>
|
||||||
error_code on_setup(Launcher & launcher, const filesystem::path &executable, std::wstring &cmd_line);
|
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>
|
template<typename Launcher>
|
||||||
void on_error(Launcher & launcher, const filesystem::path &executable, std::wstring &cmd_line,
|
void on_error(Launcher & launcher, const filesystem::path &executable, std::wstring &cmd_line,
|
||||||
const error_code & ec);
|
const error_code & ec);
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ also returned from `.wait()`.
|
|||||||
```
|
```
|
||||||
|
|
||||||
The normal exit-code is what the subprocess returned from `main`;
|
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`.
|
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]
|
[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).
|
`.terminate` will cause the subprocess to exit immediately (`SIGKILL` on posix).
|
||||||
This is the only reliable & portable way to end a subprocess.
|
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]
|
[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));
|
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::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;
|
asio::cancellation_signal sig;
|
||||||
async_execute(process("/usr/bin/g++", {"hello_world.cpp"}),
|
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)
|
if (!ec)
|
||||||
sig.emit(asio::cancellation_type::terminal);
|
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::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 */ }});
|
process proc(ctx, "/usr/bin/g++", {"--version"}, process_stdio{{ /* in to default */}, rp, { /* err to default */ }});
|
||||||
std::string output;
|
std::string output;
|
||||||
@@ -23,7 +23,7 @@ automatically connected and the other side will get assigned to the child proces
|
|||||||
proc.wait();
|
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]
|
[endsect]
|
||||||
|
|
||||||
@@ -86,4 +86,4 @@ It starts a process and connects pipes for stdin and stdout, so that the popen o
|
|||||||
|
|
||||||
[endsect]
|
[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>
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
project : requirements
|
project : requirements
|
||||||
<library>/boost/process//boost_process
|
<include>../../..
|
||||||
<toolset>msvc:<define>_SCL_SECURE_NO_WARNINGS
|
<toolset>msvc:<define>_SCL_SECURE_NO_WARNINGS
|
||||||
<target-os>windows:<define>WIN32_LEAN_AND_MEAN
|
<target-os>windows:<define>WIN32_LEAN_AND_MEAN
|
||||||
;
|
;
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ int main()
|
|||||||
bp::std_in < bp::null //null in
|
bp::std_in < bp::null //null in
|
||||||
);
|
);
|
||||||
|
|
||||||
boost::process::v1::filesystem::path p = "input.txt";
|
boost::process::filesystem::path p = "input.txt";
|
||||||
|
|
||||||
bp::system(
|
bp::system(
|
||||||
"test.exe",
|
"test.exe",
|
||||||
|
|||||||
@@ -8,8 +8,8 @@
|
|||||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
#include <boost/process.hpp>
|
#include <boost/process.hpp>
|
||||||
#include <boost/process/v1/posix.hpp>
|
#include <boost/process/posix.hpp>
|
||||||
#include <boost/process/v1/extend.hpp>
|
#include <boost/process/extend.hpp>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
#include <boost/process.hpp>
|
#include <boost/process.hpp>
|
||||||
#include <boost/process/v1/filesystem.hpp>
|
#include <boost/process/filesystem.hpp>
|
||||||
|
|
||||||
namespace bp = boost::process;
|
namespace bp = boost::process;
|
||||||
|
|
||||||
@@ -19,9 +19,9 @@ int main()
|
|||||||
bp::start_dir="../foo"
|
bp::start_dir="../foo"
|
||||||
);
|
);
|
||||||
|
|
||||||
boost::process::v1::filesystem::path exe = "test.exe";
|
boost::process::filesystem::path exe = "test.exe";
|
||||||
bp::system(
|
bp::system(
|
||||||
boost::process::v1::filesystem::absolute(exe),
|
boost::process::filesystem::absolute(exe),
|
||||||
bp::start_dir="../foo"
|
bp::start_dir="../foo"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,12 +4,14 @@
|
|||||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
project : requirements
|
project : requirements
|
||||||
|
<include>../../..
|
||||||
<toolset>msvc:<define>_SCL_SECURE_NO_WARNINGS
|
<toolset>msvc:<define>_SCL_SECURE_NO_WARNINGS
|
||||||
<target-os>windows:<define>WIN32_LEAN_AND_MEAN
|
<target-os>windows:<define>WIN32_LEAN_AND_MEAN
|
||||||
<link>static
|
|
||||||
;
|
;
|
||||||
|
|
||||||
import testing ;
|
import testing ;
|
||||||
|
|
||||||
exe intro : intro.cpp ;
|
alias filesystem : /boost//filesystem : <link>static ;
|
||||||
exe intro_popen : intro_popen.cpp : <boost.process.fs>boost ;
|
|
||||||
|
exe intro : intro.cpp filesystem ;
|
||||||
|
exe intro_popen : intro_popen.cpp filesystem ;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2022 Klemens Morgenstern
|
// Copyright (c) 2022Klemens Morgernstern
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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 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
|
// 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 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
#include <boost/process.hpp>
|
#include <boost/process.hpp>
|
||||||
#include <boost/process/v1/extend.hpp>
|
#include <boost/process/extend.hpp>
|
||||||
#include <boost/process/v1/windows.hpp>
|
#include <boost/process/windows.hpp>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|||||||
@@ -19,16 +19,24 @@
|
|||||||
* boost.process header files.
|
* boost.process header files.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if !defined(BOOST_PROCESS_VERSION)
|
#include <boost/process/args.hpp>
|
||||||
#define BOOST_PROCESS_VERSION 1
|
#include <boost/process/async.hpp>
|
||||||
#endif
|
#include <boost/process/async_system.hpp>
|
||||||
|
#include <boost/process/group.hpp>
|
||||||
#if BOOST_PROCESS_VERSION == 1
|
#include <boost/process/child.hpp>
|
||||||
#include <boost/process/v1.hpp>
|
#include <boost/process/cmd.hpp>
|
||||||
#elif BOOST_PROCESS_VERSION == 2
|
#include <boost/process/env.hpp>
|
||||||
#include <boost/process/v2.hpp>
|
#include <boost/process/environment.hpp>
|
||||||
#else
|
#include <boost/process/error.hpp>
|
||||||
#error "Unknown boost process version"
|
#include <boost/process/exe.hpp>
|
||||||
#endif
|
#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
|
#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
|
// 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 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>
|
/** \file boost/process/args.hpp
|
||||||
BOOST_HEADER_DEPRECATED("<boost/process/v1/args.hpp>")
|
*
|
||||||
#include <boost/process/v1/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
|
// 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 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>
|
The header which provides the basic asynchrounous features.
|
||||||
BOOST_HEADER_DEPRECATED("<boost/process/v1/async.hpp>")
|
It provides the on_exit property, which allows callbacks when the process exits.
|
||||||
#include <boost/process/v1/async.hpp>
|
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
|
// 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 LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
|
||||||
#include <boost/config/header_deprecated.hpp>
|
#ifndef BOOST_PROCESS_ASYNC_PIPE_HPP
|
||||||
BOOST_HEADER_DEPRECATED("<boost/process/v1/async_pipe.hpp>")
|
#define BOOST_PROCESS_ASYNC_PIPE_HPP
|
||||||
#include <boost/process/v1/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
|
// 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 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
|
// 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 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
|
// 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 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>
|
#include <boost/winapi/config.hpp>
|
||||||
BOOST_HEADER_DEPRECATED("<boost/process/v1/cmd.hpp>")
|
#include <boost/process/detail/config.hpp>
|
||||||
#include <boost/process/v1/cmd.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>
|
#include <type_traits>
|
||||||
|
|
||||||
#if defined(BOOST_POSIX_API)
|
#if defined(BOOST_POSIX_API)
|
||||||
#include <boost/process/v1/posix.hpp>
|
#include <boost/process/posix.hpp>
|
||||||
#include <boost/process/v1/detail/posix/async_handler.hpp>
|
#include <boost/process/detail/posix/async_handler.hpp>
|
||||||
#include <boost/process/v1/detail/posix/asio_fwd.hpp>
|
#include <boost/process/detail/posix/asio_fwd.hpp>
|
||||||
#else
|
#else
|
||||||
#include <boost/process/v1/detail/windows/async_handler.hpp>
|
#include <boost/process/detail/windows/async_handler.hpp>
|
||||||
#include <boost/process/v1/detail/windows/asio_fwd.hpp>
|
#include <boost/process/detail/windows/asio_fwd.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
|
|
||||||
namespace process { BOOST_PROCESS_V1_INLINE namespace v1 {
|
namespace process {
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
#if defined(BOOST_POSIX_API)
|
#if defined(BOOST_POSIX_API)
|
||||||
using ::boost::process::v1::detail::posix::is_async_handler;
|
using ::boost::process::detail::posix::is_async_handler;
|
||||||
using ::boost::process::v1::detail::posix::does_require_io_context;
|
using ::boost::process::detail::posix::does_require_io_context;
|
||||||
#else
|
#else
|
||||||
using ::boost::process::v1::detail::windows::is_async_handler;
|
using ::boost::process::detail::windows::is_async_handler;
|
||||||
using ::boost::process::v1::detail::windows::does_require_io_context;
|
using ::boost::process::detail::windows::does_require_io_context;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template<typename ...Args>
|
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_ */
|
#endif /* BOOST_PROCESS_DETAIL_ASYNC_HANDLER_HPP_ */
|
||||||
@@ -7,26 +7,26 @@
|
|||||||
#ifndef BOOST_PROCESS_DETAIL_BASIC_CMD_HPP_
|
#ifndef BOOST_PROCESS_DETAIL_BASIC_CMD_HPP_
|
||||||
#define 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/detail/handler_base.hpp>
|
||||||
#include <boost/process/v1/detail/traits/cmd_or_exe.hpp>
|
#include <boost/process/detail/traits/cmd_or_exe.hpp>
|
||||||
#include <boost/process/v1/detail/traits/wchar_t.hpp>
|
#include <boost/process/detail/traits/wchar_t.hpp>
|
||||||
|
|
||||||
#if defined( BOOST_WINDOWS_API )
|
#if defined( BOOST_WINDOWS_API )
|
||||||
#include <boost/process/v1/detail/windows/basic_cmd.hpp>
|
#include <boost/process/detail/windows/basic_cmd.hpp>
|
||||||
#include <boost/process/v1/detail/windows/cmd.hpp>
|
#include <boost/process/detail/windows/cmd.hpp>
|
||||||
#elif defined( BOOST_POSIX_API )
|
#elif defined( BOOST_POSIX_API )
|
||||||
#include <boost/process/v1/detail/posix/basic_cmd.hpp>
|
#include <boost/process/detail/posix/basic_cmd.hpp>
|
||||||
#include <boost/process/v1/detail/posix/cmd.hpp>
|
#include <boost/process/detail/posix/cmd.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <boost/process/v1/shell.hpp>
|
#include <boost/process/shell.hpp>
|
||||||
|
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
|
||||||
|
|
||||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail {
|
namespace boost { namespace process { namespace detail {
|
||||||
|
|
||||||
template<typename Char>
|
template<typename Char>
|
||||||
struct exe_setter_
|
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)
|
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)
|
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(),
|
std::transform(in._args.begin(), in._args.end(), vec.begin(),
|
||||||
[](const std::wstring & ws)
|
[](const std::wstring & ws)
|
||||||
{
|
{
|
||||||
return ::boost::process::v1::detail::convert(ws);
|
return ::boost::process::detail::convert(ws);
|
||||||
});
|
});
|
||||||
return {vec};
|
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(),
|
std::transform(in._args.begin(), in._args.end(), vec.begin(),
|
||||||
[](const std::string & ws)
|
[](const std::string & ws)
|
||||||
{
|
{
|
||||||
return ::boost::process::v1::detail::convert(ws);
|
return ::boost::process::detail::convert(ws);
|
||||||
});
|
});
|
||||||
|
|
||||||
return {vec};
|
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(),
|
std::transform(in._args.begin(), in._args.end(), vec.begin(),
|
||||||
[](const std::wstring & ws)
|
[](const std::wstring & ws)
|
||||||
{
|
{
|
||||||
return ::boost::process::v1::detail::convert(ws);
|
return ::boost::process::detail::convert(ws);
|
||||||
});
|
});
|
||||||
return {vec}; }
|
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(),
|
std::transform(in._args.begin(), in._args.end(), vec.begin(),
|
||||||
[](const std::string & ws)
|
[](const std::string & ws)
|
||||||
{
|
{
|
||||||
return ::boost::process::v1::detail::convert(ws);
|
return ::boost::process::detail::convert(ws);
|
||||||
});
|
});
|
||||||
return {vec};
|
return {vec};
|
||||||
}
|
}
|
||||||
@@ -168,7 +168,7 @@ struct exe_builder
|
|||||||
string_type exe;
|
string_type exe;
|
||||||
std::vector<string_type> args;
|
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;
|
not_cmd = true;
|
||||||
if (exe.empty())
|
if (exe.empty())
|
||||||
@@ -285,7 +285,7 @@ struct initializer_builder<cmd_or_exe_tag<wchar_t>>
|
|||||||
typedef exe_builder<wchar_t> type;
|
typedef exe_builder<wchar_t> type;
|
||||||
};
|
};
|
||||||
|
|
||||||
}}}}
|
}}}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
#ifndef BOOST_PROCESS_CHILD_DECL_HPP
|
#ifndef BOOST_PROCESS_CHILD_DECL_HPP
|
||||||
#define 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 <chrono>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
@@ -25,36 +25,36 @@
|
|||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
|
||||||
#if defined(BOOST_POSIX_API)
|
#if defined(BOOST_POSIX_API)
|
||||||
#include <boost/process/v1/detail/posix/child_handle.hpp>
|
#include <boost/process/detail/posix/child_handle.hpp>
|
||||||
#include <boost/process/v1/detail/posix/terminate.hpp>
|
#include <boost/process/detail/posix/terminate.hpp>
|
||||||
#include <boost/process/v1/detail/posix/wait_for_exit.hpp>
|
#include <boost/process/detail/posix/wait_for_exit.hpp>
|
||||||
#include <boost/process/v1/detail/posix/is_running.hpp>
|
#include <boost/process/detail/posix/is_running.hpp>
|
||||||
#elif defined(BOOST_WINDOWS_API)
|
#elif defined(BOOST_WINDOWS_API)
|
||||||
#include <boost/process/v1/detail/windows/child_handle.hpp>
|
#include <boost/process/detail/windows/child_handle.hpp>
|
||||||
#include <boost/process/v1/detail/windows/terminate.hpp>
|
#include <boost/process/detail/windows/terminate.hpp>
|
||||||
#include <boost/process/v1/detail/windows/wait_for_exit.hpp>
|
#include <boost/process/detail/windows/wait_for_exit.hpp>
|
||||||
#include <boost/process/v1/detail/windows/is_running.hpp>
|
#include <boost/process/detail/windows/is_running.hpp>
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
namespace boost {
|
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
|
class child
|
||||||
{
|
{
|
||||||
::boost::process::v1::detail::api::child_handle _child_handle;
|
::boost::process::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);
|
std::shared_ptr<std::atomic<int>> _exit_status = std::make_shared<std::atomic<int>>(::boost::process::detail::api::still_active);
|
||||||
bool _attached = true;
|
bool _attached = true;
|
||||||
bool _terminated = false;
|
bool _terminated = false;
|
||||||
|
|
||||||
bool _exited()
|
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:
|
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;
|
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, 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) {}
|
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(); }
|
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(); }
|
pid_t id() const {return _child_handle.id(); }
|
||||||
|
|
||||||
int native_exit_code() const {return _exit_status->load();}
|
int native_exit_code() const {return _exit_status->load();}
|
||||||
@@ -107,7 +107,7 @@ public:
|
|||||||
{
|
{
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
bool b = running(ec);
|
bool b = running(ec);
|
||||||
boost::process::v1::detail::throw_error(ec, "running error");
|
boost::process::detail::throw_error(ec, "running error");
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,14 +115,14 @@ public:
|
|||||||
{
|
{
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
terminate(ec);
|
terminate(ec);
|
||||||
boost::process::v1::detail::throw_error(ec, "terminate error");
|
boost::process::detail::throw_error(ec, "terminate error");
|
||||||
}
|
}
|
||||||
|
|
||||||
void wait()
|
void wait()
|
||||||
{
|
{
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
wait(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)
|
#if !defined(BOOST_PROCESS_NO_DEPRECATED)
|
||||||
@@ -133,7 +133,7 @@ public:
|
|||||||
{
|
{
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
bool b = wait_for(rel_time, 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;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,7 +143,7 @@ public:
|
|||||||
{
|
{
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
bool b = wait_until(timeout_time, 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;
|
return b;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -154,7 +154,7 @@ public:
|
|||||||
if (valid() && !_exited() && !ec)
|
if (valid() && !_exited() && !ec)
|
||||||
{
|
{
|
||||||
int exit_code = 0;
|
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())
|
if (!ec && !res && !_exited())
|
||||||
_exit_status->store(exit_code);
|
_exit_status->store(exit_code);
|
||||||
|
|
||||||
@@ -166,7 +166,7 @@ public:
|
|||||||
void terminate(std::error_code & ec) noexcept
|
void terminate(std::error_code & ec) noexcept
|
||||||
{
|
{
|
||||||
if (valid() && running(ec) && !ec)
|
if (valid() && running(ec) && !ec)
|
||||||
boost::process::v1::detail::api::terminate(_child_handle, ec);
|
boost::process::detail::api::terminate(_child_handle, ec);
|
||||||
|
|
||||||
if (!ec)
|
if (!ec)
|
||||||
_terminated = true;
|
_terminated = true;
|
||||||
@@ -177,7 +177,7 @@ public:
|
|||||||
if (!_exited() && valid())
|
if (!_exited() && valid())
|
||||||
{
|
{
|
||||||
int exit_code = 0;
|
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)
|
if (!ec)
|
||||||
_exit_status->store(exit_code);
|
_exit_status->store(exit_code);
|
||||||
}
|
}
|
||||||
@@ -198,7 +198,7 @@ public:
|
|||||||
if (!_exited())
|
if (!_exited())
|
||||||
{
|
{
|
||||||
int exit_code = 0;
|
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)
|
if (!b || ec)
|
||||||
return false;
|
return false;
|
||||||
_exit_status->store(exit_code);
|
_exit_status->store(exit_code);
|
||||||
@@ -225,7 +225,6 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
}}}
|
}}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -21,19 +21,7 @@
|
|||||||
#include <system_error>
|
#include <system_error>
|
||||||
#include <boost/system/api_config.hpp>
|
#include <boost/system/api_config.hpp>
|
||||||
|
|
||||||
#if !defined(BOOST_PROCESS_VERSION)
|
#include <boost/process/exception.hpp>
|
||||||
#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>
|
|
||||||
|
|
||||||
#if defined(BOOST_POSIX_API)
|
#if defined(BOOST_POSIX_API)
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
@@ -48,9 +36,7 @@ extern char **environ;
|
|||||||
#error "System API not supported by boost.process"
|
#error "System API not supported by boost.process"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
namespace boost { namespace process { namespace detail
|
||||||
|
|
||||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail
|
|
||||||
{
|
{
|
||||||
|
|
||||||
#if !defined(BOOST_PROCESS_PIPE_SIZE)
|
#if !defined(BOOST_PROCESS_PIPE_SIZE)
|
||||||
@@ -85,33 +71,31 @@ inline std::error_code get_last_error() noexcept
|
|||||||
}
|
}
|
||||||
#endif
|
#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,
|
inline void throw_error(const std::error_code& ec)
|
||||||
boost::source_location const & loc = boost::source_location())
|
|
||||||
{
|
{
|
||||||
if (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,
|
inline void throw_error(const std::error_code& ec, const char* msg)
|
||||||
boost::source_location const & loc = boost::source_location())
|
|
||||||
{
|
{
|
||||||
if (ec)
|
if (ec)
|
||||||
boost::throw_exception(process_error(ec, msg), loc);
|
throw process_error(ec, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Char> constexpr Char null_char();
|
template<typename Char> constexpr Char null_char();
|
||||||
@@ -133,7 +117,5 @@ template<> constexpr wchar_t space_sign<wchar_t> () {return L' '; }
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -17,17 +17,17 @@
|
|||||||
#ifndef BOOST_PROCESS_EXECUTE_HPP
|
#ifndef BOOST_PROCESS_EXECUTE_HPP
|
||||||
#define BOOST_PROCESS_EXECUTE_HPP
|
#define BOOST_PROCESS_EXECUTE_HPP
|
||||||
|
|
||||||
#include <boost/process/v1/detail/config.hpp>
|
#include <boost/process/detail/config.hpp>
|
||||||
#include <boost/process/v1/detail/traits.hpp>
|
#include <boost/process/detail/traits.hpp>
|
||||||
|
|
||||||
#if defined(BOOST_POSIX_API)
|
#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)
|
#elif defined(BOOST_WINDOWS_API)
|
||||||
#include <boost/process/v1/detail/windows/executor.hpp>
|
#include <boost/process/detail/windows/executor.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <boost/process/v1/detail/basic_cmd.hpp>
|
#include <boost/process/detail/basic_cmd.hpp>
|
||||||
#include <boost/process/v1/detail/handler.hpp>
|
#include <boost/process/detail/handler.hpp>
|
||||||
|
|
||||||
#include <boost/fusion/view.hpp>
|
#include <boost/fusion/view.hpp>
|
||||||
#include <boost/fusion/container.hpp>
|
#include <boost/fusion/container.hpp>
|
||||||
@@ -40,7 +40,7 @@
|
|||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 {
|
namespace boost { namespace process {
|
||||||
|
|
||||||
class child;
|
class child;
|
||||||
|
|
||||||
@@ -228,7 +228,7 @@ inline child basic_execute_impl(Args && ... args)
|
|||||||
boost::fusion::tuple<typename std::remove_reference<Args>::type&...> tup(args...);
|
boost::fusion::tuple<typename std::remove_reference<Args>::type&...> tup(args...);
|
||||||
|
|
||||||
auto inits = boost::fusion::filter_if<
|
auto inits = boost::fusion::filter_if<
|
||||||
boost::process::v1::detail::is_initializer<
|
boost::process::detail::is_initializer<
|
||||||
typename std::remove_reference<
|
typename std::remove_reference<
|
||||||
boost::mpl::_
|
boost::mpl::_
|
||||||
>::type
|
>::type
|
||||||
@@ -237,7 +237,7 @@ inline child basic_execute_impl(Args && ... args)
|
|||||||
|
|
||||||
auto others = boost::fusion::filter_if<
|
auto others = boost::fusion::filter_if<
|
||||||
boost::mpl::not_<
|
boost::mpl::not_<
|
||||||
boost::process::v1::detail::is_initializer<
|
boost::process::detail::is_initializer<
|
||||||
typename std::remove_reference<
|
typename std::remove_reference<
|
||||||
boost::mpl::_
|
boost::mpl::_
|
||||||
>::type
|
>::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(inits)>::type inits_t;
|
||||||
typedef typename boost::fusion::result_of::as_vector<decltype(others)>::type others_t;
|
typedef typename boost::fusion::result_of::as_vector<decltype(others)>::type others_t;
|
||||||
// typedef decltype(others) 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::begin<others_t>::type,
|
||||||
typename boost::fusion::result_of::end <others_t>::type>::type builder_t;
|
typename boost::fusion::result_of::end <others_t>::type>::type builder_t;
|
||||||
|
|
||||||
builder_t builders;
|
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);
|
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);
|
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();
|
return exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -273,11 +273,12 @@ inline child execute_impl(Args&& ... args)
|
|||||||
typedef required_char_type_t<Args...> req_char_type;
|
typedef required_char_type_t<Args...> req_char_type;
|
||||||
|
|
||||||
return basic_execute_impl<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))...
|
std::forward<Args>(args))...
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}}}}
|
}}}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -7,16 +7,16 @@
|
|||||||
#ifndef BOOST_PROCESS_DETAIL_HANDLER_HPP_
|
#ifndef BOOST_PROCESS_DETAIL_HANDLER_HPP_
|
||||||
#define 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)
|
#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)
|
#elif defined(BOOST_WINDOWS_API)
|
||||||
#include <boost/process/v1/detail/windows/handler.hpp>
|
#include <boost/process/detail/windows/handler.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail {
|
namespace boost { namespace process { namespace detail {
|
||||||
|
|
||||||
//extended handler base.
|
//extended handler base.
|
||||||
typedef api::handler_base_ext handler;
|
typedef api::handler_base_ext handler;
|
||||||
@@ -68,6 +68,8 @@ private:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
}}}
|
}}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* BOOST_PROCESS_DETAIL_HANDLER_HPP_ */
|
#endif /* BOOST_PROCESS_DETAIL_HANDLER_HPP_ */
|
||||||
@@ -11,10 +11,9 @@
|
|||||||
#ifndef BOOST_PROCESS_DETAIL_HANDLER_BASE_HPP
|
#ifndef BOOST_PROCESS_DETAIL_HANDLER_BASE_HPP
|
||||||
#define BOOST_PROCESS_DETAIL_HANDLER_BASE_HPP
|
#define BOOST_PROCESS_DETAIL_HANDLER_BASE_HPP
|
||||||
|
|
||||||
#include <boost/process/v1/detail/config.hpp>
|
|
||||||
#include <system_error>
|
#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>
|
template<template <class> class Template>
|
||||||
struct make_handler_t
|
struct make_handler_t
|
||||||
@@ -45,6 +44,6 @@ struct handler_base
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
}}}}
|
}}}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -6,18 +6,18 @@
|
|||||||
#ifndef BOOST_PROCESS_DETAIL_ON_EXIT_HPP_
|
#ifndef BOOST_PROCESS_DETAIL_ON_EXIT_HPP_
|
||||||
#define 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)
|
#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)
|
#elif defined(BOOST_WINDOWS_API)
|
||||||
#include <boost/process/v1/detail/windows/on_exit.hpp>
|
#include <boost/process/detail/windows/on_exit.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <future>
|
#include <future>
|
||||||
#include <memory>
|
#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)
|
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_ */
|
#endif /* INCLUDE_BOOST_PROCESS_WINDOWS_ON_EXIT_HPP_ */
|
||||||
@@ -38,7 +38,7 @@ typedef basic_stream_descriptor<any_io_executor> stream_descriptor;
|
|||||||
} //posix
|
} //posix
|
||||||
} //asio
|
} //asio
|
||||||
|
|
||||||
namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail { namespace posix {
|
namespace process { namespace detail { namespace posix {
|
||||||
|
|
||||||
class async_pipe;
|
class async_pipe;
|
||||||
|
|
||||||
@@ -54,9 +54,8 @@ struct async_out_future;
|
|||||||
} // posix
|
} // posix
|
||||||
} // detail
|
} // detail
|
||||||
|
|
||||||
using ::boost::process::v1::detail::posix::async_pipe;
|
using ::boost::process::detail::posix::async_pipe;
|
||||||
|
|
||||||
} // v1
|
|
||||||
} // process
|
} // process
|
||||||
} // boost
|
} // boost
|
||||||
|
|
||||||
@@ -7,10 +7,10 @@
|
|||||||
#ifndef BOOST_PROCESS_POSIX_ASYNC_HANDLER_HPP_
|
#ifndef BOOST_PROCESS_POSIX_ASYNC_HANDLER_HPP_
|
||||||
#define 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>
|
#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 {};
|
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> {};
|
struct does_require_io_context<const T&> : std::is_base_of<require_io_context, T> {};
|
||||||
|
|
||||||
|
|
||||||
}}}}}
|
}}}}
|
||||||
|
|
||||||
#endif /* BOOST_PROCESS_WINDOWS_ASYNC_HANDLER_HPP_ */
|
#endif /* BOOST_PROCESS_WINDOWS_ASYNC_HANDLER_HPP_ */
|
||||||
@@ -10,22 +10,22 @@
|
|||||||
#ifndef BOOST_PROCESS_DETAIL_POSIX_ASYNC_IN_HPP
|
#ifndef BOOST_PROCESS_DETAIL_POSIX_ASYNC_IN_HPP
|
||||||
#define 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/detail/handler_base.hpp>
|
||||||
#include <boost/process/v1/detail/posix/async_handler.hpp>
|
#include <boost/process/detail/posix/async_handler.hpp>
|
||||||
#include <boost/asio/write.hpp>
|
#include <boost/asio/write.hpp>
|
||||||
#include <boost/process/v1/async_pipe.hpp>
|
#include <boost/process/async_pipe.hpp>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <future>
|
#include <future>
|
||||||
#include <boost/process/v1/detail/used_handles.hpp>
|
#include <boost/process/detail/used_handles.hpp>
|
||||||
#include <array>
|
#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>
|
template<typename Buffer>
|
||||||
struct async_in_buffer : ::boost::process::v1::detail::posix::handler_base_ext,
|
struct async_in_buffer : ::boost::process::detail::posix::handler_base_ext,
|
||||||
::boost::process::v1::detail::posix::require_io_context,
|
::boost::process::detail::posix::require_io_context,
|
||||||
::boost::process::v1::detail::uses_handles
|
::boost::process::detail::uses_handles
|
||||||
{
|
{
|
||||||
Buffer & buf;
|
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)
|
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)
|
void on_setup(Executor & exec)
|
||||||
{
|
{
|
||||||
if (!pipe)
|
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()
|
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)
|
void on_exec_setup(Executor &exec)
|
||||||
{
|
{
|
||||||
if (::dup2(pipe->native_source(), STDIN_FILENO) == -1)
|
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)
|
if (pipe->native_source() != STDIN_FILENO)
|
||||||
::close(pipe->native_source());
|
::close(pipe->native_source());
|
||||||
@@ -106,6 +106,6 @@ struct async_in_buffer : ::boost::process::v1::detail::posix::handler_base_ext,
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
}}}}}
|
}}}}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -11,18 +11,18 @@
|
|||||||
#define BOOST_PROCESS_DETAIL_POSIX_ASYNC_OUT_HPP
|
#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/posix/stream_descriptor.hpp>
|
||||||
#include <boost/asio/read.hpp>
|
#include <boost/asio/read.hpp>
|
||||||
#include <boost/process/v1/async_pipe.hpp>
|
#include <boost/process/async_pipe.hpp>
|
||||||
#include <istream>
|
#include <istream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#include <future>
|
#include <future>
|
||||||
#include <array>
|
#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>)
|
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>
|
template<int p1, int p2, typename Buffer>
|
||||||
struct async_out_buffer : ::boost::process::v1::detail::posix::handler_base_ext,
|
struct async_out_buffer : ::boost::process::detail::posix::handler_base_ext,
|
||||||
::boost::process::v1::detail::posix::require_io_context,
|
::boost::process::detail::posix::require_io_context,
|
||||||
::boost::process::v1::detail::uses_handles
|
::boost::process::detail::uses_handles
|
||||||
{
|
{
|
||||||
Buffer & buf;
|
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()
|
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>
|
template <typename Executor>
|
||||||
inline void on_success(Executor &)
|
inline void on_success(Executor &exec)
|
||||||
{
|
{
|
||||||
auto pipe = this->pipe;
|
auto pipe = this->pipe;
|
||||||
boost::asio::async_read(*pipe, buf,
|
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>
|
template<typename Executor>
|
||||||
void on_setup(Executor & exec)
|
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(),
|
int res = apply_out_handles(pipe->native_sink(),
|
||||||
std::integral_constant<int, p1>(), std::integral_constant<int, p2>());
|
std::integral_constant<int, p1>(), std::integral_constant<int, p2>());
|
||||||
if (res == -1)
|
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_sink());
|
||||||
::close(pipe->native_source());
|
::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>
|
template<int p1, int p2, typename Type>
|
||||||
struct async_out_future : ::boost::process::v1::detail::posix::handler_base_ext,
|
struct async_out_future : ::boost::process::detail::posix::handler_base_ext,
|
||||||
::boost::process::v1::detail::posix::require_io_context
|
::boost::process::detail::posix::require_io_context
|
||||||
{
|
{
|
||||||
std::shared_ptr<std::promise<Type>> promise = std::make_shared<std::promise<Type>>();
|
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::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)
|
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>
|
template<typename Executor>
|
||||||
void on_setup(Executor & exec)
|
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>
|
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(),
|
int res = apply_out_handles(pipe->native_sink(),
|
||||||
std::integral_constant<int, p1>(), std::integral_constant<int, p2>());
|
std::integral_constant<int, p1>(), std::integral_constant<int, p2>());
|
||||||
if (res == -1)
|
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_sink());
|
||||||
::close(pipe->native_source());
|
::close(pipe->native_source());
|
||||||
@@ -185,6 +185,6 @@ struct async_out_future : ::boost::process::v1::detail::posix::handler_base_ext,
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}}}}}
|
}}}}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -7,14 +7,14 @@
|
|||||||
#define BOOST_PROCESS_DETAIL_POSIX_ASYNC_PIPE_HPP_
|
#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/posix/stream_descriptor.hpp>
|
||||||
#include <boost/asio/post.hpp>
|
#include <boost/asio/post.hpp>
|
||||||
#include <system_error>
|
#include <system_error>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
#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
|
class async_pipe
|
||||||
{
|
{
|
||||||
@@ -37,7 +37,7 @@ public:
|
|||||||
{
|
{
|
||||||
int fds[2];
|
int fds[2];
|
||||||
if (::pipe(fds) == -1)
|
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]);
|
_source.assign(fds[0]);
|
||||||
_sink .assign(fds[1]);
|
_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 );
|
auto fifo = mkfifo(name.c_str(), 0666 );
|
||||||
|
|
||||||
if (fifo != 0)
|
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);
|
int read_fd = open(name.c_str(), O_RDWR);
|
||||||
|
|
||||||
if (read_fd == -1)
|
if (read_fd == -1)
|
||||||
boost::process::v1::detail::throw_last_error();
|
boost::process::detail::throw_last_error();
|
||||||
|
|
||||||
int write_fd = dup(read_fd);
|
int write_fd = dup(read_fd);
|
||||||
|
|
||||||
if (write_fd == -1)
|
if (write_fd == -1)
|
||||||
boost::process::v1::detail::throw_last_error();
|
boost::process::detail::throw_last_error();
|
||||||
|
|
||||||
_source.assign(read_fd);
|
_source.assign(read_fd);
|
||||||
_sink .assign(write_fd);
|
_sink .assign(write_fd);
|
||||||
@@ -236,7 +236,7 @@ async_pipe::async_pipe(const async_pipe & p) :
|
|||||||
{
|
{
|
||||||
_source.assign(::dup(source_in));
|
_source.assign(::dup(source_in));
|
||||||
if (_source.native_handle()== -1)
|
if (_source.native_handle()== -1)
|
||||||
::boost::process::v1::detail::throw_last_error("dup()");
|
::boost::process::detail::throw_last_error("dup()");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sink_in == -1)
|
if (sink_in == -1)
|
||||||
@@ -245,7 +245,7 @@ async_pipe::async_pipe(const async_pipe & p) :
|
|||||||
{
|
{
|
||||||
_sink.assign(::dup(sink_in));
|
_sink.assign(::dup(sink_in));
|
||||||
if (_sink.native_handle() == -1)
|
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);
|
source = ::dup(source_in);
|
||||||
if (source == -1)
|
if (source == -1)
|
||||||
::boost::process::v1::detail::throw_last_error("dup()");
|
::boost::process::detail::throw_last_error("dup()");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sink_in == -1)
|
if (sink_in == -1)
|
||||||
@@ -272,7 +272,7 @@ async_pipe& async_pipe::operator=(const async_pipe & p)
|
|||||||
{
|
{
|
||||||
sink = ::dup(sink_in);
|
sink = ::dup(sink_in);
|
||||||
if (sink == -1)
|
if (sink == -1)
|
||||||
::boost::process::v1::detail::throw_last_error("dup()");
|
::boost::process::detail::throw_last_error("dup()");
|
||||||
}
|
}
|
||||||
_source.assign(source);
|
_source.assign(source);
|
||||||
_sink. assign(sink);
|
_sink. assign(sink);
|
||||||
@@ -304,7 +304,7 @@ async_pipe::operator basic_pipe<CharT, Traits>() const
|
|||||||
{
|
{
|
||||||
source = ::dup(source_in);
|
source = ::dup(source_in);
|
||||||
if (source == -1)
|
if (source == -1)
|
||||||
::boost::process::v1::detail::throw_last_error("dup()");
|
::boost::process::detail::throw_last_error("dup()");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sink_in == -1)
|
if (sink_in == -1)
|
||||||
@@ -313,7 +313,7 @@ async_pipe::operator basic_pipe<CharT, Traits>() const
|
|||||||
{
|
{
|
||||||
sink = ::dup(sink_in);
|
sink = ::dup(sink_in);
|
||||||
if (sink == -1)
|
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};
|
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());
|
!compare_handles(lhs.native_sink(), rhs.native_sink());
|
||||||
}
|
}
|
||||||
|
|
||||||
}}}}}
|
}}}}
|
||||||
|
|
||||||
#endif /* INCLUDE_BOOST_PIPE_DETAIL_WINDOWS_ASYNC_PIPE_HPP_ */
|
#endif /* INCLUDE_BOOST_PIPE_DETAIL_WINDOWS_ASYNC_PIPE_HPP_ */
|
||||||
@@ -7,11 +7,10 @@
|
|||||||
#ifndef BOOST_PROCESS_DETAIL_POSIX_BASIC_CMD_HPP_
|
#ifndef BOOST_PROCESS_DETAIL_POSIX_BASIC_CMD_HPP_
|
||||||
#define 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/detail/posix/handler.hpp>
|
||||||
#include <boost/process/v1/detail/posix/handler.hpp>
|
#include <boost/process/detail/posix/cmd.hpp>
|
||||||
#include <boost/process/v1/detail/posix/cmd.hpp>
|
|
||||||
#include <boost/algorithm/string/replace.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/trim.hpp>
|
||||||
#include <boost/algorithm/string/join.hpp>
|
#include <boost/algorithm/string/join.hpp>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -21,13 +20,12 @@ namespace boost
|
|||||||
{
|
{
|
||||||
namespace process
|
namespace process
|
||||||
{
|
{
|
||||||
BOOST_PROCESS_V1_INLINE namespace v1
|
|
||||||
{
|
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
namespace posix
|
namespace posix
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
inline std::string build_cmd_shell(const std::string & exe, std::vector<std::string> && data)
|
inline std::string build_cmd_shell(const std::string & exe, std::vector<std::string> && data)
|
||||||
{
|
{
|
||||||
std::string st = exe;
|
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,
|
//the first one is put directly onto the output,
|
||||||
//because then I don't have to copy the whole string
|
//because then I don't have to copy the whole string
|
||||||
arg.insert(arg.begin(), '"' );
|
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 += ' ';
|
||||||
|
|
||||||
st += arg;
|
st += arg;
|
||||||
@@ -103,7 +101,7 @@ template<typename Char>
|
|||||||
struct exe_cmd_init;
|
struct exe_cmd_init;
|
||||||
|
|
||||||
template<>
|
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(const exe_cmd_init & ) = delete;
|
||||||
exe_cmd_init(exe_cmd_init && ) = default;
|
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 (exe.empty()) //cmd style
|
||||||
{
|
{
|
||||||
if (args.empty())
|
exec.exe = args.front().c_str();
|
||||||
exec.exe = "";
|
|
||||||
else
|
|
||||||
exec.exe = args.front().c_str();
|
|
||||||
exec.cmd_style = true;
|
exec.cmd_style = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -177,6 +172,6 @@ std::vector<char*> exe_cmd_init<char>::make_cmd()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}}}}}
|
}}}}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -11,15 +11,15 @@
|
|||||||
#define BOOST_PROCESS_POSIX_PIPE_HPP
|
#define BOOST_PROCESS_POSIX_PIPE_HPP
|
||||||
|
|
||||||
|
|
||||||
#include <boost/process/v1/filesystem.hpp>
|
#include <boost/process/filesystem.hpp>
|
||||||
#include <boost/process/v1/detail/posix/compare_handles.hpp>
|
#include <boost/process/detail/posix/compare_handles.hpp>
|
||||||
#include <system_error>
|
#include <system_error>
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <memory>
|
#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>>
|
template<class CharT, class Traits = std::char_traits<CharT>>
|
||||||
@@ -41,7 +41,7 @@ public:
|
|||||||
{
|
{
|
||||||
int fds[2];
|
int fds[2];
|
||||||
if (::pipe(fds) == -1)
|
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];
|
_source = fds[0];
|
||||||
_sink = fds[1];
|
_sink = fds[1];
|
||||||
@@ -77,29 +77,32 @@ public:
|
|||||||
void assign_source(native_handle_type h) { _source = h;}
|
void assign_source(native_handle_type h) { _source = h;}
|
||||||
void assign_sink (native_handle_type h) { _sink = h;}
|
void assign_sink (native_handle_type h) { _sink = h;}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int_type write(const char_type * data, int_type count)
|
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)
|
while ((write_len = ::write(_sink, data, count * sizeof(char_type))) == -1)
|
||||||
{
|
{
|
||||||
//Try again if interrupted
|
//Try again if interrupted
|
||||||
auto err = errno;
|
auto err = errno;
|
||||||
if (err != EINTR)
|
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)
|
int_type read(char_type * data, int_type count)
|
||||||
{
|
{
|
||||||
ssize_t read_len;
|
int_type read_len;
|
||||||
while ((read_len = ::read(_source, data, count * sizeof(char_type))) == -1)
|
while ((read_len = static_cast<int_type>(::read(_source, data, count * sizeof(char_type)))) == -1)
|
||||||
{
|
{
|
||||||
//Try again if interrupted
|
//Try again if interrupted
|
||||||
auto err = errno;
|
auto err = errno;
|
||||||
if (err != EINTR)
|
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
|
bool is_open() const
|
||||||
@@ -126,13 +129,13 @@ basic_pipe<CharT, Traits>::basic_pipe(const basic_pipe & rhs)
|
|||||||
{
|
{
|
||||||
_source = ::dup(rhs._source);
|
_source = ::dup(rhs._source);
|
||||||
if (_source == -1)
|
if (_source == -1)
|
||||||
::boost::process::v1::detail::throw_last_error("dup() failed");
|
::boost::process::detail::throw_last_error("dup() failed");
|
||||||
}
|
}
|
||||||
if (rhs._sink != -1)
|
if (rhs._sink != -1)
|
||||||
{
|
{
|
||||||
_sink = ::dup(rhs._sink);
|
_sink = ::dup(rhs._sink);
|
||||||
if (_sink == -1)
|
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);
|
_source = ::dup(rhs._source);
|
||||||
if (_source == -1)
|
if (_source == -1)
|
||||||
::boost::process::v1::detail::throw_last_error("dup() failed");
|
::boost::process::detail::throw_last_error("dup() failed");
|
||||||
}
|
}
|
||||||
if (rhs._sink != -1)
|
if (rhs._sink != -1)
|
||||||
{
|
{
|
||||||
_sink = ::dup(rhs._sink);
|
_sink = ::dup(rhs._sink);
|
||||||
if (_sink == -1)
|
if (_sink == -1)
|
||||||
::boost::process::v1::detail::throw_last_error("dup() failed");
|
::boost::process::detail::throw_last_error("dup() failed");
|
||||||
|
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
@@ -163,18 +166,18 @@ basic_pipe<CharT, Traits>::basic_pipe(const std::string & name)
|
|||||||
auto fifo = mkfifo(name.c_str(), 0666 );
|
auto fifo = mkfifo(name.c_str(), 0666 );
|
||||||
|
|
||||||
if (fifo != 0)
|
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);
|
int read_fd = open(name.c_str(), O_RDWR);
|
||||||
|
|
||||||
if (read_fd == -1)
|
if (read_fd == -1)
|
||||||
boost::process::v1::detail::throw_last_error();
|
boost::process::detail::throw_last_error();
|
||||||
|
|
||||||
int write_fd = dup(read_fd);
|
int write_fd = dup(read_fd);
|
||||||
|
|
||||||
if (write_fd == -1)
|
if (write_fd == -1)
|
||||||
boost::process::v1::detail::throw_last_error();
|
boost::process::detail::throw_last_error();
|
||||||
|
|
||||||
_sink = write_fd;
|
_sink = write_fd;
|
||||||
_source = read_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());
|
!compare_handles(lhs.native_sink(), rhs.native_sink());
|
||||||
}
|
}
|
||||||
|
|
||||||
}}}}}
|
}}}}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
#include <system_error>
|
#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;
|
typedef ::pid_t pid_t;
|
||||||
|
|
||||||
@@ -55,6 +55,6 @@ struct child_handle
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}}}}}
|
}}}}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -11,24 +11,24 @@
|
|||||||
#define BOOST_PROCESS_WINDOWS_INITIALIZERS_CLOSE_IN_HPP
|
#define BOOST_PROCESS_WINDOWS_INITIALIZERS_CLOSE_IN_HPP
|
||||||
|
|
||||||
|
|
||||||
#include <boost/process/v1/detail/posix/handler.hpp>
|
#include <boost/process/detail/posix/handler.hpp>
|
||||||
#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 {
|
||||||
|
|
||||||
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>
|
template <class Executor>
|
||||||
void on_exec_setup(Executor &e) const
|
void on_exec_setup(Executor &e) const
|
||||||
{
|
{
|
||||||
if (::close(STDIN_FILENO) == -1)
|
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;}
|
int get_used_handles() {return STDIN_FILENO;}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}}}}}
|
}}}}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -10,11 +10,11 @@
|
|||||||
#ifndef BOOST_PROCESS_DETAIL_POSIX_CLOSE_OUT_HPP
|
#ifndef BOOST_PROCESS_DETAIL_POSIX_CLOSE_OUT_HPP
|
||||||
#define 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/detail/used_handles.hpp>
|
||||||
#include <boost/process/v1/detail/posix/handler.hpp>
|
#include <boost/process/detail/posix/handler.hpp>
|
||||||
#include <array>
|
#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>
|
template<int p1, int p2>
|
||||||
struct close_out : handler_base_ext
|
struct close_out : handler_base_ext
|
||||||
@@ -30,7 +30,7 @@ template<typename Executor>
|
|||||||
void close_out<1,-1>::on_exec_setup(Executor &e) const
|
void close_out<1,-1>::on_exec_setup(Executor &e) const
|
||||||
{
|
{
|
||||||
if (::close(STDOUT_FILENO) == -1)
|
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
|
void close_out<2,-1>::on_exec_setup(Executor &e) const
|
||||||
{
|
{
|
||||||
if (::close(STDERR_FILENO) == -1)
|
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<>
|
template<>
|
||||||
@@ -47,12 +47,12 @@ template<typename Executor>
|
|||||||
void close_out<1,2>::on_exec_setup(Executor &e) const
|
void close_out<1,2>::on_exec_setup(Executor &e) const
|
||||||
{
|
{
|
||||||
if (::close(STDOUT_FILENO) == -1)
|
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)
|
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
|
#endif
|
||||||
@@ -7,8 +7,8 @@
|
|||||||
#ifndef BOOST_PROCESS_DETAIL_POSIX_CMD_HPP_
|
#ifndef BOOST_PROCESS_DETAIL_POSIX_CMD_HPP_
|
||||||
#define BOOST_PROCESS_DETAIL_POSIX_CMD_HPP_
|
#define BOOST_PROCESS_DETAIL_POSIX_CMD_HPP_
|
||||||
|
|
||||||
#include <boost/process/v1/detail/config.hpp>
|
#include <boost/process/detail/config.hpp>
|
||||||
#include <boost/process/v1/detail/posix/handler.hpp>
|
#include <boost/process/detail/posix/handler.hpp>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -16,8 +16,6 @@ namespace boost
|
|||||||
{
|
{
|
||||||
namespace process
|
namespace process
|
||||||
{
|
{
|
||||||
BOOST_PROCESS_V1_INLINE namespace v1
|
|
||||||
{
|
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
namespace posix
|
namespace posix
|
||||||
@@ -101,6 +99,6 @@ std::vector<Char*> cmd_setter_<Char>::make_cmd(std::vector<std::basic_string<Cha
|
|||||||
return vec;
|
return vec;
|
||||||
}
|
}
|
||||||
|
|
||||||
}}}}}
|
}}}}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -7,12 +7,12 @@
|
|||||||
#define BOOST_PROCESS_DETAIL_POSIX_COMPARE_HANDLES_HPP_
|
#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/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <unistd.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)
|
inline bool compare_handles(int lhs, int rhs)
|
||||||
@@ -25,8 +25,8 @@ inline bool compare_handles(int lhs, int rhs)
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
struct stat stat1, stat2;
|
struct stat stat1, stat2;
|
||||||
if(fstat(lhs, &stat1) < 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::v1::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);
|
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_
|
#define BOOST_PROCESS_DETAIL_POSIX_ENV_INIT_HPP_
|
||||||
|
|
||||||
|
|
||||||
#include <boost/process/v1/detail/config.hpp>
|
#include <boost/process/detail/config.hpp>
|
||||||
#include <boost/process/v1/detail/posix/handler.hpp>
|
#include <boost/process/detail/posix/handler.hpp>
|
||||||
#include <boost/process/v1/environment.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>
|
template<typename Char>
|
||||||
struct env_init;
|
struct env_init;
|
||||||
@@ -20,10 +20,10 @@ struct env_init;
|
|||||||
template<>
|
template<>
|
||||||
struct env_init<char> : handler_base_ext
|
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(boost::process::environment && env) : env(std::move(env)) {};
|
||||||
env_init(const boost::process::v1::environment & env) : env(env) {};
|
env_init(const boost::process::environment & env) : env(env) {};
|
||||||
|
|
||||||
|
|
||||||
template <class Executor>
|
template <class Executor>
|
||||||
@@ -34,7 +34,7 @@ struct env_init<char> : handler_base_ext
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}}}}}
|
}}}}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -9,13 +9,13 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <boost/process/v1/detail/config.hpp>
|
#include <boost/process/detail/config.hpp>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstdlib>
|
#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>
|
template<typename Char>
|
||||||
class native_environment_impl
|
class native_environment_impl
|
||||||
@@ -27,7 +27,7 @@ class native_environment_impl
|
|||||||
while (*p != nullptr)
|
while (*p != nullptr)
|
||||||
{
|
{
|
||||||
std::string str = *p;
|
std::string str = *p;
|
||||||
val.push_back(::boost::process::v1::detail::convert(str));
|
val.push_back(::boost::process::detail::convert(str));
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
return val;
|
return val;
|
||||||
@@ -68,24 +68,24 @@ public:
|
|||||||
|
|
||||||
string_type get(const string_type & id)
|
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());
|
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)
|
void set(const string_type & id, const string_type & value)
|
||||||
{
|
{
|
||||||
std::string id_c = ::boost::process::v1::detail::convert(id.c_str());
|
std::string id_c = ::boost::process::detail::convert(id.c_str());
|
||||||
std::string value_c = ::boost::process::v1::detail::convert(value.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);
|
auto res = ::setenv(id_c.c_str(), value_c.c_str(), true);
|
||||||
if (res != 0)
|
if (res != 0)
|
||||||
boost::process::v1::detail::throw_last_error();
|
boost::process::detail::throw_last_error();
|
||||||
}
|
}
|
||||||
void reset(const string_type & id)
|
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());
|
auto res = ::unsetenv(id_c.c_str());
|
||||||
if (res != 0)
|
if (res != 0)
|
||||||
::boost::process::v1::detail::throw_last_error();
|
::boost::process::detail::throw_last_error();
|
||||||
}
|
}
|
||||||
|
|
||||||
native_environment_impl() = default;
|
native_environment_impl() = default;
|
||||||
@@ -114,14 +114,14 @@ public:
|
|||||||
{
|
{
|
||||||
auto res = ::setenv(id, value, 1);
|
auto res = ::setenv(id, value, 1);
|
||||||
if (res != 0)
|
if (res != 0)
|
||||||
boost::process::v1::detail::throw_last_error();
|
boost::process::detail::throw_last_error();
|
||||||
reload();
|
reload();
|
||||||
}
|
}
|
||||||
void reset(const pointer_type id)
|
void reset(const pointer_type id)
|
||||||
{
|
{
|
||||||
auto res = ::unsetenv(id);
|
auto res = ::unsetenv(id);
|
||||||
if (res != 0)
|
if (res != 0)
|
||||||
boost::process::v1::detail::throw_last_error();
|
boost::process::detail::throw_last_error();
|
||||||
reload();
|
reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,13 +186,13 @@ public:
|
|||||||
template<typename CharR>
|
template<typename CharR>
|
||||||
explicit inline basic_environment_impl(
|
explicit inline basic_environment_impl(
|
||||||
const basic_environment_impl<CharR>& rhs,
|
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())
|
: _data(rhs._data.size())
|
||||||
{
|
{
|
||||||
std::transform(rhs._data.begin(), rhs._data.end(), _data.begin(),
|
std::transform(rhs._data.begin(), rhs._data.end(), _data.begin(),
|
||||||
[&](const std::basic_string<CharR> & st)
|
[&](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>
|
template<typename CharR>
|
||||||
basic_environment_impl & operator=(const basic_environment_impl<CharR>& rhs)
|
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_arr = _load_var(&*_data.begin());
|
||||||
_env_impl = &*_env_arr.begin();
|
_env_impl = &*_env_arr.begin();
|
||||||
return *this;
|
return *this;
|
||||||
@@ -230,7 +230,7 @@ basic_environment_impl<Char>::basic_environment_impl(const native_environment_im
|
|||||||
template<typename Char>
|
template<typename Char>
|
||||||
inline auto basic_environment_impl<Char>::get(const string_type &id) -> string_type
|
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
|
[&](const string_type & st) -> bool
|
||||||
{
|
{
|
||||||
if (st.size() <= id.size())
|
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>
|
template<typename Char>
|
||||||
inline void basic_environment_impl<Char>::set(const string_type &id, const string_type &value)
|
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
|
[&](const string_type & st) -> bool
|
||||||
{
|
{
|
||||||
if (st.size() <= id.size())
|
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())
|
if (itr != _data.end())
|
||||||
*itr = id + equal_sign<Char>() + value;
|
*itr = id + equal_sign<Char>() + value;
|
||||||
else
|
else
|
||||||
_data.push_back(id + equal_sign<Char>() + value);
|
_data.push_back(id + equal_sign<Char>() + value);
|
||||||
|
|
||||||
reload();
|
reload();
|
||||||
@@ -270,7 +270,7 @@ inline void basic_environment_impl<Char>::set(const string_type &id, const strin
|
|||||||
template<typename Char>
|
template<typename Char>
|
||||||
inline void basic_environment_impl<Char>::reset(const string_type &id)
|
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
|
[&](const string_type & st) -> bool
|
||||||
{
|
{
|
||||||
if (st.size() <= id.size())
|
if (st.size() <= id.size())
|
||||||
@@ -280,9 +280,9 @@ inline void basic_environment_impl<Char>::reset(const string_type &id)
|
|||||||
);
|
);
|
||||||
if (itr != _data.end())
|
if (itr != _data.end())
|
||||||
{
|
{
|
||||||
_data.erase(itr);//and remove it
|
_data.erase(itr);//and remove it
|
||||||
}
|
}
|
||||||
|
|
||||||
reload();
|
reload();
|
||||||
|
|
||||||
|
|
||||||
@@ -320,7 +320,7 @@ inline int native_handle() {return getpid(); }
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -7,14 +7,11 @@
|
|||||||
#ifndef BOOST_PROCESS_DETAIL_POSIX_EXE_HPP_
|
#ifndef BOOST_PROCESS_DETAIL_POSIX_EXE_HPP_
|
||||||
#define BOOST_PROCESS_DETAIL_POSIX_EXE_HPP_
|
#define BOOST_PROCESS_DETAIL_POSIX_EXE_HPP_
|
||||||
|
|
||||||
#include <boost/process/v1/detail/config.hpp>
|
|
||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
namespace process
|
namespace process
|
||||||
{
|
{
|
||||||
BOOST_PROCESS_V1_INLINE namespace v1
|
|
||||||
{
|
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
namespace posix
|
namespace posix
|
||||||
@@ -33,7 +30,7 @@ inline void apply_exe(const StringType & exe, Executor & e)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* INCLUDE_BOOST_PROCESS_WINDOWS_ARGS_HPP_ */
|
#endif /* INCLUDE_BOOST_PROCESS_WINDOWS_ARGS_HPP_ */
|
||||||
@@ -10,11 +10,11 @@
|
|||||||
#ifndef BOOST_PROCESS_DETAIL_POSIX_EXECUTOR_HPP
|
#ifndef BOOST_PROCESS_DETAIL_POSIX_EXECUTOR_HPP
|
||||||
#define BOOST_PROCESS_DETAIL_POSIX_EXECUTOR_HPP
|
#define BOOST_PROCESS_DETAIL_POSIX_EXECUTOR_HPP
|
||||||
|
|
||||||
#include <boost/process/v1/detail/child_decl.hpp>
|
#include <boost/process/detail/child_decl.hpp>
|
||||||
#include <boost/process/v1/error.hpp>
|
#include <boost/process/error.hpp>
|
||||||
#include <boost/process/v1/pipe.hpp>
|
#include <boost/process/pipe.hpp>
|
||||||
#include <boost/process/v1/detail/posix/basic_pipe.hpp>
|
#include <boost/process/detail/posix/basic_pipe.hpp>
|
||||||
#include <boost/process/v1/detail/posix/use_vfork.hpp>
|
#include <boost/process/detail/posix/use_vfork.hpp>
|
||||||
#include <boost/fusion/algorithm/iteration/for_each.hpp>
|
#include <boost/fusion/algorithm/iteration/for_each.hpp>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
#include <boost/core/ignore_unused.hpp>
|
#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>
|
template<typename Executor>
|
||||||
struct on_setup_t
|
struct on_setup_t
|
||||||
@@ -204,9 +204,9 @@ class executor
|
|||||||
throw process_error(_ec, _msg);
|
throw process_error(_ec, _msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef typename ::boost::process::v1::detail::has_error_handler<Sequence>::type has_error_handler;
|
typedef typename ::boost::process::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::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::posix::shall_use_vfork<Sequence>::type shall_use_vfork;
|
||||||
|
|
||||||
inline child invoke(boost::mpl::true_ , boost::mpl::true_ );
|
inline child invoke(boost::mpl::true_ , boost::mpl::true_ );
|
||||||
inline child invoke(boost::mpl::false_, 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();
|
this->pid = ::fork();
|
||||||
if (pid == -1)
|
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));
|
boost::fusion::for_each(seq, call_on_fork_error(*this, ec));
|
||||||
return child();
|
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));
|
boost::fusion::for_each(seq, call_on_exec_setup(*this));
|
||||||
::execve(exe, cmd_line, env);
|
::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));
|
boost::fusion::for_each(seq, call_on_exec_error(*this, ec));
|
||||||
_exit(EXIT_FAILURE);
|
_exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
@@ -389,25 +389,21 @@ child executor<Sequence>::invoke(boost::mpl::false_, boost::mpl::false_)
|
|||||||
|
|
||||||
if (::pipe(p.p) == -1)
|
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();
|
return child();
|
||||||
}
|
}
|
||||||
if (::fcntl(p.p[1], F_SETFD, FD_CLOEXEC) == -1)
|
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.
|
set_error(err, "fcntl(2) failed");//this might throw, so we need to be sure our pipe is safe.
|
||||||
return child();
|
return child();
|
||||||
}
|
}
|
||||||
|
|
||||||
_pipe_sink = p.p[1];
|
|
||||||
|
|
||||||
_ec.clear();
|
_ec.clear();
|
||||||
boost::fusion::for_each(seq, call_on_setup(*this));
|
boost::fusion::for_each(seq, call_on_setup(*this));
|
||||||
|
|
||||||
if (_ec)
|
if (_ec)
|
||||||
{
|
{
|
||||||
boost::fusion::for_each(seq, call_on_error(*this, _ec));
|
boost::fusion::for_each(seq, call_on_error(*this, _ec));
|
||||||
_pipe_sink = -1;
|
|
||||||
return child();
|
return child();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -417,20 +413,20 @@ child executor<Sequence>::invoke(boost::mpl::false_, boost::mpl::false_)
|
|||||||
this->pid = ::fork();
|
this->pid = ::fork();
|
||||||
if (pid == -1)
|
if (pid == -1)
|
||||||
{
|
{
|
||||||
_ec = boost::process::v1::detail::get_last_error();
|
_ec = boost::process::detail::get_last_error();
|
||||||
_msg = "fork() failed";
|
_msg = "fork() failed";
|
||||||
boost::fusion::for_each(seq, call_on_fork_error(*this, _ec));
|
boost::fusion::for_each(seq, call_on_fork_error(*this, _ec));
|
||||||
boost::fusion::for_each(seq, call_on_error(*this, _ec));
|
boost::fusion::for_each(seq, call_on_error(*this, _ec));
|
||||||
_pipe_sink = -1;
|
|
||||||
return child();
|
return child();
|
||||||
}
|
}
|
||||||
else if (pid == 0)
|
else if (pid == 0)
|
||||||
{
|
{
|
||||||
|
_pipe_sink = p.p[1];
|
||||||
::close(p.p[0]);
|
::close(p.p[0]);
|
||||||
|
|
||||||
boost::fusion::for_each(seq, call_on_exec_setup(*this));
|
boost::fusion::for_each(seq, call_on_exec_setup(*this));
|
||||||
::execve(exe, cmd_line, env);
|
::execve(exe, cmd_line, env);
|
||||||
_ec = boost::process::v1::detail::get_last_error();
|
_ec = boost::process::detail::get_last_error();
|
||||||
_msg = "execve failed";
|
_msg = "execve failed";
|
||||||
boost::fusion::for_each(seq, call_on_exec_error(*this, _ec));
|
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]);
|
::close(p.p[1]);
|
||||||
p.p[1] = -1;
|
p.p[1] = -1;
|
||||||
_pipe_sink = -1;
|
|
||||||
_read_error(p.p[0]);
|
_read_error(p.p[0]);
|
||||||
|
|
||||||
}
|
}
|
||||||
if (_ec)
|
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);
|
::waitpid(this->pid, nullptr, WNOHANG);
|
||||||
boost::fusion::for_each(seq, call_on_error(*this, _ec));
|
boost::fusion::for_each(seq, call_on_error(*this, _ec));
|
||||||
return child();
|
return child();
|
||||||
@@ -480,7 +475,7 @@ child executor<Sequence>::invoke(boost::mpl::true_, boost::mpl::true_) //ignore
|
|||||||
this->pid = ::vfork();
|
this->pid = ::vfork();
|
||||||
if (pid == -1)
|
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));
|
boost::fusion::for_each(seq, call_on_fork_error(*this, ec));
|
||||||
return child();
|
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));
|
boost::fusion::for_each(seq, call_on_exec_setup(*this));
|
||||||
::execve(exe, cmd_line, env);
|
::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));
|
boost::fusion::for_each(seq, call_on_exec_error(*this, ec));
|
||||||
_exit(EXIT_FAILURE);
|
_exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
@@ -516,7 +511,7 @@ child executor<Sequence>::invoke(boost::mpl::false_, boost::mpl::true_)
|
|||||||
this->pid = ::vfork();
|
this->pid = ::vfork();
|
||||||
if (pid == -1)
|
if (pid == -1)
|
||||||
{
|
{
|
||||||
_ec = boost::process::v1::detail::get_last_error();
|
_ec = boost::process::detail::get_last_error();
|
||||||
_msg = "fork() failed";
|
_msg = "fork() failed";
|
||||||
boost::fusion::for_each(seq, call_on_fork_error(*this, _ec));
|
boost::fusion::for_each(seq, call_on_fork_error(*this, _ec));
|
||||||
boost::fusion::for_each(seq, call_on_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);
|
::execve(exe, cmd_line, env);
|
||||||
|
|
||||||
_ec = boost::process::v1::detail::get_last_error();
|
_ec = boost::process::detail::get_last_error();
|
||||||
_msg = "execve failed";
|
_msg = "execve failed";
|
||||||
boost::fusion::for_each(seq, call_on_exec_error(*this, _ec));
|
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);
|
return executor<Tup>(tup);
|
||||||
}
|
}
|
||||||
|
|
||||||
}}}}}
|
}}}}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -10,15 +10,15 @@
|
|||||||
#ifndef BOOST_PROCESS_DETAIL_POSIX_FD_HPP
|
#ifndef BOOST_PROCESS_DETAIL_POSIX_FD_HPP
|
||||||
#define 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 <unistd.h>
|
||||||
#include <boost/process/v1/detail/used_handles.hpp>
|
#include <boost/process/detail/used_handles.hpp>
|
||||||
#include <array>
|
#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) {}
|
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
|
void on_exec_setup(PosixExecutor& e) const
|
||||||
{
|
{
|
||||||
if (::close(fd_) == -1)
|
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_;}
|
int get_used_handles() {return fd_;}
|
||||||
@@ -37,7 +37,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <class Range>
|
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:
|
public:
|
||||||
close_fds_(const Range &fds) : fds_(fds) {}
|
close_fds_(const Range &fds) : fds_(fds) {}
|
||||||
@@ -48,7 +48,7 @@ public:
|
|||||||
for (auto & fd_ : fds_)
|
for (auto & fd_ : fds_)
|
||||||
if (::close(fd_) == -1)
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -62,7 +62,7 @@ private:
|
|||||||
|
|
||||||
|
|
||||||
template <class FileDescriptor>
|
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:
|
public:
|
||||||
bind_fd_(int id, const FileDescriptor &fd) : id_(id), fd_(fd) {}
|
bind_fd_(int id, const FileDescriptor &fd) : id_(id), fd_(fd) {}
|
||||||
@@ -71,7 +71,7 @@ public:
|
|||||||
void on_exec_setup(PosixExecutor& e) const
|
void on_exec_setup(PosixExecutor& e) const
|
||||||
{
|
{
|
||||||
if (::dup2(fd_, id_) == -1)
|
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_};}
|
std::array<int, 2> get_used_handles() {return {id_, fd_};}
|
||||||
@@ -97,6 +97,6 @@ struct fd_
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
}}}}}
|
}}}}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -8,10 +8,10 @@
|
|||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <boost/process/v1/filesystem.hpp>
|
#include <boost/process/filesystem.hpp>
|
||||||
#include <boost/core/exchange.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
|
struct file_descriptor
|
||||||
{
|
{
|
||||||
@@ -24,7 +24,7 @@ struct file_descriptor
|
|||||||
|
|
||||||
|
|
||||||
file_descriptor() = default;
|
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)
|
: file_descriptor(p.native(), mode)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -84,6 +84,6 @@ private:
|
|||||||
int _handle = -1;
|
int _handle = -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
}}}}}
|
}}}}
|
||||||
|
|
||||||
#endif /* BOOST_PROCESS_DETAIL_WINDOWS_FILE_DESCRIPTOR_HPP_ */
|
#endif /* BOOST_PROCESS_DETAIL_WINDOWS_FILE_DESCRIPTOR_HPP_ */
|
||||||
@@ -10,16 +10,16 @@
|
|||||||
#ifndef BOOST_PROCESS_DETAIL_POSIX_FILE_IN_HPP
|
#ifndef BOOST_PROCESS_DETAIL_POSIX_FILE_IN_HPP
|
||||||
#define BOOST_PROCESS_DETAIL_POSIX_FILE_IN_HPP
|
#define BOOST_PROCESS_DETAIL_POSIX_FILE_IN_HPP
|
||||||
|
|
||||||
#include <boost/process/v1/pipe.hpp>
|
#include <boost/process/pipe.hpp>
|
||||||
#include <boost/process/v1/detail/posix/handler.hpp>
|
#include <boost/process/detail/posix/handler.hpp>
|
||||||
#include <boost/process/v1/detail/posix/file_descriptor.hpp>
|
#include <boost/process/detail/posix/file_descriptor.hpp>
|
||||||
#include <boost/process/v1/detail/used_handles.hpp>
|
#include <boost/process/detail/used_handles.hpp>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <unistd.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 {
|
||||||
|
|
||||||
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;
|
file_descriptor file;
|
||||||
int handle = file.handle();
|
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
|
void on_exec_setup(WindowsExecutor &e) const
|
||||||
{
|
{
|
||||||
if (::dup2(handle, STDIN_FILENO) == -1)
|
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
|
#endif
|
||||||
@@ -11,15 +11,15 @@
|
|||||||
#ifndef BOOST_PROCESS_POSIX_FILE_OUT_HPP
|
#ifndef BOOST_PROCESS_POSIX_FILE_OUT_HPP
|
||||||
#define BOOST_PROCESS_POSIX_FILE_OUT_HPP
|
#define BOOST_PROCESS_POSIX_FILE_OUT_HPP
|
||||||
|
|
||||||
#include <boost/process/v1/detail/posix/handler.hpp>
|
#include <boost/process/detail/posix/handler.hpp>
|
||||||
#include <boost/process/v1/detail/posix/file_descriptor.hpp>
|
#include <boost/process/detail/posix/file_descriptor.hpp>
|
||||||
#include <boost/process/v1/detail/used_handles.hpp>
|
#include <boost/process/detail/used_handles.hpp>
|
||||||
#include <unistd.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 {
|
||||||
|
|
||||||
template<int p1, int p2>
|
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;
|
file_descriptor file;
|
||||||
int handle = file.handle();
|
int handle = file.handle();
|
||||||
@@ -45,7 +45,7 @@ template<typename Executor>
|
|||||||
void file_out<1,-1>::on_exec_setup(Executor &e) const
|
void file_out<1,-1>::on_exec_setup(Executor &e) const
|
||||||
{
|
{
|
||||||
if (::dup2(handle, STDOUT_FILENO) == -1)
|
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<>
|
template<>
|
||||||
@@ -53,7 +53,7 @@ template<typename Executor>
|
|||||||
void file_out<2,-1>::on_exec_setup(Executor &e) const
|
void file_out<2,-1>::on_exec_setup(Executor &e) const
|
||||||
{
|
{
|
||||||
if (::dup2(handle, STDERR_FILENO) == -1)
|
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<>
|
template<>
|
||||||
@@ -61,13 +61,13 @@ template<typename Executor>
|
|||||||
void file_out<1,2>::on_exec_setup(Executor &e) const
|
void file_out<1,2>::on_exec_setup(Executor &e) const
|
||||||
{
|
{
|
||||||
if (::dup2(handle, STDOUT_FILENO) == -1)
|
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)
|
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
|
#endif
|
||||||
@@ -6,12 +6,12 @@
|
|||||||
#ifndef BOOST_PROCESS_DETAIL_POSIX_GROUP_HPP_
|
#ifndef BOOST_PROCESS_DETAIL_POSIX_GROUP_HPP_
|
||||||
#define BOOST_PROCESS_DETAIL_POSIX_GROUP_HPP_
|
#define BOOST_PROCESS_DETAIL_POSIX_GROUP_HPP_
|
||||||
|
|
||||||
#include <boost/process/v1/detail/config.hpp>
|
#include <boost/process/detail/config.hpp>
|
||||||
#include <boost/process/v1/detail/posix/child_handle.hpp>
|
#include <boost/process/detail/posix/child_handle.hpp>
|
||||||
#include <system_error>
|
#include <system_error>
|
||||||
#include <unistd.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 {
|
||||||
|
|
||||||
struct group_handle
|
struct group_handle
|
||||||
{
|
{
|
||||||
@@ -70,7 +70,7 @@ struct group_handle
|
|||||||
inline void terminate(group_handle &p, std::error_code &ec) noexcept
|
inline void terminate(group_handle &p, std::error_code &ec) noexcept
|
||||||
{
|
{
|
||||||
if (::killpg(p.grp, SIGKILL) == -1)
|
if (::killpg(p.grp, SIGKILL) == -1)
|
||||||
ec = boost::process::v1::detail::get_last_error();
|
ec = boost::process::detail::get_last_error();
|
||||||
else
|
else
|
||||||
ec.clear();
|
ec.clear();
|
||||||
|
|
||||||
@@ -81,7 +81,7 @@ inline void terminate(group_handle &p)
|
|||||||
{
|
{
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
terminate(p, 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()
|
inline bool in_group()
|
||||||
@@ -89,6 +89,6 @@ inline bool in_group()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}}}}}
|
}}}}
|
||||||
|
|
||||||
#endif /* BOOST_PROCESS_DETAIL_WINDOWS_GROUP_HPP_ */
|
#endif /* BOOST_PROCESS_DETAIL_WINDOWS_GROUP_HPP_ */
|
||||||
@@ -6,13 +6,13 @@
|
|||||||
#ifndef BOOST_PROCESS_DETAIL_POSIX_GROUP_REF_HPP_
|
#ifndef BOOST_PROCESS_DETAIL_POSIX_GROUP_REF_HPP_
|
||||||
#define 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/detail/config.hpp>
|
||||||
#include <boost/process/v1/detail/posix/group_handle.hpp>
|
#include <boost/process/detail/posix/group_handle.hpp>
|
||||||
#include <boost/process/v1/detail/posix/handler.hpp>
|
#include <boost/process/detail/posix/handler.hpp>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
|
||||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 {
|
namespace boost { namespace process {
|
||||||
|
|
||||||
namespace detail { namespace posix {
|
namespace detail { namespace posix {
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ struct group_ref : handler_base_ext
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}}}}}
|
}}}}
|
||||||
|
|
||||||
|
|
||||||
#endif /* BOOST_PROCESS_DETAIL_POSIX_GROUP_REF_HPP_ */
|
#endif /* BOOST_PROCESS_DETAIL_POSIX_GROUP_REF_HPP_ */
|
||||||
@@ -6,9 +6,9 @@
|
|||||||
#ifndef BOOST_PROCESS_DETAIL_POSIX_HANDLER_HPP_
|
#ifndef BOOST_PROCESS_DETAIL_POSIX_HANDLER_HPP_
|
||||||
#define 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.
|
//does not extend anything.
|
||||||
struct handler_base_ext : handler_base
|
struct handler_base_ext : handler_base
|
||||||
@@ -67,7 +67,7 @@ private:
|
|||||||
Handler handler_;
|
Handler handler_;
|
||||||
};
|
};
|
||||||
|
|
||||||
}}}}}
|
}}}}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -13,9 +13,9 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <cstdlib>
|
#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;
|
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);}};
|
std::unique_ptr<DIR, void(*)(DIR*)> dir{::opendir("/dev/fd"), +[](DIR* p){::closedir(p);}};
|
||||||
if (!dir)
|
if (!dir)
|
||||||
{
|
{
|
||||||
ec = ::boost::process::v1::detail::get_last_error();
|
ec = ::boost::process::detail::get_last_error();
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ec.clear();
|
ec.clear();
|
||||||
|
|
||||||
auto my_fd = dirfd(dir.get());
|
auto my_fd = ::dirfd(dir.get());
|
||||||
|
|
||||||
struct ::dirent * ent_p;
|
struct ::dirent * ent_p;
|
||||||
|
|
||||||
@@ -60,7 +60,7 @@ inline std::vector<native_handle_type> get_handles()
|
|||||||
|
|
||||||
auto res = get_handles(ec);
|
auto res = get_handles(ec);
|
||||||
if (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;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -72,7 +72,7 @@ inline bool is_stream_handle(native_handle_type handle, std::error_code & ec)
|
|||||||
|
|
||||||
if (::fstat(handle, &stat_) != 0)
|
if (::fstat(handle, &stat_) != 0)
|
||||||
{
|
{
|
||||||
ec = ::boost::process::v1::detail::get_last_error();
|
ec = ::boost::process::detail::get_last_error();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ec.clear();
|
ec.clear();
|
||||||
@@ -90,7 +90,7 @@ inline bool is_stream_handle(native_handle_type handle)
|
|||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
auto res = is_stream_handle(handle, ec);
|
auto res = is_stream_handle(handle, ec);
|
||||||
if (ec)
|
if (ec)
|
||||||
boost::process::v1::detail::throw_error(ec, "fstat() failed");
|
boost::process::detail::throw_error(ec, "fstat() failed");
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -113,11 +113,11 @@ struct limit_handles_ : handler_base_ext
|
|||||||
auto dir = ::opendir("/dev/fd");
|
auto dir = ::opendir("/dev/fd");
|
||||||
if (!dir)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto my_fd = dirfd(dir);
|
auto my_fd = ::dirfd(dir);
|
||||||
struct ::dirent * ent_p;
|
struct ::dirent * ent_p;
|
||||||
|
|
||||||
while ((ent_p = readdir(dir)) != nullptr)
|
while ((ent_p = readdir(dir)) != nullptr)
|
||||||
@@ -135,7 +135,7 @@ struct limit_handles_ : handler_base_ext
|
|||||||
|
|
||||||
if (::close(conv) != 0)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -143,6 +143,6 @@ struct limit_handles_ : handler_base_ext
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}}}}}
|
}}}}
|
||||||
|
|
||||||
#endif //PROCESS_HANDLES_HPP
|
#endif //PROCESS_HANDLES_HPP
|
||||||
@@ -6,8 +6,8 @@
|
|||||||
#ifndef BOOST_PROCESS_POSIX_IO_CONTEXT_REF_HPP_
|
#ifndef BOOST_PROCESS_POSIX_IO_CONTEXT_REF_HPP_
|
||||||
#define 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/detail/posix/handler.hpp>
|
||||||
#include <boost/process/v1/detail/posix/async_handler.hpp>
|
#include <boost/process/detail/posix/async_handler.hpp>
|
||||||
#include <boost/asio/io_context.hpp>
|
#include <boost/asio/io_context.hpp>
|
||||||
|
|
||||||
#include <boost/fusion/algorithm/iteration/for_each.hpp>
|
#include <boost/fusion/algorithm/iteration/for_each.hpp>
|
||||||
@@ -17,8 +17,8 @@
|
|||||||
#include <boost/fusion/container/vector/convert.hpp>
|
#include <boost/fusion/container/vector/convert.hpp>
|
||||||
|
|
||||||
|
|
||||||
#include <boost/process/v1/detail/posix/sigchld_service.hpp>
|
#include <boost/process/detail/posix/sigchld_service.hpp>
|
||||||
#include <boost/process/v1/detail/posix/is_running.hpp>
|
#include <boost/process/detail/posix/is_running.hpp>
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <sys/wait.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 {
|
||||||
|
|
||||||
template<typename Executor>
|
template<typename Executor>
|
||||||
struct on_exit_handler_transformer
|
struct on_exit_handler_transformer
|
||||||
@@ -80,7 +80,7 @@ struct io_context_ref : handler_base_ext
|
|||||||
void on_success(Executor& exec)
|
void on_success(Executor& exec)
|
||||||
{
|
{
|
||||||
ios.notify_fork(boost::asio::io_context::fork_parent);
|
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<
|
auto asyncs = boost::fusion::filter_if<
|
||||||
is_async_handler<
|
is_async_handler<
|
||||||
typename std::remove_reference< boost::mpl::_ > ::type
|
typename std::remove_reference< boost::mpl::_ > ::type
|
||||||
@@ -100,7 +100,7 @@ struct io_context_ref : handler_base_ext
|
|||||||
{
|
{
|
||||||
es->store(val);
|
es->store(val);
|
||||||
for (auto & func : funcs)
|
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));
|
sigchld_service.async_wait(exec.pid, std::move(wh));
|
||||||
@@ -117,9 +117,9 @@ struct io_context_ref : handler_base_ext
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
boost::asio::io_context &ios;
|
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_ */
|
#endif /* BOOST_PROCESS_WINDOWS_IO_CONTEXT_REF_HPP_ */
|
||||||
@@ -6,12 +6,12 @@
|
|||||||
#ifndef BOOST_PROCESS_DETAIL_POSIX_IS_RUNNING_HPP
|
#ifndef BOOST_PROCESS_DETAIL_POSIX_IS_RUNNING_HPP
|
||||||
#define 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/detail/config.hpp>
|
||||||
#include <boost/process/v1/detail/posix/child_handle.hpp>
|
#include <boost/process/detail/posix/child_handle.hpp>
|
||||||
#include <system_error>
|
#include <system_error>
|
||||||
#include <sys/wait.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 {
|
||||||
|
|
||||||
// Use the "stopped" state (WIFSTOPPED) to indicate "not terminated".
|
// 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
|
// 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 (ret == -1)
|
||||||
{
|
{
|
||||||
if (errno != ECHILD) //because it no child is running, then this one isn't either, obviously.
|
if (errno != ECHILD) //because it no child is running, than this one isn't either, obviously.
|
||||||
ec = ::boost::process::v1::detail::get_last_error();
|
ec = ::boost::process::detail::get_last_error();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (ret == 0)
|
else if (ret == 0)
|
||||||
@@ -55,7 +55,7 @@ inline bool is_running(const child_handle &p, int & exit_code)
|
|||||||
{
|
{
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
bool b = is_running(p, exit_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;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,6 +75,6 @@ inline int eval_exit_status(int code)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}}}}}
|
}}}}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -10,16 +10,16 @@
|
|||||||
#ifndef BOOST_PROCESS_DETAIL_POSIX_NULL_IN_HPP
|
#ifndef BOOST_PROCESS_DETAIL_POSIX_NULL_IN_HPP
|
||||||
#define BOOST_PROCESS_DETAIL_POSIX_NULL_IN_HPP
|
#define BOOST_PROCESS_DETAIL_POSIX_NULL_IN_HPP
|
||||||
|
|
||||||
#include <boost/process/v1/pipe.hpp>
|
#include <boost/process/pipe.hpp>
|
||||||
#include <boost/process/v1/detail/posix/handler.hpp>
|
#include <boost/process/detail/posix/handler.hpp>
|
||||||
#include <boost/process/v1/detail/posix/file_descriptor.hpp>
|
#include <boost/process/detail/posix/file_descriptor.hpp>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <boost/process/v1/detail/used_handles.hpp>
|
#include <boost/process/detail/used_handles.hpp>
|
||||||
#include <array>
|
#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};
|
file_descriptor source{"/dev/null", file_descriptor::read};
|
||||||
|
|
||||||
@@ -34,10 +34,10 @@ public:
|
|||||||
void on_exec_setup(Executor &e) const
|
void on_exec_setup(Executor &e) const
|
||||||
{
|
{
|
||||||
if (::dup2(source.handle(), STDIN_FILENO) == -1)
|
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
|
#endif
|
||||||
@@ -11,16 +11,16 @@
|
|||||||
#ifndef BOOST_PROCESS_POSIX_PIPE_OUT_HPP
|
#ifndef BOOST_PROCESS_POSIX_PIPE_OUT_HPP
|
||||||
#define BOOST_PROCESS_POSIX_PIPE_OUT_HPP
|
#define BOOST_PROCESS_POSIX_PIPE_OUT_HPP
|
||||||
|
|
||||||
#include <boost/process/v1/detail/posix/handler.hpp>
|
#include <boost/process/detail/posix/handler.hpp>
|
||||||
#include <boost/process/v1/detail/posix/file_descriptor.hpp>
|
#include <boost/process/detail/posix/file_descriptor.hpp>
|
||||||
#include <boost/process/v1/detail/used_handles.hpp>
|
#include <boost/process/detail/used_handles.hpp>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <array>
|
#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>
|
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};
|
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
|
void null_out<1,-1>::on_exec_setup(Executor &e) const
|
||||||
{
|
{
|
||||||
if (::dup2(sink.handle(), STDOUT_FILENO) == -1)
|
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<>
|
template<>
|
||||||
@@ -49,7 +49,7 @@ template<typename Executor>
|
|||||||
void null_out<2,-1>::on_exec_setup(Executor &e) const
|
void null_out<2,-1>::on_exec_setup(Executor &e) const
|
||||||
{
|
{
|
||||||
if (::dup2(sink.handle(), STDERR_FILENO) == -1)
|
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<>
|
template<>
|
||||||
@@ -57,12 +57,12 @@ template<typename Executor>
|
|||||||
void null_out<1,2>::on_exec_setup(Executor &e) const
|
void null_out<1,2>::on_exec_setup(Executor &e) const
|
||||||
{
|
{
|
||||||
if (::dup2(sink.handle(), STDOUT_FILENO) == -1)
|
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)
|
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
|
#endif
|
||||||
@@ -7,21 +7,21 @@
|
|||||||
#define BOOST_PROCESS_POSIX_ON_EXIT_HPP_
|
#define BOOST_PROCESS_POSIX_ON_EXIT_HPP_
|
||||||
|
|
||||||
#include <boost/asio/execution.hpp>
|
#include <boost/asio/execution.hpp>
|
||||||
#include <boost/process/v1/async.hpp>
|
#include <boost/process/async.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/detail/handler_base.hpp>
|
||||||
#include <boost/process/v1/detail/posix/async_handler.hpp>
|
#include <boost/process/detail/posix/async_handler.hpp>
|
||||||
#include <system_error>
|
#include <system_error>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail {
|
namespace boost { namespace process { namespace detail {
|
||||||
|
|
||||||
template<typename Tuple>
|
template<typename Tuple>
|
||||||
inline asio::io_context& get_io_context(const Tuple & tup);
|
inline asio::io_context& get_io_context(const Tuple & tup);
|
||||||
|
|
||||||
namespace posix {
|
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;
|
std::function<void(int, const std::error_code&)> handler;
|
||||||
on_exit_(const std::function<void(int, const std::error_code&)> & handler) : handler(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>
|
template<typename Executor>
|
||||||
std::function<void(int, const std::error_code&)> on_exit_handler(Executor& exec)
|
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);
|
boost::asio::execution::outstanding_work.tracked);
|
||||||
auto handler_ = this->handler;
|
auto handler_ = this->handler;
|
||||||
return
|
return
|
||||||
@@ -44,5 +44,5 @@ struct on_exit_ : boost::process::v1::detail::posix::async_handler
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
}}}}}
|
}}}}
|
||||||
#endif /* BOOST_PROCESS_POSIX_ON_EXIT_HPP_ */
|
#endif /* BOOST_PROCESS_POSIX_ON_EXIT_HPP_ */
|
||||||
@@ -10,15 +10,15 @@
|
|||||||
#ifndef BOOST_PROCESS_POSIX_PIPE_IN_HPP
|
#ifndef BOOST_PROCESS_POSIX_PIPE_IN_HPP
|
||||||
#define BOOST_PROCESS_POSIX_PIPE_IN_HPP
|
#define BOOST_PROCESS_POSIX_PIPE_IN_HPP
|
||||||
|
|
||||||
#include <boost/process/v1/pipe.hpp>
|
#include <boost/process/pipe.hpp>
|
||||||
#include <boost/process/v1/detail/posix/handler.hpp>
|
#include <boost/process/detail/posix/handler.hpp>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <boost/process/v1/detail/used_handles.hpp>
|
#include <boost/process/detail/used_handles.hpp>
|
||||||
#include <array>
|
#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 source;
|
||||||
int sink; //opposite end
|
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
|
void on_exec_setup(Executor &e) const
|
||||||
{
|
{
|
||||||
if (::dup2(source, STDIN_FILENO) == -1)
|
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)
|
if (source != STDIN_FILENO)
|
||||||
::close(source);
|
::close(source);
|
||||||
|
|
||||||
@@ -93,6 +93,6 @@ struct async_pipe_in : public pipe_in
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}}}}}
|
}}}}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -11,28 +11,18 @@
|
|||||||
#ifndef BOOST_PROCESS_DETAIL_POSIX_PIPE_OUT_HPP
|
#ifndef BOOST_PROCESS_DETAIL_POSIX_PIPE_OUT_HPP
|
||||||
#define BOOST_PROCESS_DETAIL_POSIX_PIPE_OUT_HPP
|
#define BOOST_PROCESS_DETAIL_POSIX_PIPE_OUT_HPP
|
||||||
|
|
||||||
#include <boost/process/v1/pipe.hpp>
|
#include <boost/process/pipe.hpp>
|
||||||
#include <boost/process/v1/detail/posix/handler.hpp>
|
#include <boost/process/detail/posix/handler.hpp>
|
||||||
#include <unistd.h>
|
#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>
|
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 sink;
|
||||||
int source; //opposite end
|
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) {}
|
pipe_out(int sink, int source) : sink(sink), source(source) {}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
@@ -62,7 +52,7 @@ template<typename Executor>
|
|||||||
void pipe_out<1,-1>::on_exec_setup(Executor &e) const
|
void pipe_out<1,-1>::on_exec_setup(Executor &e) const
|
||||||
{
|
{
|
||||||
if (::dup2(sink, STDOUT_FILENO) == -1)
|
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)
|
if (sink != STDOUT_FILENO)
|
||||||
::close(sink);
|
::close(sink);
|
||||||
@@ -74,7 +64,7 @@ template<typename Executor>
|
|||||||
void pipe_out<2,-1>::on_exec_setup(Executor &e) const
|
void pipe_out<2,-1>::on_exec_setup(Executor &e) const
|
||||||
{
|
{
|
||||||
if (::dup2(sink, STDERR_FILENO) == -1)
|
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)
|
if (sink != STDOUT_FILENO)
|
||||||
::close(sink);
|
::close(sink);
|
||||||
@@ -86,12 +76,11 @@ template<typename Executor>
|
|||||||
void pipe_out<1,2>::on_exec_setup(Executor &e) const
|
void pipe_out<1,2>::on_exec_setup(Executor &e) const
|
||||||
{
|
{
|
||||||
if (::dup2(sink, STDOUT_FILENO) == -1)
|
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)
|
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))
|
if ((sink != STDOUT_FILENO) && (sink != STDERR_FILENO))
|
||||||
::close(sink);
|
::close(sink);
|
||||||
::close(source);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class async_pipe;
|
class async_pipe;
|
||||||
@@ -126,6 +115,6 @@ struct async_pipe_out : public pipe_out<p1, p2>
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
}}}}}
|
}}}}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -10,21 +10,21 @@
|
|||||||
#ifndef BOOST_PROCESS_POSIX_SEARCH_PATH_HPP
|
#ifndef BOOST_PROCESS_POSIX_SEARCH_PATH_HPP
|
||||||
#define BOOST_PROCESS_POSIX_SEARCH_PATH_HPP
|
#define BOOST_PROCESS_POSIX_SEARCH_PATH_HPP
|
||||||
|
|
||||||
#include <boost/process/v1/detail/config.hpp>
|
#include <boost/process/detail/config.hpp>
|
||||||
#include <boost/process/v1/filesystem.hpp>
|
#include <boost/process/filesystem.hpp>
|
||||||
#include <boost/tokenizer.hpp>
|
#include <boost/tokenizer.hpp>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.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(
|
inline boost::process::filesystem::path search_path(
|
||||||
const boost::process::v1::filesystem::path &filename,
|
const boost::process::filesystem::path &filename,
|
||||||
const std::vector<boost::process::v1::filesystem::path> &path)
|
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;
|
auto p = pp / filename;
|
||||||
#if defined(BOOST_PROCESS_USE_STD_FS)
|
#if defined(BOOST_PROCESS_USE_STD_FS)
|
||||||
@@ -32,13 +32,13 @@ inline boost::process::v1::filesystem::path search_path(
|
|||||||
#else
|
#else
|
||||||
boost::system::error_code ec;
|
boost::system::error_code ec;
|
||||||
#endif
|
#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)
|
if (!ec && file && ::access(p.c_str(), X_OK) == 0)
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
}}}}}
|
}}}}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -10,23 +10,23 @@
|
|||||||
#ifndef BOOST_PROCESS_POSIX_SHELL_PATH_HPP
|
#ifndef BOOST_PROCESS_POSIX_SHELL_PATH_HPP
|
||||||
#define 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/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";
|
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();
|
ec.clear();
|
||||||
return "/bin/sh";
|
return "/bin/sh";
|
||||||
}
|
}
|
||||||
|
|
||||||
}}}}}
|
}}}}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <list>
|
#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>
|
class sigchld_service : public boost::asio::detail::service_base<sigchld_service>
|
||||||
{
|
{
|
||||||
@@ -145,7 +145,7 @@ void sigchld_service::_handle_signal(const boost::system::error_code & ec)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -11,10 +11,10 @@
|
|||||||
#ifndef BOOST_PROCESS_POSIX_SIGNAL_HPP
|
#ifndef BOOST_PROCESS_POSIX_SIGNAL_HPP
|
||||||
#define 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>
|
#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__)
|
#if defined(__GLIBC__)
|
||||||
using sighandler_t = ::sighandler_t;
|
using sighandler_t = ::sighandler_t;
|
||||||
@@ -55,16 +55,16 @@ struct sig_init_ : handler_base_ext
|
|||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
bool _reset = false;
|
bool _reset = false;
|
||||||
::boost::process::v1::detail::posix::sighandler_t _old{0};
|
::boost::process::detail::posix::sighandler_t _old{0};
|
||||||
::boost::process::v1::detail::posix::sighandler_t _handler{0};
|
::boost::process::detail::posix::sighandler_t _handler{0};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sig_
|
struct sig_
|
||||||
{
|
{
|
||||||
constexpr sig_() {}
|
constexpr sig_() {}
|
||||||
|
|
||||||
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::v1::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_ dfl() const {return SIG_DFL;}
|
||||||
sig_init_ ign() const {return SIG_IGN;}
|
sig_init_ ign() const {return SIG_IGN;}
|
||||||
|
|
||||||
@@ -74,6 +74,6 @@ struct sig_
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
}}}}}
|
}}}}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -10,12 +10,12 @@
|
|||||||
#ifndef BOOST_PROCESS_DETAIL_POSIX_START_DIR_HPP
|
#ifndef BOOST_PROCESS_DETAIL_POSIX_START_DIR_HPP
|
||||||
#define 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 <string>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <boost/core/ignore_unused.hpp>
|
#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>
|
template<typename Char>
|
||||||
struct start_dir_init : handler_base_ext
|
struct start_dir_init : handler_base_ext
|
||||||
@@ -34,6 +34,6 @@ private:
|
|||||||
string_type s_;
|
string_type s_;
|
||||||
};
|
};
|
||||||
|
|
||||||
}}}}}
|
}}}}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -10,19 +10,19 @@
|
|||||||
#ifndef BOOST_PROCESS_DETAIL_POSIX_TERMINATE_HPP
|
#ifndef BOOST_PROCESS_DETAIL_POSIX_TERMINATE_HPP
|
||||||
#define BOOST_PROCESS_DETAIL_POSIX_TERMINATE_HPP
|
#define BOOST_PROCESS_DETAIL_POSIX_TERMINATE_HPP
|
||||||
|
|
||||||
#include <boost/process/v1/detail/config.hpp>
|
#include <boost/process/detail/config.hpp>
|
||||||
#include <boost/process/v1/detail/posix/child_handle.hpp>
|
#include <boost/process/detail/posix/child_handle.hpp>
|
||||||
#include <system_error>
|
#include <system_error>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <sys/wait.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
|
inline void terminate(const child_handle &p, std::error_code &ec) noexcept
|
||||||
{
|
{
|
||||||
if (::kill(p.pid, SIGKILL) == -1)
|
if (::kill(p.pid, SIGKILL) == -1)
|
||||||
ec = boost::process::v1::detail::get_last_error();
|
ec = boost::process::detail::get_last_error();
|
||||||
else
|
else
|
||||||
ec.clear();
|
ec.clear();
|
||||||
|
|
||||||
@@ -34,9 +34,9 @@ inline void terminate(const child_handle &p)
|
|||||||
{
|
{
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
terminate(p, ec);
|
terminate(p, ec);
|
||||||
boost::process::v1::detail::throw_error(ec, "kill(2) failed");
|
boost::process::detail::throw_error(ec, "kill(2) failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
}}}}}
|
}}}}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -9,11 +9,11 @@
|
|||||||
#define BOOST_PROCESS_DETAIL_POSIX_USE_VFORK_HPP_
|
#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/sequence/intrinsic/has_key.hpp>
|
||||||
#include <boost/fusion/container/set/convert.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
|
struct use_vfork_ : handler_base_ext
|
||||||
{
|
{
|
||||||
@@ -28,6 +28,6 @@ struct shall_use_vfork
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
}}}}}
|
}}}}
|
||||||
|
|
||||||
#endif /* BOOST_PROCESS_DETAIL_POSIX_USE_VFORK_HPP_ */
|
#endif /* BOOST_PROCESS_DETAIL_POSIX_USE_VFORK_HPP_ */
|
||||||
@@ -10,14 +10,14 @@
|
|||||||
#ifndef BOOST_PROCESS_DETAIL_POSIX_WAIT_FOR_EXIT_HPP
|
#ifndef BOOST_PROCESS_DETAIL_POSIX_WAIT_FOR_EXIT_HPP
|
||||||
#define 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/detail/config.hpp>
|
||||||
#include <boost/process/v1/detail/posix/child_handle.hpp>
|
#include <boost/process/detail/posix/child_handle.hpp>
|
||||||
#include <system_error>
|
#include <system_error>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <unistd.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
|
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)));
|
(ret != -1 && !WIFEXITED(status) && !WIFSIGNALED(status)));
|
||||||
|
|
||||||
if (ret == -1)
|
if (ret == -1)
|
||||||
ec = boost::process::v1::detail::get_last_error();
|
ec = boost::process::detail::get_last_error();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ec.clear();
|
ec.clear();
|
||||||
@@ -44,7 +44,7 @@ inline void wait(const child_handle &p, int & exit_code) noexcept
|
|||||||
{
|
{
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
wait(p, exit_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 >
|
template< class Clock, class Duration >
|
||||||
@@ -131,7 +131,7 @@ inline bool wait_until(
|
|||||||
pid_t timeout_pid = ::fork();
|
pid_t timeout_pid = ::fork();
|
||||||
if (timeout_pid == -1)
|
if (timeout_pid == -1)
|
||||||
{
|
{
|
||||||
ec = boost::process::v1::detail::get_last_error();
|
ec = boost::process::detail::get_last_error();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (timeout_pid == 0)
|
else if (timeout_pid == 0)
|
||||||
@@ -192,7 +192,7 @@ inline bool wait_until(
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (ret == -1)
|
if (ret == -1)
|
||||||
ec = boost::process::v1::detail::get_last_error();
|
ec = boost::process::detail::get_last_error();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ec.clear();
|
ec.clear();
|
||||||
@@ -210,7 +210,7 @@ inline bool wait_until(
|
|||||||
{
|
{
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
bool b = wait_until(p, exit_code, time_out, 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;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,10 +232,10 @@ inline bool wait_for(
|
|||||||
{
|
{
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
bool b = wait_for(p, exit_code, rel_time, 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;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
}}}}}
|
}}}}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -10,15 +10,15 @@
|
|||||||
#ifndef BOOST_PROCESS_DETAIL_POSIX_WAIT_GROUP_HPP
|
#ifndef BOOST_PROCESS_DETAIL_POSIX_WAIT_GROUP_HPP
|
||||||
#define 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/detail/config.hpp>
|
||||||
#include <boost/process/v1/detail/posix/group_handle.hpp>
|
#include <boost/process/detail/posix/group_handle.hpp>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <system_error>
|
#include <system_error>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <unistd.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
|
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));
|
while ((ret != -1) || (errno != ECHILD));
|
||||||
|
|
||||||
if (errno != ECHILD)
|
if (errno != ECHILD)
|
||||||
ec = boost::process::v1::detail::get_last_error();
|
ec = boost::process::detail::get_last_error();
|
||||||
else
|
else
|
||||||
ec.clear();
|
ec.clear();
|
||||||
}
|
}
|
||||||
@@ -49,7 +49,7 @@ inline void wait(const group_handle &p) noexcept
|
|||||||
{
|
{
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
wait(p, 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 >
|
template< class Clock, class Duration >
|
||||||
@@ -79,7 +79,7 @@ inline bool wait_until(
|
|||||||
ec.clear();
|
ec.clear();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
ec = boost::process::v1::detail::get_last_error();
|
ec = boost::process::detail::get_last_error();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
//we can wait, because unlike in the wait_for_exit, we have no race condition regarding eh exit code.
|
//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;
|
std::error_code ec;
|
||||||
bool b = wait_until(p, time_out, 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;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,10 +115,10 @@ inline bool wait_for(
|
|||||||
{
|
{
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
bool b = wait_for(p, rel_time, 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;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
}}}}}
|
}}}}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -11,12 +11,12 @@
|
|||||||
#ifndef BOOST_PROCESS_DETAIL_INITIALIZERS_THROW_ON_ERROR_HPP
|
#ifndef BOOST_PROCESS_DETAIL_INITIALIZERS_THROW_ON_ERROR_HPP
|
||||||
#define 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/detail/config.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 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>
|
template <class Executor>
|
||||||
void on_error(Executor& exec, const std::error_code & ec) const
|
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
|
#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_
|
#ifndef BOOST_PROCESS_DETAIL_TRAITS_ASYNC_HPP_
|
||||||
#define BOOST_PROCESS_DETAIL_TRAITS_ASYNC_HPP_
|
#define BOOST_PROCESS_DETAIL_TRAITS_ASYNC_HPP_
|
||||||
|
|
||||||
#include <boost/process/v1/detail/config.hpp>
|
#include <boost/process/detail/config.hpp>
|
||||||
#include <boost/process/v1/detail/traits/decl.hpp>
|
#include <boost/process/detail/traits/decl.hpp>
|
||||||
|
|
||||||
namespace boost { namespace asio {
|
namespace boost { namespace asio {
|
||||||
|
|
||||||
class io_context;
|
class io_context;
|
||||||
}}
|
}}
|
||||||
|
|
||||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail {
|
namespace boost { namespace process { namespace detail {
|
||||||
|
|
||||||
struct async_tag {};
|
struct async_tag {};
|
||||||
|
|
||||||
@@ -27,6 +27,8 @@ template<> struct initializer_tag<::boost::asio::io_context> { typedef async_tag
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
}}}}
|
}}}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* BOOST_PROCESS_DETAIL_HANDLER_HPP_ */
|
#endif /* BOOST_PROCESS_DETAIL_HANDLER_HPP_ */
|
||||||
@@ -11,11 +11,9 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
#include <boost/process/v1/filesystem.hpp>
|
#include <boost/process/filesystem.hpp>
|
||||||
#include <boost/process/v1/detail/traits/decl.hpp>
|
#include <boost/process/detail/traits/decl.hpp>
|
||||||
|
namespace boost { namespace process { namespace detail {
|
||||||
|
|
||||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail {
|
|
||||||
|
|
||||||
template<typename Char>
|
template<typename Char>
|
||||||
struct cmd_or_exe_tag {};
|
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_>
|
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>
|
template <typename Char>
|
||||||
@@ -80,6 +78,8 @@ template<>
|
|||||||
struct initializer_builder<cmd_or_exe_tag<wchar_t>>;
|
struct initializer_builder<cmd_or_exe_tag<wchar_t>>;
|
||||||
|
|
||||||
|
|
||||||
}}}}
|
}}}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* BOOST_PROCESS_DETAIL_STRING_TRAITS_HPP_ */
|
#endif /* BOOST_PROCESS_DETAIL_STRING_TRAITS_HPP_ */
|
||||||
@@ -7,18 +7,18 @@
|
|||||||
#ifndef BOOST_PROCESS_DETAIL_TRAITS_DECL_HPP_
|
#ifndef BOOST_PROCESS_DETAIL_TRAITS_DECL_HPP_
|
||||||
#define 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 <boost/none.hpp>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
#if defined(BOOST_POSIX_API)
|
#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)
|
#elif defined(BOOST_WINDOWS_API)
|
||||||
#include <boost/process/v1/detail/windows/handler.hpp>
|
#include <boost/process/detail/windows/handler.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail {
|
namespace boost { namespace process { namespace detail {
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
@@ -69,6 +69,8 @@ struct valid_argument_list
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
}}}}
|
}}}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* BOOST_PROCESS_DETAIL_HANDLER_HPP_ */
|
#endif /* BOOST_PROCESS_DETAIL_HANDLER_HPP_ */
|
||||||
@@ -6,10 +6,11 @@
|
|||||||
#ifndef BOOST_PROCESS_DETAIL_TRAITS_ENV_HPP_
|
#ifndef BOOST_PROCESS_DETAIL_TRAITS_ENV_HPP_
|
||||||
#define 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>
|
template<typename Char>
|
||||||
class basic_environment;
|
class basic_environment;
|
||||||
@@ -22,6 +23,9 @@ namespace detail {
|
|||||||
template<typename Char>
|
template<typename Char>
|
||||||
struct env_tag {};
|
struct env_tag {};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template<typename Char> struct env_set;
|
template<typename Char> struct env_set;
|
||||||
template<typename Char> struct env_append;
|
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_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<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::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_native_environment<Char>> { typedef env_tag<Char> type; };
|
||||||
|
|
||||||
template<> struct initializer_builder<env_tag<char>>;
|
template<> struct initializer_builder<env_tag<char>>;
|
||||||
template<> struct initializer_builder<env_tag<wchar_t>>;
|
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_ */
|
#endif /* INCLUDE_BOOST_PROCESS_DETAIL_ENV_HPP_ */
|
||||||
@@ -7,19 +7,21 @@
|
|||||||
#ifndef BOOST_PROCESS_DETAIL_TRAITS_ERROR_HPP_
|
#ifndef BOOST_PROCESS_DETAIL_TRAITS_ERROR_HPP_
|
||||||
#define 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 <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;
|
struct error_tag;
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
struct initializer_tag<std::error_code>;
|
struct initializer_tag<std::error_code>;
|
||||||
|
|
||||||
}}}}
|
}}}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* BOOST_PROCESS_DETAIL_HANDLER_HPP_ */
|
#endif /* BOOST_PROCESS_DETAIL_HANDLER_HPP_ */
|
||||||
@@ -7,12 +7,12 @@
|
|||||||
#ifndef BOOST_PROCESS_DETAIL_TRAITS_GROUP_HPP_
|
#ifndef BOOST_PROCESS_DETAIL_TRAITS_GROUP_HPP_
|
||||||
#define BOOST_PROCESS_DETAIL_TRAITS_GROUP_HPP_
|
#define BOOST_PROCESS_DETAIL_TRAITS_GROUP_HPP_
|
||||||
|
|
||||||
#include <boost/process/v1/detail/config.hpp>
|
#include <boost/process/detail/config.hpp>
|
||||||
#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 boost { namespace process {
|
||||||
|
|
||||||
struct group;
|
struct group;
|
||||||
|
|
||||||
@@ -25,12 +25,12 @@ template<>
|
|||||||
struct make_initializer_t<group_tag>;
|
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 <algorithm>
|
||||||
|
|
||||||
#include <boost/process/v1/detail/traits/decl.hpp>
|
#include <boost/process/detail/traits/decl.hpp>
|
||||||
#include <boost/process/v1/detail/traits/cmd_or_exe.hpp>
|
#include <boost/process/detail/traits/cmd_or_exe.hpp>
|
||||||
#include <boost/process/v1/detail/traits/env.hpp>
|
#include <boost/process/detail/traits/env.hpp>
|
||||||
#include <boost/process/v1/locale.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
|
||||||
|
|
||||||
template<typename T> struct is_wchar_t : std::false_type {};
|
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;
|
std::size_t size = 0;
|
||||||
while (in[size] != L'\0') size++;
|
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;
|
std::size_t size = 0;
|
||||||
while (in[size] != L'\0') size++;
|
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])
|
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;
|
std::size_t size = 0;
|
||||||
while (in[size] != '\0') size++;
|
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;
|
std::size_t size = 0;
|
||||||
while (in[size] != '\0') size++;
|
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])
|
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)
|
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)
|
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_ */
|
#endif /* BOOST_PROCESS_DETAIL_TRAITS_WCHAR_T_HPP_ */
|
||||||
@@ -11,14 +11,14 @@
|
|||||||
#include <boost/fusion/include/for_each.hpp>
|
#include <boost/fusion/include/for_each.hpp>
|
||||||
|
|
||||||
#if defined(BOOST_POSIX_API)
|
#if defined(BOOST_POSIX_API)
|
||||||
#include <boost/process/v1/detail/posix/handles.hpp>
|
#include <boost/process/detail/posix/handles.hpp>
|
||||||
#include <boost/process/v1/detail/posix/asio_fwd.hpp>
|
#include <boost/process/detail/posix/asio_fwd.hpp>
|
||||||
#else
|
#else
|
||||||
#include <boost/process/v1/detail/windows/handles.hpp>
|
#include <boost/process/detail/windows/handles.hpp>
|
||||||
#include <boost/process/v1/detail/windows/asio_fwd.hpp>
|
#include <boost/process/detail/windows/asio_fwd.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace boost { namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail {
|
namespace boost { namespace process { namespace detail {
|
||||||
|
|
||||||
struct uses_handles
|
struct uses_handles
|
||||||
{
|
{
|
||||||
@@ -52,7 +52,7 @@ struct foreach_handle_invocator
|
|||||||
func(handle_);
|
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>
|
template<typename T>
|
||||||
void operator()(T & val) const {invoke(val.get_used_handles());}
|
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>
|
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)
|
get_used_handles(Executor &exec)
|
||||||
{
|
{
|
||||||
std::vector<::boost::process::v1::detail::api::native_handle_type> res = exec.get_used_handles();
|
std::vector<::boost::process::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);});
|
foreach_used_handle(exec, [&](::boost::process::detail::api::native_handle_type handle){res.push_back(handle);});
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}}}}
|
}}}
|
||||||
|
|
||||||
#endif /* BOOST_PROCESS_DETAIL_USED_HANDLES_HPP_ */
|
#endif /* BOOST_PROCESS_DETAIL_USED_HANDLES_HPP_ */
|
||||||
@@ -6,9 +6,8 @@
|
|||||||
#ifndef BOOST_PROCESS_DETAIL_WINDOWS_ASIO_FWD_HPP_
|
#ifndef BOOST_PROCESS_DETAIL_WINDOWS_ASIO_FWD_HPP_
|
||||||
#define 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 <memory>
|
||||||
|
#include <boost/asio/ts/netfwd.hpp>
|
||||||
|
|
||||||
namespace boost { namespace asio {
|
namespace boost { namespace asio {
|
||||||
|
|
||||||
@@ -38,7 +37,7 @@ typedef basic_object_handle<any_io_executor> object_handle;
|
|||||||
} //windows
|
} //windows
|
||||||
} //asio
|
} //asio
|
||||||
|
|
||||||
namespace process { BOOST_PROCESS_V1_INLINE namespace v1 { namespace detail { namespace windows {
|
namespace process { namespace detail { namespace windows {
|
||||||
|
|
||||||
class async_pipe;
|
class async_pipe;
|
||||||
|
|
||||||
@@ -54,9 +53,8 @@ struct async_out_future;
|
|||||||
} // windows
|
} // windows
|
||||||
} // detail
|
} // detail
|
||||||
|
|
||||||
using ::boost::process::v1::detail::windows::async_pipe;
|
using ::boost::process::detail::windows::async_pipe;
|
||||||
|
|
||||||
} // v1
|
|
||||||
} // process
|
} // process
|
||||||
} // boost
|
} // boost
|
||||||
|
|
||||||
@@ -7,11 +7,10 @@
|
|||||||
#ifndef BOOST_PROCESS_WINDOWS_ASYNC_HANDLER_HPP_
|
#ifndef BOOST_PROCESS_WINDOWS_ASYNC_HANDLER_HPP_
|
||||||
#define BOOST_PROCESS_WINDOWS_ASYNC_HANDLER_HPP_
|
#define BOOST_PROCESS_WINDOWS_ASYNC_HANDLER_HPP_
|
||||||
|
|
||||||
#include <boost/process/v1/detail/config.hpp>
|
#include <boost/process/detail/windows/handler.hpp>
|
||||||
#include <boost/process/v1/detail/windows/handler.hpp>
|
|
||||||
#include <type_traits>
|
#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 {};
|
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> {};
|
struct does_require_io_context<const T&> : std::is_base_of<require_io_context, T> {};
|
||||||
|
|
||||||
|
|
||||||
}}}}}
|
}}}}
|
||||||
|
|
||||||
#endif /* BOOST_PROCESS_WINDOWS_ASYNC_HANDLER_HPP_ */
|
#endif /* BOOST_PROCESS_WINDOWS_ASYNC_HANDLER_HPP_ */
|
||||||
@@ -16,21 +16,21 @@
|
|||||||
#include <boost/winapi/error_codes.hpp>
|
#include <boost/winapi/error_codes.hpp>
|
||||||
|
|
||||||
#include <boost/asio/write.hpp>
|
#include <boost/asio/write.hpp>
|
||||||
#include <boost/process/v1/detail/handler_base.hpp>
|
#include <boost/process/detail/handler_base.hpp>
|
||||||
#include <boost/process/v1/detail/used_handles.hpp>
|
#include <boost/process/detail/used_handles.hpp>
|
||||||
#include <boost/process/v1/detail/windows/async_handler.hpp>
|
#include <boost/process/detail/windows/async_handler.hpp>
|
||||||
#include <boost/process/v1/detail/windows/asio_fwd.hpp>
|
#include <boost/process/detail/windows/asio_fwd.hpp>
|
||||||
#include <boost/process/v1/async_pipe.hpp>
|
#include <boost/process/async_pipe.hpp>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <future>
|
#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>
|
template<typename Buffer>
|
||||||
struct async_in_buffer : ::boost::process::v1::detail::windows::handler_base_ext,
|
struct async_in_buffer : ::boost::process::detail::windows::handler_base_ext,
|
||||||
::boost::process::v1::detail::windows::require_io_context,
|
::boost::process::detail::windows::require_io_context,
|
||||||
::boost::process::v1::detail::uses_handles
|
::boost::process::detail::uses_handles
|
||||||
{
|
{
|
||||||
Buffer & buf;
|
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);
|
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
|
::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)
|
void on_setup(WindowsExecutor &exec)
|
||||||
{
|
{
|
||||||
if (!pipe)
|
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();
|
::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
|
#endif
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user