mirror of
https://github.com/boostorg/process.git
synced 2026-01-20 04:42:24 +00:00
Compare commits
68 Commits
boost-1.73
...
boost-1.76
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b2a96a3e13 | ||
|
|
1dbb3626a9 | ||
|
|
d79e1f2443 | ||
|
|
605dcd19d8 | ||
|
|
6b6a6fa61c | ||
|
|
295e2bdd9c | ||
|
|
dd1513846b | ||
|
|
7a94abfaf2 | ||
|
|
b55a09479c | ||
|
|
5afb20760c | ||
|
|
eec87e1dd9 | ||
|
|
f250a33fb4 | ||
|
|
570cf83a96 | ||
|
|
d52d244f83 | ||
|
|
04ab646f12 | ||
|
|
31c65b5442 | ||
|
|
ebbb6d8b36 | ||
|
|
b9c0140a26 | ||
|
|
27f587a4be | ||
|
|
7f6061c956 | ||
|
|
2f32c95341 | ||
|
|
a8029fc191 | ||
|
|
9f4bd9bce3 | ||
|
|
71f844c24f | ||
|
|
b0b6d67e6f | ||
|
|
3a2576a4d8 | ||
|
|
34eaa262dd | ||
|
|
ce3b3d8f99 | ||
|
|
429f2ba95c | ||
|
|
0c2e7387c8 | ||
|
|
2a2ea4b92d | ||
|
|
873ab2558d | ||
|
|
03571d4eaf | ||
|
|
46ab3ba9b8 | ||
|
|
3aba1f6eb1 | ||
|
|
44771769fa | ||
|
|
8704416941 | ||
|
|
f48392399f | ||
|
|
80f81117aa | ||
|
|
9cff55215d | ||
|
|
2e4b3c2406 | ||
|
|
b510b6a9d9 | ||
|
|
046b96186f | ||
|
|
1df2e67bc4 | ||
|
|
6cf69e2797 | ||
|
|
d3e4cbf3b3 | ||
|
|
e67e49c891 | ||
|
|
29a43b17e4 | ||
|
|
6d10c3a807 | ||
|
|
668579ed6f | ||
|
|
8af828cd43 | ||
|
|
590cc10b42 | ||
|
|
3bc11ce3ac | ||
|
|
603441ecc3 | ||
|
|
612a953369 | ||
|
|
1554773d39 | ||
|
|
dd003bf2b0 | ||
|
|
1502de1001 | ||
|
|
8541cae396 | ||
|
|
38fa1fd040 | ||
|
|
ba15f760ab | ||
|
|
5e3e8f977e | ||
|
|
6182876d4f | ||
|
|
5bfd2ee08c | ||
|
|
c91b227c47 | ||
|
|
192191ecfb | ||
|
|
3aeb6601cd | ||
|
|
8a7c37617e |
@@ -133,5 +133,4 @@ after_success:
|
||||
after_script:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
- cd $BOOST/libs/$PROJECT_TO_TEST/test
|
||||
- curl -s https://report.ci/upload.py | python - --name="$BADGE test run" --root_dir $BOOST
|
||||
|
||||
- curl -s https://report.ci/report.py | python - --name="$BADGE test run"
|
||||
|
||||
@@ -16,11 +16,11 @@ In that it is different than other facilities (like sockets) and provides anothe
|
||||
Pipes are typically used for interprocess communication. The main reason is, that pipes can be directly assigned to the process stdio, i.e. stderr, stdin and stdout.
|
||||
Additionally, half of the pipe can be inherited to the child process and closed in the father process. This will cause the pipe to be broken when the child process exits.
|
||||
|
||||
Though please note, that if the the same thread reads and write to a pipe, it will only talk to itself.
|
||||
Though please note, that if the same thread reads and writes to a pipe, it will only talk to itself.
|
||||
|
||||
[section:anonymous Anonymous Pipes]
|
||||
|
||||
The most common pipes are anonymous. Since the have no name,
|
||||
The most common pipes are anonymous. Since they have no name,
|
||||
a handle to them can only be obtained from duplicating either handle.
|
||||
|
||||
In this library the following functions are used for the creation of unnamed pipes:
|
||||
@@ -57,12 +57,12 @@ Every process is identified by a unique number[footnote it is unique as long as
|
||||
|
||||
[section:exit_code Exit code]
|
||||
A process will return an integer value indicating whether it was successful. On posix
|
||||
there are more codes associated with that, but not so on windows. Therefore there is not such encoding currently in the library.
|
||||
there are more codes associated with that, but not so on windows. Therefore there is no such encoding currently in the library.
|
||||
However an exit code of zero means the process was successful, while one different than zero indicates an error.
|
||||
[endsect]
|
||||
|
||||
[section:termination Termination]
|
||||
Processes can also be forced to exit. There are two ways to do this, signal the process to so and wait, and just terminate the process without conditions.
|
||||
Processes can also be forced to exit. There are two ways to do this, signal the process to do so and wait, and just terminate the process without conditions.
|
||||
|
||||
Usually the first approach is to signal an exit request, but windows - unlike posix - does not provide a consistent way to do this. Hence this is not part of the
|
||||
library and only the hard terminate is.
|
||||
@@ -79,4 +79,4 @@ The environment is a map of variables local to every process. The most significa
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
[endsect]
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
[section:design Design Rationale]
|
||||
[section Scope]
|
||||
This library is meant to give an wrapper around the different OS-specific methods
|
||||
This library is meant to give a wrapper around the different OS-specific methods
|
||||
to launch processes. Its aim is to provide all functionality that is available on
|
||||
those systems and allow the user to do all related things, which require using the OS APIs.
|
||||
|
||||
[*This library does not try to provide a full library for everything process related]
|
||||
[*This library does not try to provide a full library for everything process related.]
|
||||
In many discussions the proposal was made to build boost.process into a DSEL [footnote Domain Specific Embedded Language] of some sort.
|
||||
This is not the goal, it rather provides the facilities to build such a DSEL-Library on top of it.
|
||||
This is not the goal, it rather provides the facilities to build such a DSEL-library on top of it.
|
||||
Therefore the library also does [*not] force any particular use (such as only asynchronous communication) on its user.
|
||||
It rather could be integrated with such a library.
|
||||
|
||||
@@ -33,7 +33,7 @@ Both styles can also be mixed in some cases.
|
||||
system("gcc", "-c", args+={"main.cpp"});
|
||||
```
|
||||
|
||||
In the following section the avaible styles will be described. Note that the
|
||||
In the following section the available styles will be described. Note that the
|
||||
overload style is implemented via type traits, so the types will be listed.
|
||||
|
||||
[caution There is no guarantee in which order the arguments will be applied!
|
||||
@@ -54,7 +54,7 @@ interpret each string as an argument.
|
||||
]
|
||||
|
||||
When using the overloading variant, a single string will result in a cmd interpretation,
|
||||
several strings will yield a exe-args interpretation. Both version can be set explicitly:
|
||||
several strings will yield a exe-args interpretation. Both versions can be set explicitly:
|
||||
|
||||
```
|
||||
system("grep -c false /etc/passwd"); //cmd style
|
||||
@@ -65,7 +65,7 @@ system(exe="grep", args={"-c", "false", "/etc/passwd"}); //exe-/args-
|
||||
```
|
||||
|
||||
[note If a '"' sign is used in the argument style, it will be passed as part of the argument.
|
||||
If the same effect it wanted with the cmd syntax, it ought to be escaped, i.e. '\\\"'. ]
|
||||
If the same effect is wanted with the cmd syntax, it ought to be escaped, i.e. '\\\"'. ]
|
||||
[note The `PATH` variable will automatically be searched in the command style,
|
||||
but the one of the launching process, not the one passed to the child process.]
|
||||
[endsect]
|
||||
|
||||
@@ -15,14 +15,14 @@ To extend the library, the header [headerref boost/process/extend.hpp extend] is
|
||||
|
||||
It only provides the explicit style for custom properties, but no implicit style.
|
||||
|
||||
What this means is, that a custom initializer can be implemented, a reference to which can be passed to one of the launching functions.
|
||||
If a class inherits [classref boost::process::extend::handler] it will be regarded as a initializer and thus directly put into the sequence
|
||||
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::extend::handler] it will be regarded as an initializer and thus directly put into the sequence
|
||||
the executor gets passed.
|
||||
|
||||
[section:structure Structure]
|
||||
|
||||
The executor calls different handlers of the initializers during the process launch.
|
||||
The basic structure is consists of three functions, as given below:
|
||||
The basic structure consists of three functions, as given below:
|
||||
|
||||
* [globalref boost::process::extend::on_setup on_setup]
|
||||
* [globalref boost::process::extend::on_error on_error]
|
||||
@@ -53,7 +53,7 @@ namespace ex = bp::extend;
|
||||
__child__ c("foo", __on_success__=[](auto & exec) {std::cout << "hello world" << std::endl;});
|
||||
```
|
||||
|
||||
Considering that lambda 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::extend::windows_executor windows_executor]
|
||||
and [classref boost::process::extend::posix_executor posix_executor].
|
||||
@@ -86,7 +86,7 @@ __child__ c("foo", hello_world());
|
||||
|
||||
[note The implementation is done via overloading, not overriding.]
|
||||
|
||||
Every handler not implemented dafaults to [classref boost::process::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]
|
||||
|
||||
@@ -100,7 +100,7 @@ this functionality is also available for extensions. If the class needs the __io
|
||||
```
|
||||
struct async_foo : __handler__, __require_io_context__
|
||||
{
|
||||
tempalte<typename Executor>
|
||||
template<typename Executor>
|
||||
void on_setup(Executor & exec)
|
||||
{
|
||||
__io_context__ & ios = __get_io_context__(exec.seq); //gives us a reference and a compiler error if not present.
|
||||
@@ -139,10 +139,10 @@ struct async_bar : __handler, __async_handler__
|
||||
|
||||
[section:error Error handling]
|
||||
|
||||
If an error occurs in the initializers it shall be told to the executor and not handles directly. This is because
|
||||
the behaviour can be changed through arguments passed to the launching function. Hence the the executor
|
||||
If an error occurs in the initializers it shall be told to the executor and not handled directly. This is because
|
||||
the behaviour can be changed through arguments passed to the launching function. Hence the executor
|
||||
has the function `set_error`, which takes an [@http://en.cppreference.com/w/cpp/error/error_code std::error_code] and a string.
|
||||
Depending on the cofiguration of the executor, this may either throw, set an internal `error_code`, or do nothing.
|
||||
Depending on the configuration of the executor, this may either throw, set an internal `error_code`, or do nothing.
|
||||
|
||||
So let's take a simple example, where we set a randomly chosen `error_code`.
|
||||
|
||||
@@ -202,8 +202,8 @@ struct hello_exe : __handler__
|
||||
};
|
||||
```
|
||||
|
||||
So given our example, the definitions with the non-native exectur are still a template so that they will not be evaluated if not used. Hence this provides a
|
||||
way to implement systems-specific code without using the preprocessor.
|
||||
So given our example, the definitions with the non-native executor are still a template so that they will not be evaluated if not used. Hence this provides a
|
||||
way to implement system-specific code without using the preprocessor.
|
||||
|
||||
[note If you only write a partial implementation, e.g. only for __posix_executor__, the other variants will default to __handler__].
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ while (is >> file)
|
||||
This will also deadlock, because the pipe does not close when the subprocess exits.
|
||||
So the `ipstream` will still look for data even though the process has ended.
|
||||
|
||||
[note It is not possible to use automatically pipe-closing in this library, because
|
||||
[note It is not possible to use automatic pipe-closing in this library, because
|
||||
a pipe might be a file-handle (as for async pipes on windows).]
|
||||
|
||||
But, since pipes are buffered, you might get incomplete data if you do this:
|
||||
@@ -64,7 +64,7 @@ while (c.running())
|
||||
}
|
||||
```
|
||||
|
||||
It is therefore highly recommended that you use the asynchronous api if you are
|
||||
It is therefore highly recommended that you use the asynchronous API if you are
|
||||
not absolutely sure how the output will look.
|
||||
|
||||
[endsect]
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
[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::basic_environment bp::environment]]
|
||||
[def bp::native_environment [classref boost::process::basic_native_environment bp::native_environment]]
|
||||
[def boost::this_process::environment [funcref boost::this_process::environment boost::this_process:deadlock :environment]]
|
||||
[def boost::this_process::environment [funcref boost::this_process::environment boost::this_process::environment]]
|
||||
[def std::chrono::seconds [@http://en.cppreference.com/w/cpp/chrono/duration std::chrono::seconds]]
|
||||
[def std::vector [@http://en.cppreference.com/w/cpp/container/vector std::vector]]
|
||||
|
||||
@@ -68,12 +68,12 @@ namespace bp = boost::process; //we will assume this for all further examples
|
||||
int result = bp::system("g++ main.cpp");
|
||||
```
|
||||
|
||||
If a single string (or the explicit form bp::cmd), it will be interpreted as a command line.
|
||||
If a single string is given (or the explicit form bp::cmd), it will be interpreted as a command line.
|
||||
That will cause the execution function to search the `PATH` variable to find the executable.
|
||||
The alternative is the `exe-args` style, where the first string will be interpreted as a filename (including the path),
|
||||
and the rest as arguments passed to said function.
|
||||
|
||||
[note For more details on the `cmd`/`exe-args` style look [link boost_process.design.arg_cmd_style here]]
|
||||
[note For more details on the `cmd`/`exe-args` style look [link boost_process.design.arg_cmd_style here].]
|
||||
|
||||
So as a first step, we'll use the `exe-args` style.
|
||||
|
||||
@@ -141,7 +141,7 @@ things while the process is running and afterwards get the exit code. The call
|
||||
to child_wait is necessary, to obtain it and tell the operating system, that no
|
||||
one is waiting for the process anymore.
|
||||
|
||||
[note You can also wait for a time span or a until a time point with __wait_for__ and __wait_until__]
|
||||
[note You can also wait for a time span or until a time point with __wait_for__ and __wait_until__.]
|
||||
|
||||
[warning If you don't call wait on a child object, it will be terminated on destruction.
|
||||
This can be avoided by calling __detach__ beforehand]
|
||||
@@ -217,7 +217,7 @@ std::vector<std::string> read_outline(std::string & file)
|
||||
What this does is redirect the `stdout` of the process into a pipe and we read this
|
||||
synchronously.
|
||||
|
||||
[note You can do the same thing with [globalref boost::process::std_err std_err]]
|
||||
[note You can do the same thing with [globalref boost::process::std_err std_err].]
|
||||
|
||||
Now we get the name from `nm` and we might want to demangle it, so we use input and output.
|
||||
`nm` has a demangle option, but for the sake of the example, we'll use
|
||||
@@ -246,7 +246,7 @@ std::vector<std::string> read_demangled_outline(const std::string & file)
|
||||
|
||||
std::vector<std::string> outline;
|
||||
|
||||
//we just use the same pipe, so the
|
||||
//we just use the same pipe, so the output of nm is directly passed as input to c++filt
|
||||
bp::child nm(bp::search_path("nm"), file, bp::std_out > p);
|
||||
bp::child filt(bp::search_path("c++filt"), bp::std_in < p, bp::std_out > is);
|
||||
|
||||
@@ -270,7 +270,7 @@ If you are familiar with [@http://www.boost.org/doc/libs/release/libs/asio/ boos
|
||||
you can use [classref boost::process::async_pipe async_pipe] which is implemented
|
||||
as an I/O-Object and can be used like [classref boost::process::pipe pipe] as shown above.
|
||||
|
||||
Now we get back to our compiling example. `nm` we might analyze it 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.
|
||||
|
||||
With [@http://www.boost.org/doc/libs/release/libs/asio/ boost.asio] this is what it looks like.
|
||||
@@ -290,7 +290,7 @@ ios.run();
|
||||
int result = c.exit_code();
|
||||
```
|
||||
|
||||
To make it easier, boost.process provides simpler interface for that, so that the buffer can be passed directly,
|
||||
To make it easier, boost.process provides a simpler interface for that, so that the buffer can be passed directly,
|
||||
provided we also pass a reference to an io_service.
|
||||
|
||||
```
|
||||
@@ -304,7 +304,7 @@ int result = c.exit_code();
|
||||
```
|
||||
|
||||
[note Passing an instance of io_service to the launching function automatically cause it to wait asynchronously for the exit, so no call of
|
||||
[memberref boost::process::child::wait wait] is needed]
|
||||
[memberref boost::process::child::wait wait] is needed.]
|
||||
|
||||
To make it even easier, you can use [@http://en.cppreference.com/w/cpp/thread/future std::future] for asynchronous operations
|
||||
(you will still need to pass a reference to a io_service) to the launching function, unless you use bp::system or bp::async_system.
|
||||
@@ -331,7 +331,7 @@ auto err = data.get();
|
||||
[endsect]
|
||||
[section:group Groups]
|
||||
|
||||
When launching several processes, processes can be grouped together.
|
||||
When launching several processes, they can be grouped together.
|
||||
This will also apply for a child process, that launches other processes,
|
||||
if they do not modify the group membership. E.g. if you call `make` which
|
||||
launches other processes and call terminate on it,
|
||||
@@ -342,7 +342,7 @@ The two main reasons to use groups are:
|
||||
# Being able to terminate child processes of the child process
|
||||
# Grouping several processes into one, just so they can be terminated at once
|
||||
|
||||
If we have program like `make`, which does launch its own child processes,
|
||||
If we have a program like `make`, which does launch its own child processes,
|
||||
a call of child_terminate might not suffice. I.e. if we have a makefile launching `gcc`
|
||||
and use the following code, the `gcc` process will still run afterwards:
|
||||
|
||||
@@ -412,14 +412,14 @@ bp::system("stuff", env_);
|
||||
```
|
||||
|
||||
A more convenient way to modify the environment for the child is the
|
||||
[globalref boost::process::env env] property, which 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"});
|
||||
|
||||
```
|
||||
|
||||
Please see to the [headerref boost/process/environment.hpp reference] for more information.
|
||||
Please see the [headerref boost/process/environment.hpp reference] for more information.
|
||||
|
||||
[endsect]
|
||||
[endsect]
|
||||
|
||||
@@ -10,6 +10,9 @@
|
||||
//[intro
|
||||
#include <boost/process.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
using namespace boost::process;
|
||||
|
||||
int main()
|
||||
|
||||
@@ -138,7 +138,7 @@ struct args_
|
||||
|
||||
arg_setter_<char, true> operator()(std::initializer_list<const char*> &&range) const
|
||||
{
|
||||
return arg_setter_<char>(range.begin(), range.end());
|
||||
return arg_setter_<char, true>(range.begin(), range.end());
|
||||
}
|
||||
arg_setter_<char, true> operator+=(std::initializer_list<const char*> &&range) const
|
||||
{
|
||||
@@ -146,11 +146,11 @@ struct args_
|
||||
}
|
||||
arg_setter_<char, false> operator= (std::initializer_list<const char*> &&range) const
|
||||
{
|
||||
return arg_setter_<char, true>(range.begin(), range.end());
|
||||
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>(range.begin(), range.end());
|
||||
return arg_setter_<char, true>(range.begin(), range.end());
|
||||
}
|
||||
arg_setter_<char, true> operator+=(std::initializer_list<std::string> &&range) const
|
||||
{
|
||||
@@ -158,12 +158,12 @@ struct args_
|
||||
}
|
||||
arg_setter_<char, false> operator= (std::initializer_list<std::string> &&range) const
|
||||
{
|
||||
return arg_setter_<char, true>(range.begin(), range.end());
|
||||
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>(range.begin(), range.end());
|
||||
return arg_setter_<wchar_t, true>(range.begin(), range.end());
|
||||
}
|
||||
arg_setter_<wchar_t, true> operator+=(std::initializer_list<const wchar_t*> &&range) const
|
||||
{
|
||||
@@ -171,11 +171,11 @@ struct args_
|
||||
}
|
||||
arg_setter_<wchar_t, false> operator= (std::initializer_list<const wchar_t*> &&range) const
|
||||
{
|
||||
return arg_setter_<wchar_t, true>(range.begin(), range.end());
|
||||
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>(range.begin(), range.end());
|
||||
return arg_setter_<wchar_t, true>(range.begin(), range.end());
|
||||
}
|
||||
arg_setter_<wchar_t, true> operator+=(std::initializer_list<std::wstring> &&range) const
|
||||
{
|
||||
@@ -183,7 +183,7 @@ struct args_
|
||||
}
|
||||
arg_setter_<wchar_t, false> operator= (std::initializer_list<std::wstring> &&range) const
|
||||
{
|
||||
return arg_setter_<wchar_t, true>(range.begin(), range.end());
|
||||
return arg_setter_<wchar_t, false>(range.begin(), range.end());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -109,10 +109,10 @@ with `function` being a callable object with the signature `(int, const std::err
|
||||
\code{.cpp}
|
||||
io_context ios;
|
||||
|
||||
child c("ls", on_exit=[](int exit, const std::error_code& ec_in){});
|
||||
child c("ls", ios, on_exit=[](int exit, const std::error_code& ec_in){});
|
||||
|
||||
std::future<int> exit_code;
|
||||
chlid c2("ls", on_exit=exit_code);
|
||||
chlid c2("ls", ios, on_exit=exit_code);
|
||||
|
||||
\endcode
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace boost { namespace process { namespace detail {
|
||||
|
||||
struct cmd_
|
||||
{
|
||||
constexpr cmd_() {}
|
||||
constexpr cmd_() = default;
|
||||
|
||||
template<typename Char>
|
||||
inline api::cmd_setter_<Char> operator()(const Char *s) const
|
||||
|
||||
@@ -73,7 +73,7 @@ public:
|
||||
|
||||
template<typename ...Args>
|
||||
explicit child(Args&&...args);
|
||||
child() {}
|
||||
child() { } // Must be kept non defaulted for MSVC 14.1 & 14.2 #113
|
||||
child& operator=(const child&) = delete;
|
||||
child& operator=(child && lhs)
|
||||
{
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#define BOOST_PROCESS_DETAIL_POSIX_ASIO_FWD_HPP_
|
||||
|
||||
#include <memory>
|
||||
#include <boost/asio/ts/netfwd.hpp>
|
||||
|
||||
namespace boost { namespace asio {
|
||||
|
||||
@@ -20,39 +21,19 @@ template<typename Allocator>
|
||||
class basic_streambuf;
|
||||
|
||||
typedef basic_streambuf<std::allocator<char>> streambuf;
|
||||
class io_context;
|
||||
|
||||
class executor;
|
||||
|
||||
|
||||
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
|
||||
class signal_set_service;
|
||||
template <typename SignalSetService>
|
||||
|
||||
class basic_signal_set;
|
||||
typedef basic_signal_set<signal_set_service> signal_set;
|
||||
#else /* defined(BOOST_ASIO_ENABLE_OLD_SERVICES) */
|
||||
template <typename Executor>
|
||||
class basic_signal_set;
|
||||
typedef basic_signal_set<executor> signal_set;
|
||||
#endif /* defined(BOOST_ASIO_ENABLE_OLD_SERVICES) */
|
||||
typedef basic_signal_set<any_io_executor> signal_set;
|
||||
|
||||
template <typename Handler>
|
||||
class basic_yield_context;
|
||||
|
||||
namespace posix {
|
||||
|
||||
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
|
||||
class stream_descriptor_service;
|
||||
|
||||
template <typename StreamDesscriptorService>
|
||||
class basic_stream_descriptor;
|
||||
typedef basic_stream_descriptor<stream_descriptor_service> stream_descriptor;
|
||||
#else /* defined(BOOST_ASIO_ENABLE_OLD_SERVICES) */
|
||||
template <typename Executor>
|
||||
class basic_stream_descriptor;
|
||||
typedef basic_stream_descriptor<executor> stream_descriptor;
|
||||
#endif /* defined(BOOST_ASIO_ENABLE_OLD_SERVICES) */
|
||||
typedef basic_stream_descriptor<any_io_executor> stream_descriptor;
|
||||
|
||||
} //posix
|
||||
} //asio
|
||||
|
||||
@@ -71,10 +71,8 @@ public:
|
||||
|
||||
~async_pipe()
|
||||
{
|
||||
if (_sink .native_handle() != -1)
|
||||
::close(_sink.native_handle());
|
||||
if (_source.native_handle() != -1)
|
||||
::close(_source.native_handle());
|
||||
boost::system::error_code ec;
|
||||
close(ec);
|
||||
}
|
||||
|
||||
template<class CharT, class Traits = std::char_traits<CharT>>
|
||||
|
||||
@@ -22,7 +22,7 @@ struct close_out : handler_base_ext
|
||||
template <class Executor>
|
||||
inline void on_exec_setup(Executor &e) const;
|
||||
|
||||
std::array<int, 2> get_used_handles() {return {p1 != -1 ? p1 : p2, p2 != -1 ? p2 : p1};}
|
||||
std::array<int, 2> get_used_handles() {return {{p1 != -1 ? p1 : p2, p2 != -1 ? p2 : p1}};}
|
||||
};
|
||||
|
||||
template<>
|
||||
|
||||
@@ -230,7 +230,7 @@ template<typename Char>
|
||||
inline auto basic_environment_impl<Char>::get(const string_type &id) -> string_type
|
||||
{
|
||||
auto itr = std::find_if(_data.begin(), _data.end(),
|
||||
[&](const string_type & st)
|
||||
[&](const string_type & st) -> bool
|
||||
{
|
||||
if (st.size() <= id.size())
|
||||
return false;
|
||||
@@ -250,7 +250,7 @@ template<typename Char>
|
||||
inline void basic_environment_impl<Char>::set(const string_type &id, const string_type &value)
|
||||
{
|
||||
auto itr = std::find_if(_data.begin(), _data.end(),
|
||||
[&](const string_type & st)
|
||||
[&](const string_type & st) -> bool
|
||||
{
|
||||
if (st.size() <= id.size())
|
||||
return false;
|
||||
@@ -270,7 +270,7 @@ template<typename Char>
|
||||
inline void basic_environment_impl<Char>::reset(const string_type &id)
|
||||
{
|
||||
auto itr = std::find_if(_data.begin(), _data.end(),
|
||||
[&](const string_type & st)
|
||||
[&](const string_type & st) -> bool
|
||||
{
|
||||
if (st.size() <= id.size())
|
||||
return false;
|
||||
|
||||
@@ -274,10 +274,10 @@ class executor
|
||||
if ((prepare_cmd_style_fn.find('/') == std::string::npos) && ::access(prepare_cmd_style_fn.c_str(), X_OK))
|
||||
{
|
||||
auto e = ::environ;
|
||||
while ((*e != nullptr) && !boost::starts_with(*e, "PATH="))
|
||||
while ((e != nullptr) && (*e != nullptr) && !boost::starts_with(*e, "PATH="))
|
||||
e++;
|
||||
|
||||
if (e != nullptr)
|
||||
if ((e != nullptr) && (*e != nullptr))
|
||||
{
|
||||
std::vector<std::string> path;
|
||||
boost::split(path, *e, boost::is_any_of(":"));
|
||||
|
||||
@@ -26,7 +26,7 @@ struct file_in : handler_base_ext, ::boost::process::detail::uses_handles
|
||||
|
||||
std::array<int, 2> get_used_handles()
|
||||
{
|
||||
return {STDIN_FILENO, handle};
|
||||
return {{STDIN_FILENO, handle}};
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
||||
@@ -25,7 +25,7 @@ struct null_in : handler_base_ext, ::boost::process::detail::uses_handles
|
||||
|
||||
std::array<int, 2> get_used_handles()
|
||||
{
|
||||
return {STDIN_FILENO, source.handle()};
|
||||
return {{STDIN_FILENO, source.handle()}};
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ struct pipe_in : handler_base_ext, ::boost::process::detail::uses_handles
|
||||
|
||||
std::array<int, 3> get_used_handles()
|
||||
{
|
||||
return {STDIN_FILENO, source, sink};
|
||||
return {{STDIN_FILENO, source, sink}};
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace boost { namespace process { namespace detail { namespace posix {
|
||||
|
||||
class sigchld_service : public boost::asio::detail::service_base<sigchld_service>
|
||||
{
|
||||
boost::asio::io_context::strand _strand{get_io_context()};
|
||||
boost::asio::strand<boost::asio::io_context::executor_type> _strand{get_io_context().get_executor()};
|
||||
boost::asio::signal_set _signal_set{get_io_context(), SIGCHLD};
|
||||
|
||||
std::vector<std::pair<::pid_t, std::function<void(int, std::error_code)>>> _receivers;
|
||||
|
||||
@@ -21,7 +21,7 @@ struct start_dir_init : handler_base_ext
|
||||
{
|
||||
typedef Char value_type;
|
||||
typedef std::basic_string<value_type> string_type;
|
||||
start_dir_init(const string_type &s) : s_(s) {}
|
||||
start_dir_init(string_type s) : s_(std::move(s)) {}
|
||||
|
||||
template <class PosixExecutor>
|
||||
void on_exec_setup(PosixExecutor&) const
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#define BOOST_PROCESS_DETAIL_WINDOWS_ASIO_FWD_HPP_
|
||||
|
||||
#include <memory>
|
||||
#include <boost/asio/ts/netfwd.hpp>
|
||||
|
||||
namespace boost { namespace asio {
|
||||
|
||||
@@ -19,43 +20,19 @@ template<typename Allocator>
|
||||
class basic_streambuf;
|
||||
|
||||
typedef basic_streambuf<std::allocator<char>> streambuf;
|
||||
class io_context;
|
||||
|
||||
class executor;
|
||||
|
||||
|
||||
template <typename Handler>
|
||||
class basic_yield_context;
|
||||
|
||||
namespace windows {
|
||||
|
||||
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
|
||||
class stream_handle_service;
|
||||
|
||||
template <typename StreamHandleService>
|
||||
class basic_stream_handle;
|
||||
|
||||
typedef basic_stream_handle<stream_handle_service> stream_handle;
|
||||
#else /* defined(BOOST_ASIO_ENABLE_OLD_SERVICES) */
|
||||
template <typename Executor>
|
||||
class basic_stream_handle;
|
||||
typedef basic_stream_handle<executor> stream_handle;
|
||||
typedef basic_stream_handle<any_io_executor> stream_handle;
|
||||
|
||||
#endif /* defined(BOOST_ASIO_ENABLE_OLD_SERVICES) */
|
||||
|
||||
|
||||
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
|
||||
class object_handle_service;
|
||||
|
||||
template <typename ObjectHandleService>
|
||||
class basic_object_handle;
|
||||
|
||||
typedef basic_object_handle<object_handle_service> object_handle;
|
||||
#else /* defined(BOOST_ASIO_ENABLE_OLD_SERVICES) */
|
||||
template <typename Executor>
|
||||
class basic_object_handle;
|
||||
typedef basic_object_handle<executor> object_handle;
|
||||
#endif /* defined(BOOST_ASIO_ENABLE_OLD_SERVICES) */
|
||||
typedef basic_object_handle<any_io_executor> object_handle;
|
||||
|
||||
} //windows
|
||||
} //asio
|
||||
|
||||
@@ -30,14 +30,17 @@ inline std::string build_args(const std::string & exe, std::vector<std::string>
|
||||
{
|
||||
std::string st = exe;
|
||||
|
||||
//put in quotes if it has spaces
|
||||
//put in quotes if it has spaces or double quotes
|
||||
if(!exe.empty())
|
||||
{
|
||||
boost::replace_all(st, "\"", "\\\"");
|
||||
auto it = st.find_first_of(" \"");
|
||||
|
||||
auto it = std::find(st.begin(), st.end(), ' ');
|
||||
|
||||
if (it != st.end())//contains spaces.
|
||||
if(it != st.npos)//contains spaces.
|
||||
{
|
||||
// double existing quotes
|
||||
boost::replace_all(st, "\"", "\"\"");
|
||||
|
||||
// surround with quotes
|
||||
st.insert(st.begin(), '"');
|
||||
st += '"';
|
||||
}
|
||||
@@ -45,15 +48,18 @@ inline std::string build_args(const std::string & exe, std::vector<std::string>
|
||||
|
||||
for (auto & arg : data)
|
||||
{
|
||||
boost::replace_all(arg, "\"", "\\\"");
|
||||
|
||||
auto it = std::find(arg.begin(), arg.end(), ' ');//contains space?
|
||||
if (it != arg.end())//ok, contains spaces.
|
||||
if(!arg.empty())
|
||||
{
|
||||
//the first one is put directly onto the output,
|
||||
//because then I don't have to copy the whole string
|
||||
arg.insert(arg.begin(), '"');
|
||||
arg += '"'; //thats the post one.
|
||||
auto it = arg.find_first_of(" \"");//contains space or double quotes?
|
||||
if(it != arg.npos)//yes
|
||||
{
|
||||
// double existing quotes
|
||||
boost::replace_all(arg, "\"", "\"\"");
|
||||
|
||||
// surround with quotes
|
||||
arg.insert(arg.begin(), '"');
|
||||
arg += '"';
|
||||
}
|
||||
}
|
||||
|
||||
if (!st.empty())//first one does not need a preceeding space
|
||||
@@ -68,30 +74,36 @@ inline std::wstring build_args(const std::wstring & exe, std::vector<std::wstrin
|
||||
{
|
||||
std::wstring st = exe;
|
||||
|
||||
//put in quotes if it has spaces
|
||||
//put in quotes if it has spaces or double quotes
|
||||
if(!exe.empty())
|
||||
{
|
||||
boost::replace_all(st, L"\"", L"\\\"");
|
||||
auto it = st.find_first_of(L" \"");
|
||||
|
||||
auto it = std::find(st.begin(), st.end(), L' ');
|
||||
|
||||
if (it != st.end())//contains spaces.
|
||||
if(it != st.npos)//contains spaces or double quotes.
|
||||
{
|
||||
// double existing quotes
|
||||
boost::replace_all(st, L"\"", L"\"\"");
|
||||
|
||||
// surround with quotes
|
||||
st.insert(st.begin(), L'"');
|
||||
st += L'"';
|
||||
}
|
||||
}
|
||||
|
||||
for (auto & arg : data)
|
||||
for(auto & arg : data)
|
||||
{
|
||||
boost::replace_all(arg, L"\"", L"\\\"");
|
||||
|
||||
auto it = std::find(arg.begin(), arg.end(), L' ');//contains space?
|
||||
if (it != arg.end())//ok, contains spaces.
|
||||
if(!arg.empty())
|
||||
{
|
||||
//the first one is put directly onto the output,
|
||||
//because then I don't have to copy the whole string
|
||||
arg.insert(arg.begin(), L'"');
|
||||
arg += L'"'; //thats the post one.
|
||||
auto it = arg.find_first_of(L" \"");//contains space or double quotes?
|
||||
if(it != arg.npos)//yes
|
||||
{
|
||||
// double existing quotes
|
||||
boost::replace_all(arg, L"\"", L"\"\"");
|
||||
|
||||
// surround with quotes
|
||||
arg.insert(arg.begin(), L'"');
|
||||
arg += '"';
|
||||
}
|
||||
}
|
||||
|
||||
if (!st.empty())//first one does not need a preceeding space
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
namespace boost { namespace process { namespace detail { namespace windows {
|
||||
|
||||
typedef int pid_t;
|
||||
typedef ::boost::winapi::DWORD_ pid_t;
|
||||
|
||||
struct child_handle
|
||||
{
|
||||
@@ -66,7 +66,7 @@ struct child_handle
|
||||
|
||||
pid_t id() const
|
||||
{
|
||||
return static_cast<int>(proc_info.dwProcessId);
|
||||
return static_cast<pid_t>(proc_info.dwProcessId);
|
||||
}
|
||||
|
||||
typedef ::boost::winapi::HANDLE_ process_handle_t;
|
||||
|
||||
@@ -677,11 +677,11 @@ inline std::vector<boost::filesystem::path> path()
|
||||
#if defined(BOOST_WINDOWS_API)
|
||||
const ::boost::process::wnative_environment ne{};
|
||||
typedef typename ::boost::process::wnative_environment::const_entry_type value_type;
|
||||
const auto id = L"PATH";
|
||||
static constexpr auto id = L"PATH";
|
||||
#else
|
||||
const ::boost::process::native_environment ne{};
|
||||
typedef typename ::boost::process::native_environment::const_entry_type value_type;
|
||||
const auto id = "PATH";
|
||||
static constexpr auto id = "PATH";
|
||||
#endif
|
||||
|
||||
auto itr = std::find_if(ne.cbegin(), ne.cend(),
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace detail {
|
||||
|
||||
struct throw_on_error_ : ::boost::process::detail::api::handler_base_ext
|
||||
{
|
||||
constexpr throw_on_error_() {};
|
||||
constexpr throw_on_error_() = default;
|
||||
|
||||
template <class Executor>
|
||||
void on_error(Executor&, const std::error_code & ec) const
|
||||
@@ -72,7 +72,7 @@ struct throw_on_error_ : ::boost::process::detail::api::handler_base_ext
|
||||
|
||||
struct ignore_error_ : ::boost::process::detail::api::handler_base_ext
|
||||
{
|
||||
constexpr ignore_error_() {};
|
||||
constexpr ignore_error_() = default;
|
||||
};
|
||||
|
||||
struct set_on_error : ::boost::process::detail::api::handler_base_ext
|
||||
@@ -81,7 +81,7 @@ struct set_on_error : ::boost::process::detail::api::handler_base_ext
|
||||
explicit set_on_error(std::error_code &ec) : ec_(ec) {}
|
||||
|
||||
template <class Executor>
|
||||
void on_error(Executor&, const std::error_code & ec) const
|
||||
void on_error(Executor&, const std::error_code & ec) const noexcept
|
||||
{
|
||||
ec_ = ec;
|
||||
}
|
||||
@@ -92,7 +92,7 @@ private:
|
||||
|
||||
struct error_
|
||||
{
|
||||
constexpr error_() {}
|
||||
constexpr error_() = default;
|
||||
set_on_error operator()(std::error_code &ec) const {return set_on_error(ec);}
|
||||
set_on_error operator= (std::error_code &ec) const {return set_on_error(ec);}
|
||||
|
||||
|
||||
@@ -136,13 +136,13 @@ template<typename T> using is_mutable_buffer =
|
||||
>;
|
||||
|
||||
|
||||
struct null_t {constexpr null_t() {}};
|
||||
struct null_t {constexpr null_t() = default;};
|
||||
struct close_t;
|
||||
|
||||
template<class>
|
||||
struct std_in_
|
||||
{
|
||||
constexpr std_in_() {}
|
||||
constexpr std_in_() = default;
|
||||
|
||||
api::close_in close() const {return api::close_in(); }
|
||||
api::close_in operator=(const close_t &) const {return api::close_in();}
|
||||
@@ -199,7 +199,7 @@ struct std_in_
|
||||
template<int p1, int p2 = -1>
|
||||
struct std_out_
|
||||
{
|
||||
constexpr std_out_() {}
|
||||
constexpr std_out_() = default;
|
||||
|
||||
api::close_out<p1,p2> close() const {return api::close_out<p1,p2>(); }
|
||||
api::close_out<p1,p2> operator=(const close_t &) const {return api::close_out<p1,p2>();}
|
||||
@@ -260,7 +260,7 @@ struct std_out_
|
||||
|
||||
struct close_t
|
||||
{
|
||||
constexpr close_t() {}
|
||||
constexpr close_t() = default;
|
||||
template<int T, int U>
|
||||
api::close_out<T,U> operator()(std_out_<T,U>) {return api::close_out<T,U>();}
|
||||
};
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace detail
|
||||
class codecvt_category_t : public std::error_category
|
||||
{
|
||||
public:
|
||||
codecvt_category_t(){}
|
||||
codecvt_category_t() = default;
|
||||
const char* name() const noexcept override {return "codecvt";}
|
||||
std::string message(int ev) const override
|
||||
{
|
||||
|
||||
@@ -123,8 +123,8 @@ struct basic_pipebuf : std::basic_streambuf<CharT, Traits>
|
||||
///Destructor -> writes the frest of the data
|
||||
~basic_pipebuf()
|
||||
{
|
||||
if (is_open())
|
||||
overflow(Traits::eof());
|
||||
if (basic_pipebuf::is_open())
|
||||
basic_pipebuf::overflow(Traits::eof());
|
||||
}
|
||||
|
||||
///Move construct from a pipe.
|
||||
@@ -167,10 +167,12 @@ struct basic_pipebuf : std::basic_streambuf<CharT, Traits>
|
||||
if (this->pptr() == this->epptr())
|
||||
{
|
||||
bool wr = this->_write_impl();
|
||||
*this->pptr() = ch;
|
||||
this->pbump(1);
|
||||
if (wr)
|
||||
{
|
||||
*this->pptr() = ch;
|
||||
this->pbump(1);
|
||||
return ch;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -293,7 +293,7 @@ BOOST_AUTO_TEST_CASE(async_out_stream, *boost::unit_test::timeout(5))
|
||||
|
||||
std::string line;
|
||||
std::getline(istr, line);
|
||||
BOOST_REQUIRE_GE(line.size(), 3);
|
||||
BOOST_REQUIRE_GE(line.size(), 3u);
|
||||
BOOST_CHECK(boost::algorithm::starts_with(line, "abc"));
|
||||
c.wait();
|
||||
}
|
||||
@@ -413,4 +413,4 @@ BOOST_AUTO_TEST_CASE(mixed_async, *boost::unit_test::timeout(5))
|
||||
|
||||
}*/
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END();
|
||||
BOOST_AUTO_TEST_SUITE_END();
|
||||
|
||||
@@ -57,8 +57,7 @@ BOOST_AUTO_TEST_CASE(future_error, *boost::unit_test::timeout(15))
|
||||
|
||||
ios.run();
|
||||
|
||||
int exit_code = 0;
|
||||
BOOST_CHECK_THROW(exit_code = fut.get(), boost::system::system_error);
|
||||
BOOST_CHECK_THROW(fut.get(), boost::system::system_error);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END();
|
||||
BOOST_AUTO_TEST_SUITE_END();
|
||||
|
||||
@@ -41,9 +41,9 @@ BOOST_AUTO_TEST_CASE(stackful, *boost::unit_test::timeout(15))
|
||||
bp::async_system(
|
||||
ios, yield_,
|
||||
master_test_suite().argv[1],
|
||||
"test", "--exit-code", "123");
|
||||
"test", "--wait", "1");
|
||||
|
||||
BOOST_CHECK_EQUAL(ret, 123);
|
||||
BOOST_CHECK_EQUAL(ret, 0);
|
||||
BOOST_CHECK(did_something_else);
|
||||
};
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ BOOST_AUTO_TEST_CASE(stackless, *boost::unit_test::timeout(15))
|
||||
master_test_suite().argv[1],
|
||||
"test", "--exit-code", "42");
|
||||
|
||||
BOOST_CHECK_EQUAL(exit_code, 42);
|
||||
BOOST_CHECK_EQUAL(exit_code, 42u);
|
||||
BOOST_CHECK(did_something_else);
|
||||
}
|
||||
}
|
||||
@@ -68,4 +68,4 @@ BOOST_AUTO_TEST_CASE(stackless, *boost::unit_test::timeout(15))
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END();
|
||||
BOOST_AUTO_TEST_SUITE_END();
|
||||
|
||||
@@ -29,7 +29,6 @@ struct run_exe
|
||||
{
|
||||
e.exe = exe.c_str();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
struct set_on_error
|
||||
@@ -74,13 +73,11 @@ struct overload_handler : ex::handler
|
||||
void on_setup(ex::windows_executor<Char, Sequence>& exec) const
|
||||
{
|
||||
st = "windows";
|
||||
const char* env = exec.env;
|
||||
}
|
||||
template <class Sequence>
|
||||
void on_setup(ex::posix_executor<Sequence>& exec) const
|
||||
{
|
||||
st = "posix";
|
||||
char** env = exec.env;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ BOOST_AUTO_TEST_CASE(leak_test, *boost::unit_test::timeout(5))
|
||||
BOOST_CHECK(bt::is_stream_handle(get_handle(stderr), ec)); BOOST_CHECK_MESSAGE(!ec, ec.message());
|
||||
|
||||
|
||||
BOOST_CHECK_GE(fd_list.size(), 3);
|
||||
BOOST_CHECK_GE(fd_list.size(), 3u);
|
||||
BOOST_CHECK_GE(bt::get_handles(ec).size(), fd_list.size());
|
||||
|
||||
bp::pipe p;
|
||||
@@ -66,14 +66,14 @@ BOOST_AUTO_TEST_CASE(leak_test, *boost::unit_test::timeout(5))
|
||||
|
||||
auto fd_list_new = bt::get_handles(ec);
|
||||
BOOST_CHECK_MESSAGE(!ec, ec);
|
||||
BOOST_CHECK_LE(fd_list.size() + 2, fd_list_new.size());
|
||||
BOOST_CHECK_LE(fd_list.size() + 2u, fd_list_new.size());
|
||||
fd_list = std::move(fd_list_new);
|
||||
}
|
||||
|
||||
|
||||
|
||||
BOOST_CHECK_EQUAL(std::count(fd_list.begin(), fd_list.end(), p.native_source()), 1);
|
||||
BOOST_CHECK_EQUAL(std::count(fd_list.begin(), fd_list.end(), p.native_sink()), 1);
|
||||
BOOST_CHECK_EQUAL(std::count(fd_list.begin(), fd_list.end(), p.native_source()), 1u);
|
||||
BOOST_CHECK_EQUAL(std::count(fd_list.begin(), fd_list.end(), p.native_sink()), 1u);
|
||||
|
||||
BOOST_CHECK(bt::is_stream_handle(p.native_source(), ec)); BOOST_CHECK_MESSAGE(!ec, ec.message());
|
||||
BOOST_CHECK(bt::is_stream_handle(p.native_sink(), ec)); BOOST_CHECK_MESSAGE(!ec, ec.message());
|
||||
@@ -82,8 +82,8 @@ BOOST_AUTO_TEST_CASE(leak_test, *boost::unit_test::timeout(5))
|
||||
p.close();
|
||||
fd_list = bt::get_handles(ec);
|
||||
|
||||
BOOST_CHECK_EQUAL(std::count(fd_list.begin(), fd_list.end(), p.native_source()), 0);
|
||||
BOOST_CHECK_EQUAL(std::count(fd_list.begin(), fd_list.end(), p.native_sink()), 0);
|
||||
BOOST_CHECK_EQUAL(std::count(fd_list.begin(), fd_list.end(), p.native_source()), 0u);
|
||||
BOOST_CHECK_EQUAL(std::count(fd_list.begin(), fd_list.end(), p.native_sink()), 0u);
|
||||
|
||||
#if defined( BOOST_WINDOWS_API )
|
||||
std::thread thr([]{});
|
||||
@@ -128,7 +128,6 @@ struct on_setup_t
|
||||
bp::extend::foreach_used_handle(e, [this](bt::native_handle_type handle)
|
||||
{
|
||||
res.push_back(handle);
|
||||
std::cout << "Pushing " << handle << std::endl;
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -155,9 +154,9 @@ BOOST_AUTO_TEST_CASE(iterate_handles, *boost::unit_test::timeout(5))
|
||||
|
||||
BOOST_CHECK_MESSAGE(!ec, ec.message());
|
||||
|
||||
BOOST_CHECK_EQUAL(ret, 42);
|
||||
BOOST_CHECK_EQUAL(std::count(res.begin(), res.end(), p_in. native_sink()), 0);
|
||||
BOOST_CHECK_EQUAL(std::count(res.begin(), res.end(), p_out.native_source()), 0);
|
||||
BOOST_CHECK_EQUAL(ret, 42u);
|
||||
BOOST_CHECK_EQUAL(std::count(res.begin(), res.end(), p_in. native_sink()), 0u);
|
||||
BOOST_CHECK_EQUAL(std::count(res.begin(), res.end(), p_out.native_source()), 0u);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(limit_fd, *boost::unit_test::timeout(5))
|
||||
@@ -169,11 +168,13 @@ BOOST_AUTO_TEST_CASE(limit_fd, *boost::unit_test::timeout(5))
|
||||
#endif
|
||||
|
||||
using boost::unit_test::framework::master_test_suite;
|
||||
BOOST_CHECK_EQUAL(bp::system(master_test_suite().argv[1], "--has-handle", get_handle(stdout), bp::std_err > stderr), EXIT_SUCCESS);
|
||||
|
||||
BOOST_CHECK_EQUAL(bp::system(master_test_suite().argv[1], "--has-handle", get_handle(stdin), bp::std_err > stderr), EXIT_SUCCESS);
|
||||
BOOST_CHECK_EQUAL(bp::system(master_test_suite().argv[1], "--has-handle", get_handle(stderr), bp::std_err > stderr), EXIT_SUCCESS);
|
||||
|
||||
|
||||
BOOST_CHECK_EQUAL(bp::system(master_test_suite().argv[1], "--has-handle", get_handle(stdout), bp::std_err > stderr, bp::limit_handles), EXIT_FAILURE);
|
||||
BOOST_CHECK_EQUAL(bp::system(master_test_suite().argv[1], "--has-handle", get_handle(stdin), bp::std_err > stderr, bp::limit_handles), EXIT_FAILURE);
|
||||
BOOST_CHECK_EQUAL(bp::system(master_test_suite().argv[1], "--has-handle", get_handle(stderr), bp::std_err > stderr, bp::limit_handles), EXIT_SUCCESS);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ BOOST_AUTO_TEST_CASE(wargs, *boost::unit_test::timeout(2))
|
||||
std::error_code ec;
|
||||
bp::child c(
|
||||
master_test_suite().argv[1],
|
||||
L"test", "--echo-argv", L"hello thingy", "\"stuff\"", static_cast<const wchar_t*>(L" spa ce "),
|
||||
L"test", "--echo-argv", L"hello thingy", "\"stuff\"", static_cast<const wchar_t*>(L" spa\" ce "),
|
||||
bp::std_out>is,
|
||||
ec
|
||||
);
|
||||
@@ -62,9 +62,9 @@ BOOST_AUTO_TEST_CASE(wargs, *boost::unit_test::timeout(2))
|
||||
BOOST_CHECK_EQUAL(s, "\"stuff\"");
|
||||
|
||||
std::getline(is, s);
|
||||
s.resize(10);
|
||||
s.resize(11);
|
||||
|
||||
BOOST_CHECK_EQUAL(s, " spa ce ");
|
||||
BOOST_CHECK_EQUAL(s, " spa\" ce ");
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user