mirror of
https://github.com/boostorg/process.git
synced 2026-01-19 04:22:15 +00:00
examples are compiled & included.
This commit is contained in:
committed by
Klemens Morgenstern
parent
c33828a166
commit
3fd8b2608c
25
doc/env.adoc
25
doc/env.adoc
@@ -14,33 +14,18 @@ as to have the right value comparisons.
|
||||
|
||||
To note is the `find_executable` functions, which searches in an environment for an executable.
|
||||
|
||||
.example/env.cpp:19-28
|
||||
[source,cpp]
|
||||
----
|
||||
// search in the current environment
|
||||
auto exe = environment::find_executable("g++");
|
||||
|
||||
std::unordered_map<environment::key, environment::value> my_env =
|
||||
{
|
||||
{"SECRET", "THIS_IS_A_TEST"},
|
||||
{"PATH", {"/bin", "/usr/bin"}}
|
||||
};
|
||||
|
||||
auto other_exe = environment::find_executable("g++", my_env);
|
||||
include::../example/env.cpp[tag=current_env]
|
||||
----
|
||||
|
||||
== Subprocess environment
|
||||
|
||||
The subprocess environment assignment follows the same constraints:
|
||||
|
||||
[source,cpp]
|
||||
.example/env.cpp:34-42
|
||||
[source,cpp,ident=0]
|
||||
----
|
||||
asio::io_context ctx;
|
||||
std::unordered_map<environment::key, environment::value> my_env =
|
||||
{
|
||||
{"SECRET", "THIS_IS_A_TEST"},
|
||||
{"PATH", {"/bin", "/usr/bin"}}
|
||||
};
|
||||
auto exe = find_executable("g++");
|
||||
process proc(ctx, exe, {"main.cpp"}, process_environment(my_env));
|
||||
process pro2(ctx, exe, {"test.cpp"}, process_environment(my_env));
|
||||
include::../example/env.cpp[tag=subprocess_env]
|
||||
----
|
||||
|
||||
@@ -7,14 +7,10 @@ A process needs four things to be launched:
|
||||
* a list of arguments
|
||||
* a variadic set of initializers
|
||||
|
||||
[source,cpp]
|
||||
.example/quickstart.cpp:13-17
|
||||
[source,cpp,indent=0]
|
||||
----
|
||||
// process(asio::any_io_executor, filesystem::path, range<string> args, AdditionalInitializers...)
|
||||
asio::io_context ctx;
|
||||
process proc(ctx.get_executor(), // <1>
|
||||
"/usr/bin/cp", // <2>
|
||||
{"source.txt", "target.txt"} // <3>
|
||||
); // <4>
|
||||
include::../example/quickstart.cpp[tag=cp]
|
||||
----
|
||||
<1> The executor for the process handle
|
||||
<2> The Path to the executable
|
||||
@@ -33,10 +29,10 @@ A process that completed will deliver an exit-code,
|
||||
which can be obtained by calling `.exit_code` on the exited process and which is
|
||||
also returned from `.wait()`.
|
||||
|
||||
[source,cpp]
|
||||
.example/quickstart.cpp:22-23
|
||||
[source,cpp, indent=0]
|
||||
----
|
||||
process proc("/bin/ls", {});
|
||||
assert(proc.wait() == 0);
|
||||
include::../example/quickstart.cpp[tag=ls]
|
||||
----
|
||||
|
||||
The normal exit-code is what the subprocess returned from `main`;
|
||||
@@ -54,32 +50,30 @@ The parent process can signal the subprocess demanding certain actions.
|
||||
`.terminate` will cause the subprocess to exit immediately (`SIGKILL` on posix).
|
||||
This is the only reliable & portable way to end a subprocess.
|
||||
|
||||
[source,cpp]
|
||||
.example/quickstart.cpp:28-29
|
||||
[source,cpp,indent=0]
|
||||
----
|
||||
process proc("/bin/totally-not-a-virus", {});
|
||||
proc.terminate();
|
||||
include::../example/quickstart.cpp[tag=terminate]
|
||||
----
|
||||
|
||||
`.request_exit` will ask the subprocess to shutdown (`SIGTERM` on posix),
|
||||
which the subprocess might ignore.
|
||||
|
||||
.example/quickstart.cpp:34-36
|
||||
[source,cpp]
|
||||
----
|
||||
process proc("/bin/bash", {});
|
||||
proc.request_exit();
|
||||
proc.wait();
|
||||
include::../example/quickstart.cpp[tag=request_exit]
|
||||
----
|
||||
|
||||
`.interrupt` will send an SIGINT to the subprocess, which a subprocess might
|
||||
interpret as a signal to shutdown.
|
||||
interpret as a signal for shutdown.
|
||||
|
||||
WARNING: interrupt requires the initializer `windows::create_new_process_group` to be set on windows
|
||||
|
||||
.example/quickstart.cpp:41-43
|
||||
[source,cpp]
|
||||
----
|
||||
process proc("/usr/bin/addr2line", {});
|
||||
proc.request_exit();
|
||||
proc.wait();
|
||||
include::../example/quickstart.cpp[tag=interrupt]
|
||||
----
|
||||
|
||||
[endsect]
|
||||
@@ -88,9 +82,10 @@ proc.wait();
|
||||
|
||||
Process v2 provides `execute` and `async_execute` functions that can be used for managed executions.
|
||||
|
||||
.example/quickstart.cpp:48
|
||||
[source,cpp]
|
||||
----
|
||||
assert(execute(process("/bin/ls", {}) == 0));
|
||||
include::../example/quickstart.cpp[tag=execute]
|
||||
----
|
||||
|
||||
The async version supports cancellation and will forward cancellation types as follows:
|
||||
@@ -99,14 +94,10 @@ The async version supports cancellation and will forward cancellation types as f
|
||||
- `asio::cancellation_type::partial` -> request_exit
|
||||
- `asio::cancellation_type::terminal` -> terminate
|
||||
|
||||
.example/quickstart.cpp:53-56
|
||||
[source,cpp]
|
||||
----
|
||||
asio::awaitable<void> compile()
|
||||
{
|
||||
co_await async_execute(process("/usr/bin/g++", {"hello_world.cpp"}))
|
||||
(asio::cancel_after(std::chrono::seconds(10, asio::cancellation_type::partial)) // <1>
|
||||
(asio::cancel_after(std::chrono::seconds(10, asio::cancellation_type::terminal)); //<2>
|
||||
}
|
||||
include::../example/quickstart.cpp[tag=async_execute]
|
||||
----
|
||||
<1> After 10 seconds send a request_exit.
|
||||
<2> After 20 seconds terminate
|
||||
|
||||
@@ -2,11 +2,10 @@
|
||||
|
||||
The easier initializer to use is `process_start_dir`:
|
||||
|
||||
[source,cpp]
|
||||
.example/start_dir.cpp:17-20
|
||||
[source,cpp,indent=0]
|
||||
----
|
||||
asio::io_context ctx;
|
||||
process ls(ctx.get_executor(), "/ls", {}, process_start_dir("/home"));
|
||||
ls.wait();
|
||||
include::../example/start_dir.cpp[tag=start_dir]
|
||||
----
|
||||
|
||||
This will run `ls` in the folder `/home` instead of the current folder.
|
||||
|
||||
@@ -10,18 +10,10 @@ This feature meant to be flexible, which is why there is little checking on the
|
||||
asio pipes can be used for io. When using in process_stdio they will get
|
||||
automatically connected and the other side will get assigned to the child process:
|
||||
|
||||
[source,cpp]
|
||||
.example/stdio.cpp:20-29
|
||||
[source,cpp,indent=0]
|
||||
----
|
||||
asio::io_context ctx;
|
||||
asio::readable_pipe rp{ctx};
|
||||
|
||||
process proc(ctx, "/usr/bin/g++", {"--version"}, process_stdio{{ /* in to default */}, rp, { /* err to default */ }});
|
||||
std::string output;
|
||||
|
||||
system::error_code ec;
|
||||
rp.read(asio::dynamic_buffer(output), ec);
|
||||
assert(ec == asio::eof);
|
||||
proc.wait();
|
||||
include::../example/stdio.cpp[tag=readable_pipe]
|
||||
----
|
||||
|
||||
readable pipes can be assigned to `out` an `err`, while writable_pipes can be assigned to `in`.
|
||||
@@ -30,12 +22,10 @@ readable pipes can be assigned to `out` an `err`, while writable_pipes can be as
|
||||
|
||||
`FILE*` can also be used for either side; this allows the `stdin`, `stderr`, `stdout` macros to be used:
|
||||
|
||||
.example/stdio.cpp:35-38
|
||||
[source,cpp]
|
||||
----
|
||||
asio::io_context ctx;
|
||||
// forward both stderr & stdout to stdout of the parent process
|
||||
process proc(ctx, "/usr/bin/g++", {"--version"}, process_stdio{{ /* in to default */}, stdout, stdout});
|
||||
proc.wait();
|
||||
include::../example/stdio.cpp[tag=file]
|
||||
----
|
||||
|
||||
== `nullptr`
|
||||
@@ -43,12 +33,10 @@ proc.wait();
|
||||
`nullptr` may be used to set a given stream to be opened on the null-device (`/dev/null` on posix, `NUL` on windows).
|
||||
This is used to ignore output or give only EOF as input.
|
||||
|
||||
.example/stdio.cpp:43-46
|
||||
[source,cpp]
|
||||
----
|
||||
asio::io_context ctx;
|
||||
// ignore stderr
|
||||
process proc(ctx, "/usr/bin/g++", {"--version"}, process_stdio{{ /* in to default */}, {}, nullptr});
|
||||
proc.wait();
|
||||
include::../example/stdio.cpp[tag=null]
|
||||
----
|
||||
|
||||
== `native_handle`
|
||||
@@ -56,14 +44,10 @@ proc.wait();
|
||||
A native handle can be used as well, which means an `int` on posix or a `HANDLE` on windows.
|
||||
Furthermore, any object that has a `native_handle` returning that native handle type is valid, too.
|
||||
|
||||
.example/stdio.cpp:51-56
|
||||
[source,cpp]
|
||||
----
|
||||
asio::io_context ctx;
|
||||
// ignore stderr
|
||||
asio::ip::tcp::socket sock{ctx};
|
||||
connect_my_socket(sock);
|
||||
process proc(ctx, "~/not-a-virus", {}, process_stdio{sock, sock, nullptr});
|
||||
proc.wait();
|
||||
include::../example/stdio.cpp[tag=native_handle]
|
||||
----
|
||||
|
||||
== popen
|
||||
@@ -71,11 +55,9 @@ proc.wait();
|
||||
Additionally, process v2 provides a `popen` class.
|
||||
It starts a process and connects pipes for stdin and stdout, so that the popen object can be used as a stream.
|
||||
|
||||
.example/stdio.cpp:61-64
|
||||
[source,cpp]
|
||||
----
|
||||
popen proc(executor, "/usr/bin/addr2line, {argv[0]});
|
||||
asio::write(proc, asio::buffer("main\n"));
|
||||
std::string line;
|
||||
asio::read_until(proc, asio::dynamic_buffer(line), '\n');
|
||||
include::../example/stdio.cpp[tag=popen]
|
||||
----
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ For process v2, the interfaces is simple:
|
||||
----
|
||||
extern std::unordered_map<std::string, std::string> my_env;
|
||||
extern asio::io_context ctx;
|
||||
process proc(ctx, "./test", {"--help"}, process_io{nullptr, {}, {}}, process_environment(my_env));
|
||||
process proc(ctx, "./test", {"--help"}, process_stdio{nullptr, {}, {}}, process_environment(my_env));
|
||||
----
|
||||
|
||||
Every initializer addresses one logical component (e.g. stdio) instead of multiple ones accumulating.
|
||||
@@ -49,8 +49,6 @@ Windows has provided `HANDLE`s for processes all along.
|
||||
Unless the OS doesn't support it, process v2 will use file descriptors and handles to implement waiting
|
||||
for processes.
|
||||
|
||||
|
||||
|
||||
== Full asio integration
|
||||
|
||||
Process v1 aimed to make asio optional, but synchronous IO with subprocesses usually means one is begging
|
||||
|
||||
@@ -1,28 +1,19 @@
|
||||
# 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) 2022 Klemens 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)
|
||||
|
||||
project : requirements
|
||||
<library>/boost/process//boost_process
|
||||
<toolset>msvc:<define>_SCL_SECURE_NO_WARNINGS
|
||||
<target-os>windows:<define>WIN32_LEAN_AND_MEAN
|
||||
<link>static
|
||||
;
|
||||
|
||||
import testing ;
|
||||
|
||||
compile args.cpp ;
|
||||
compile async_io.cpp ;
|
||||
compile env.cpp ;
|
||||
compile error_handling.cpp ;
|
||||
compile io.cpp ;
|
||||
compile posix.cpp : <build>no <target-os>linux:<build>yes ;
|
||||
compile start_dir.cpp ;
|
||||
compile sync_io.cpp ;
|
||||
compile terminate.cpp ;
|
||||
compile wait.cpp ;
|
||||
compile windows.cpp : <build>no <target-os>windows:<build>yes ;
|
||||
exe intro : intro.cpp /boost//process : <boost.process.fs>boost ;
|
||||
exe intro_popen : intro_popen.cpp /boost//process : <boost.process.fs>boost ;
|
||||
exe quickstart : quickstart.cpp /boost//process : <boost.process.fs>boost ;
|
||||
exe env : env.cpp /boost//process : <boost.process.fs>boost ;
|
||||
exe start_dir : start_dir.cpp /boost//process : <boost.process.fs>boost ;
|
||||
exe stdio : stdio.cpp /boost//process : <boost.process.fs>boost ;
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
||||
// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
|
||||
// Copyright (c) 2009 Boris Schaeling
|
||||
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
|
||||
// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/process.hpp>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
namespace bp = boost::process;
|
||||
|
||||
int main()
|
||||
{
|
||||
bp::child c("test.exe", "--foo", "/bar");
|
||||
|
||||
//or explicit
|
||||
|
||||
bp::child c2(
|
||||
bp::exe="test.exe",
|
||||
bp::args={"--foo", "/bar"}
|
||||
);
|
||||
|
||||
c.wait();
|
||||
c2.wait();
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
||||
// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
|
||||
// Copyright (c) 2009 Boris Schaeling
|
||||
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
|
||||
// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/process.hpp>
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/array.hpp>
|
||||
#include <string>
|
||||
|
||||
namespace bp = boost::process;
|
||||
|
||||
int main()
|
||||
{
|
||||
boost::asio::io_context ios;
|
||||
boost::asio::streambuf buffer;
|
||||
|
||||
|
||||
bp::child c(
|
||||
"test.exe",
|
||||
bp::std_out > buffer,
|
||||
ios
|
||||
);
|
||||
|
||||
ios.run();
|
||||
}
|
||||
@@ -9,16 +9,37 @@
|
||||
|
||||
#include <boost/process.hpp>
|
||||
|
||||
namespace bp = boost::process;
|
||||
using namespace boost::process;
|
||||
namespace asio = boost::asio;
|
||||
|
||||
int main()
|
||||
{
|
||||
bp::environment my_env = boost::this_process::environment();
|
||||
{
|
||||
// tag::current_env[]
|
||||
// search in the current environment
|
||||
auto exe = environment::find_executable("g++");
|
||||
|
||||
my_env["PATH"] += "/foo";
|
||||
bp::system("test.exe", my_env);
|
||||
std::unordered_map <environment::key, environment::value> my_env =
|
||||
{
|
||||
{"SECRET", "THIS_IS_A_TEST"},
|
||||
{"PATH", {"/bin", "/usr/bin"}}
|
||||
};
|
||||
|
||||
auto other_exe = environment::find_executable("g++", my_env);
|
||||
//end::current_env[]
|
||||
}
|
||||
|
||||
|
||||
bp::system("test.exe", bp::env["PATH"]+="/bar");
|
||||
{
|
||||
// tag::subprocess_env[]
|
||||
asio::io_context ctx;
|
||||
std::unordered_map<environment::key, environment::value> my_env =
|
||||
{
|
||||
{"SECRET", "THIS_IS_A_TEST"},
|
||||
{"PATH", {"/bin", "/usr/bin"}}
|
||||
};
|
||||
auto exe = environment::find_executable("g++", my_env);
|
||||
process proc(ctx, exe, {"main.cpp"}, process_environment(my_env));
|
||||
process pro2(ctx, exe, {"test.cpp"}, process_environment(my_env));
|
||||
// end::subprocess_env[]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
||||
// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
|
||||
// Copyright (c) 2009 Boris Schaeling
|
||||
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
|
||||
// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/process.hpp>
|
||||
#include <system_error>
|
||||
|
||||
namespace bp = boost::process;
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
std::error_code ec;
|
||||
bp::child c1("test.exe", ec);
|
||||
|
||||
|
||||
bp::child c2("test.exe", bp::ignore_error);
|
||||
|
||||
}
|
||||
@@ -1,8 +1,4 @@
|
||||
// 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) 2022 Klemens 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)
|
||||
@@ -10,21 +6,35 @@
|
||||
//[intro
|
||||
#include <boost/process.hpp>
|
||||
|
||||
#include <boost/asio/read.hpp>
|
||||
#include <boost/asio/readable_pipe.hpp>
|
||||
#include <boost/system/error_code.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
using namespace boost::process;
|
||||
namespace proc = boost::process;
|
||||
namespace asio = boost::asio;
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
ipstream pipe_stream;
|
||||
child c("gcc --version", std_out > pipe_stream);
|
||||
asio::io_context ctx;
|
||||
asio::readable_pipe p{ctx};
|
||||
|
||||
const auto exe = proc::environment::find_executable("gcc");
|
||||
|
||||
proc::process c{ctx, exe, {"--version"}, proc::process_stdio{nullptr, p}};
|
||||
|
||||
std::string line;
|
||||
boost::system::error_code ec;
|
||||
|
||||
while (pipe_stream && std::getline(pipe_stream, line) && !line.empty())
|
||||
std::cerr << line << std::endl;
|
||||
auto sz = asio::read(p, asio::dynamic_buffer(line), ec);
|
||||
assert(ec == asio::error::eof);
|
||||
|
||||
std::cout << "Gcc version: '" << line << "'" << std::endl;
|
||||
|
||||
c.wait();
|
||||
return c.exit_code();
|
||||
}
|
||||
//]
|
||||
|
||||
@@ -3,8 +3,10 @@
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/core/ignore_unused.hpp>
|
||||
|
||||
//[intro
|
||||
#include <boost/process/v2.hpp>
|
||||
#include <boost/process.hpp>
|
||||
|
||||
#include <boost/asio/read.hpp>
|
||||
#include <boost/asio/readable_pipe.hpp>
|
||||
@@ -13,7 +15,7 @@
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
namespace proc = boost::process::v2;
|
||||
namespace proc = boost::process;
|
||||
namespace asio = boost::asio;
|
||||
|
||||
|
||||
@@ -29,8 +31,11 @@ int main()
|
||||
auto sz = asio::read(c, asio::dynamic_buffer(line), ec);
|
||||
assert(ec == asio::error::eof);
|
||||
|
||||
boost::ignore_unused(sz);
|
||||
|
||||
std::cout << "Gcc version: '" << line << "'" << std::endl;
|
||||
|
||||
c.wait();
|
||||
return c.exit_code();
|
||||
}
|
||||
//]
|
||||
@@ -1,91 +0,0 @@
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
||||
// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
|
||||
// Copyright (c) 2009 Boris Schaeling
|
||||
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
|
||||
// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/process.hpp>
|
||||
#include <string>
|
||||
|
||||
namespace bp = boost::process;
|
||||
|
||||
int main()
|
||||
{
|
||||
//
|
||||
bp::system(
|
||||
"test.exe",
|
||||
bp::std_out > stdout, //forward
|
||||
bp::std_err.close(), //close
|
||||
bp::std_in < bp::null //null in
|
||||
);
|
||||
|
||||
boost::process::v1::filesystem::path p = "input.txt";
|
||||
|
||||
bp::system(
|
||||
"test.exe",
|
||||
(bp::std_out & bp::std_err) > "output.txt", //redirect both to one file
|
||||
bp::std_in < p //read input from file
|
||||
);
|
||||
|
||||
{
|
||||
bp::opstream p1;
|
||||
bp::ipstream p2;
|
||||
bp::system(
|
||||
"test.exe",
|
||||
bp::std_out > p2,
|
||||
bp::std_in < p1
|
||||
);
|
||||
p1 << "my_text";
|
||||
int i = 0;
|
||||
p2 >> i;
|
||||
|
||||
}
|
||||
{
|
||||
boost::asio::io_context io_context;
|
||||
bp::async_pipe p1(io_context);
|
||||
bp::async_pipe p2(io_context);
|
||||
bp::system(
|
||||
"test.exe",
|
||||
bp::std_out > p2,
|
||||
bp::std_in < p1,
|
||||
io_context,
|
||||
bp::on_exit([&](int exit, const std::error_code& ec_in)
|
||||
{
|
||||
p1.async_close();
|
||||
p2.async_close();
|
||||
})
|
||||
);
|
||||
std::vector<char> in_buf;
|
||||
std::string value = "my_string";
|
||||
boost::asio::async_write(p1, boost::asio::buffer(value), []( const boost::system::error_code&, std::size_t){});
|
||||
boost::asio::async_read (p2, boost::asio::buffer(in_buf), []( const boost::system::error_code&, std::size_t){});
|
||||
}
|
||||
{
|
||||
boost::asio::io_context io_context;
|
||||
std::vector<char> in_buf;
|
||||
std::string value = "my_string";
|
||||
bp::system(
|
||||
"test.exe",
|
||||
bp::std_out > bp::buffer(in_buf),
|
||||
bp::std_in < bp::buffer(value)
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
boost::asio::io_context io_context;
|
||||
std::future<std::vector<char>> in_buf;
|
||||
std::future<void> write_fut;
|
||||
std::string value = "my_string";
|
||||
bp::system(
|
||||
"test.exe",
|
||||
bp::std_out > in_buf,
|
||||
bp::std_in < bp::buffer(value) > write_fut
|
||||
);
|
||||
|
||||
write_fut.get();
|
||||
in_buf.get();
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
||||
// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
|
||||
// Copyright (c) 2009 Boris Schaeling
|
||||
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
|
||||
// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/process.hpp>
|
||||
#include <boost/process/v1/posix.hpp>
|
||||
#include <boost/process/v1/extend.hpp>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
namespace bp = boost::process;
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
//duplicate our pipe descriptor into literal position 4
|
||||
bp::pipe p;
|
||||
bp::system("test", bp::posix::fd.bind(4, p.native_sink()));
|
||||
|
||||
|
||||
//close file-descriptor from explicit integral value
|
||||
bp::system("test", bp::posix::fd.close(STDIN_FILENO));
|
||||
|
||||
//close file-descriptors from explicit integral values
|
||||
bp::system("test", bp::posix::fd.close({STDIN_FILENO, STDOUT_FILENO}));
|
||||
|
||||
//add custom handlers
|
||||
const char *env[2] = { 0 };
|
||||
env[0] = "LANG=de";
|
||||
bp::system("test",
|
||||
bp::extend::on_setup([env](auto &e) { e.env = const_cast<char**>(env); }),
|
||||
bp::extend::on_fork_error([](auto&, const std::error_code & ec)
|
||||
{ std::cerr << errno << std::endl; }),
|
||||
bp::extend::on_exec_setup([](auto&)
|
||||
{ ::chroot("/new/root/directory/"); }),
|
||||
bp::extend::on_exec_error([](auto&, const std::error_code & ec)
|
||||
{ std::ofstream ofs("log.txt"); if (ofs) ofs << errno; })
|
||||
);
|
||||
|
||||
}
|
||||
63
example/quickstart.cpp
Normal file
63
example/quickstart.cpp
Normal file
@@ -0,0 +1,63 @@
|
||||
#include <boost/process.hpp>
|
||||
#include <boost/asio.hpp>
|
||||
|
||||
namespace asio = boost::asio;
|
||||
using boost::process::process;
|
||||
|
||||
|
||||
int main(int /*argv*/, char ** /*argv*/)
|
||||
{
|
||||
asio::io_context ctx;
|
||||
{
|
||||
//tag::cp[]
|
||||
// process(asio::any_io_executor, filesystem::path, range<string> args, AdditionalInitializers...)
|
||||
process proc(ctx.get_executor(), // <1>
|
||||
"/usr/bin/cp", // <2>
|
||||
{"source.txt", "target.txt"} // <3>
|
||||
); // <4>
|
||||
//end::cp[]
|
||||
}
|
||||
{
|
||||
//tag::ls[]
|
||||
process proc(ctx, "/bin/ls", {});
|
||||
assert(proc.wait() == 0);
|
||||
//end::ls[]
|
||||
}
|
||||
{
|
||||
//tag::terminate[]
|
||||
process proc(ctx, "/bin/totally-not-a-virus", {});
|
||||
proc.terminate();
|
||||
//end::terminate[]
|
||||
}
|
||||
{
|
||||
//tag::request_exit[]
|
||||
process proc(ctx, "/bin/bash", {});
|
||||
proc.request_exit();
|
||||
proc.wait();
|
||||
//end::request_exit[]
|
||||
}
|
||||
{
|
||||
//tag::interrupt[]
|
||||
process proc(ctx, "/usr/bin/addr2line", {});
|
||||
proc.interrupt();
|
||||
proc.wait();
|
||||
//end::interrupt[]
|
||||
}
|
||||
{
|
||||
//tag::execute[]
|
||||
assert(execute(process(ctx, "/bin/ls", {})) == 0);
|
||||
//end::execute[]
|
||||
}
|
||||
{
|
||||
//tag::async_execute[]
|
||||
async_execute(process(ctx, "/usr/bin/g++", {"hello_world.cpp"}))
|
||||
(asio::cancel_after(std::chrono::seconds(10), asio::cancellation_type::partial)) // <1>
|
||||
(asio::cancel_after(std::chrono::seconds(10), asio::cancellation_type::terminal)) //<2>
|
||||
(asio::detached);
|
||||
//end::async_execute[]
|
||||
ctx.run();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,20 +8,15 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/process.hpp>
|
||||
#include <boost/process/v1/filesystem.hpp>
|
||||
|
||||
namespace bp = boost::process;
|
||||
using namespace boost::process;
|
||||
namespace asio = boost::asio;
|
||||
|
||||
int main()
|
||||
{
|
||||
bp::system(
|
||||
"test.exe",
|
||||
bp::start_dir="../foo"
|
||||
);
|
||||
|
||||
boost::process::v1::filesystem::path exe = "test.exe";
|
||||
bp::system(
|
||||
boost::process::v1::filesystem::absolute(exe),
|
||||
bp::start_dir="../foo"
|
||||
);
|
||||
// tag::start_dir[]
|
||||
asio::io_context ctx;
|
||||
process ls(ctx.get_executor(), "/ls", {}, process_start_dir("/home"));
|
||||
ls.wait();
|
||||
// end::start_dir[]
|
||||
}
|
||||
|
||||
68
example/stdio.cpp
Normal file
68
example/stdio.cpp
Normal file
@@ -0,0 +1,68 @@
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
||||
// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
|
||||
// Copyright (c) 2009 Boris Schaeling
|
||||
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
|
||||
// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/process.hpp>
|
||||
#include <boost/asio.hpp>
|
||||
|
||||
using namespace boost::process;
|
||||
namespace asio = boost::asio;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
{
|
||||
//tag::readable_pipe[]
|
||||
asio::io_context ctx;
|
||||
asio::readable_pipe rp{ctx};
|
||||
|
||||
process proc(ctx, "/usr/bin/g++", {"--version"}, process_stdio{{ /* in to default */}, rp, { /* err to default */ }});
|
||||
std::string output;
|
||||
|
||||
boost::system::error_code ec;
|
||||
asio::read(rp, asio::dynamic_buffer(output), ec);
|
||||
assert(!ec || (ec == asio::error::eof));
|
||||
proc.wait();
|
||||
//end::readable_pipe[]
|
||||
}
|
||||
|
||||
{
|
||||
//tag::file[]
|
||||
asio::io_context ctx;
|
||||
// forward both stderr & stdout to stdout of the parent process
|
||||
process proc(ctx, "/usr/bin/g++", {"--version"}, process_stdio{{ /* in to default */}, stdout, stdout});
|
||||
proc.wait();
|
||||
//end::file[]
|
||||
}
|
||||
{
|
||||
//tag::null[]
|
||||
asio::io_context ctx;
|
||||
// forward stderr to /dev/null or NUL
|
||||
process proc(ctx, "/usr/bin/g++", {"--version"}, process_stdio{{ /* in to default */}, {}, nullptr});
|
||||
proc.wait();
|
||||
//end::null[]
|
||||
}
|
||||
{
|
||||
//tag::native_handle[]
|
||||
asio::io_context ctx;
|
||||
// ignore stderr
|
||||
asio::local::stream_protocol::socket sock{ctx}, other{ctx};
|
||||
asio::local::connect_pair(sock, other);
|
||||
process proc(ctx, "~/not-a-virus", {}, process_stdio{sock, sock, nullptr});
|
||||
proc.wait();
|
||||
//end::native_handle[]
|
||||
}
|
||||
{
|
||||
//tag::popen[]
|
||||
asio::io_context ctx;
|
||||
boost::process::popen proc(ctx, "/usr/bin/addr2line", {argv[0]});
|
||||
asio::write(proc, asio::buffer("main\n"));
|
||||
std::string line;
|
||||
asio::read_until(proc, asio::dynamic_buffer(line), '\n');
|
||||
//end::popen[]
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
||||
// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
|
||||
// Copyright (c) 2009 Boris Schaeling
|
||||
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
|
||||
// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/process.hpp>
|
||||
#include <string>
|
||||
|
||||
namespace bp = boost::process;
|
||||
|
||||
int main()
|
||||
{
|
||||
bp::ipstream p;
|
||||
|
||||
bp::child c(
|
||||
"test.exe",
|
||||
bp::std_out > p
|
||||
);
|
||||
|
||||
std::string s;
|
||||
std::getline(p, s);
|
||||
|
||||
c.wait();
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
||||
// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
|
||||
// Copyright (c) 2009 Boris Schaeling
|
||||
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
|
||||
// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/process.hpp>
|
||||
|
||||
namespace bp = boost::process;
|
||||
|
||||
int main()
|
||||
{
|
||||
bp::child c("test.exe");
|
||||
c.terminate();
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
# Copyright (c) 2022 Klemens 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)
|
||||
|
||||
project : requirements
|
||||
<toolset>msvc:<define>_SCL_SECURE_NO_WARNINGS
|
||||
<target-os>windows:<define>WIN32_LEAN_AND_MEAN
|
||||
<link>static
|
||||
;
|
||||
|
||||
import testing ;
|
||||
|
||||
exe intro : intro.cpp ;
|
||||
exe intro_popen : intro_popen.cpp : <boost.process.fs>boost ;
|
||||
@@ -1,39 +0,0 @@
|
||||
// Copyright (c) 2022 Klemens 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)
|
||||
|
||||
//[intro
|
||||
#include <boost/process/v2.hpp>
|
||||
|
||||
#include <boost/asio/read.hpp>
|
||||
#include <boost/asio/readable_pipe.hpp>
|
||||
#include <boost/system/error_code.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
namespace proc = boost::process::v2;
|
||||
namespace asio = boost::asio;
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
asio::io_context ctx;
|
||||
asio::readable_pipe p{ctx};
|
||||
|
||||
const auto exe = proc::environment::find_executable("gcc");
|
||||
|
||||
proc::process c{ctx, exe, {"--version"}, proc::process_stdio{nullptr, p}};
|
||||
|
||||
std::string line;
|
||||
boost::system::error_code ec;
|
||||
|
||||
auto sz = asio::read(p, asio::dynamic_buffer(line), ec);
|
||||
assert(ec == asio::error::eof);
|
||||
|
||||
std::cout << "Gcc version: '" << line << "'" << std::endl;
|
||||
|
||||
c.wait();
|
||||
}
|
||||
//]
|
||||
@@ -1,34 +0,0 @@
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
||||
// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
|
||||
// Copyright (c) 2009 Boris Schaeling
|
||||
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
|
||||
// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/process.hpp>
|
||||
#include <boost/asio.hpp>
|
||||
|
||||
namespace bp = boost::process;
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
bp::child c("test.exe");
|
||||
c.wait();
|
||||
auto exit_code = c.exit_code();
|
||||
}
|
||||
|
||||
{
|
||||
boost::asio::io_context io_context;
|
||||
|
||||
bp::child c(
|
||||
"test.exe",
|
||||
io_context,
|
||||
bp::on_exit([&](int exit, const std::error_code& ec_in){})
|
||||
);
|
||||
|
||||
io_context.run();
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
||||
// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
|
||||
// Copyright (c) 2009 Boris Schaeling
|
||||
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
|
||||
// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/process.hpp>
|
||||
#include <boost/process/v1/extend.hpp>
|
||||
#include <boost/process/v1/windows.hpp>
|
||||
#include <iostream>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
namespace bp = boost::process;
|
||||
|
||||
int main()
|
||||
{
|
||||
bp::system("test.exe",
|
||||
bp::windows::show);
|
||||
|
||||
|
||||
bp::system("test.exe",
|
||||
bp::extend::on_setup([](auto &e)
|
||||
{ e.startup_info.dwFlags = STARTF_RUNFULLSCREEN; }),
|
||||
bp::extend::on_error([](auto&, const std::error_code & ec)
|
||||
{ std::cerr << ec.message() << std::endl; })
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user