89 lines
2.5 KiB
Plaintext
89 lines
2.5 KiB
Plaintext
[section:stdio stdio]
|
|
|
|
When using io with a subprocess, all three standard streams (stdin, stdout, stderr) get set for the child-process.
|
|
The default setting is to inherit the parent process.
|
|
|
|
This feature meant to be flexible, which is why there is little checking on the arguments assigned to one of those streams.
|
|
|
|
[section:pipe Pipe]
|
|
|
|
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:
|
|
|
|
```
|
|
asio::io_context ctx;
|
|
asio::readable_pipe rp;
|
|
|
|
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();
|
|
```
|
|
|
|
readable pipes can be assigned to `out` an `err`, while writable_pipes can be assigned to `in`.
|
|
|
|
[endsect]
|
|
|
|
[section:file `FILE*`]
|
|
|
|
`FILE*` can also be used for either side; this allows the `stdin`, `stderr`, `stdout` macros to be used:
|
|
|
|
```
|
|
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();
|
|
```
|
|
|
|
[endsect]
|
|
|
|
[section:null `nullptr`]
|
|
|
|
`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.
|
|
|
|
```
|
|
asio::io_context ctx;
|
|
// ignore stderr
|
|
process proc(ctx, "/usr/bin/g++", {"--version"}, process_stdio{{ /* in to default */}, {}, nullptr});
|
|
proc.wait();
|
|
```
|
|
|
|
[endsect]
|
|
|
|
|
|
[section:native_handle `native_handle`]
|
|
|
|
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.
|
|
|
|
|
|
```
|
|
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();
|
|
```
|
|
|
|
[endsect]
|
|
|
|
[section:popen popen]
|
|
|
|
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.
|
|
|
|
```
|
|
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');
|
|
```
|
|
|
|
[endsect]
|
|
|
|
[endsect] |