@@ -35,12 +35,57 @@ Valid initializers for any stdio are:
3535
3636 - `std::nullptr_t` assigning a null-device
3737 - `FILE*` any open file, including `stdin`, `stdout` and `stderr`
38- - a filesystem::path, which will open a readable or writable depending on the direction of the stream
3938 - `native_handle` any native file handle (`HANDLE` on windows) or file descriptor (`int` on posix)
40- - any io-object with a .native_handle() function that is compatible with the above. E.g. a asio::ip::tcp::socket
41- - an asio::basic_writeable_pipe for stdin or asio::basic_readable_pipe for stderr/stdout.
39+ - any io-object with a `.native_handle()` function that is compatible with the above. E.g. a `asio::ip::tcp::socket`, or a pipe object.
40+ - a filesystem::path, which will open a readable or writable depending on the direction of the stream
41+ - an `asio::basic_writeable_pipe` for stdin or `asio::basic_readable_pipe` for stderr/stdout.
42+
43+ When passing a `FILE*`, a `native_handle` or an io-object with a `native_handle`,
44+ the initializer will assign the handle as is to the child process.
45+ That is the file descriptor/handle gets cloned into the subprocess and used without modification.
46+
47+ When passing a filesystem::path, the initializer will attempt to open the file and then pass the handle
48+ to the subprocess.
49+
50+ When passing a `readable_pipe` to stdout/stderr or a `writable_pipe` to stdin by reference,
51+ the initializer to create the other side of the pipe (`writable_pipe` for stdout/stderr, `readable_pipe` for `stdin`),
52+ connect the pair and pass the native_handle to the child process.
53+
54+ That is, these two are equivalent:
55+
56+ .Implicit construction of the readable pipe.
57+ [source,cpp]
58+ ----
59+ asio::io_context ctx;
60+ asio::writable_pipe wp{ctx};
61+ // create a readable pipe internally and connect it to wp
62+ process proc{ctx, "/bin/bash", {}, process_stdio{.in=wp}};
4263
64+ // create it explicitly
65+ {
66+ // the pipe the child process reads from
67+ asio::readable_pipe rp{ctx};
68+ asio::connect_pipe(rp, wp);
69+ // `rp.native_handle()` will be assigned to the child processes stdin
70+ process proc{ctx, "/bin/bash", {}, process_stdio{.in=rp}};
71+ rp.close(); // close it so the pipe closes when the `proc exits.
72+ }
73+ ----
4374
75+ The explicit version allows you to assign the same `writable_pipe` to `stdout` and `stderr`:
76+
77+ [source,cpp]
78+ ----
79+ // the pipe the parent process reads from and both
80+ // stderr & stdout of the child process write to
81+ asio::readable_pipe rp{ctx};
82+ asio::writable_pipe wp{ctx};
83+ asio::connect_pipe(rp, wp);
84+ process proc{ctx, "/bin/bash", {}, process_stdio{.out=wp, .err=wp}};
85+ wp.close(); // close it so the pipe closes when the `proc exits.
86+ ----
87+
88+ NOTE: If the child writes to a pipe, the parent reads from it et vice versa.
4489
4590
4691[source,cpp]
@@ -52,4 +97,4 @@ struct process_stdio
5297 __implementation_defined__ out;
5398 __implementation_defined__ err;
5499};
55- ----
100+ ----
0 commit comments