This suppresses the following warning caused by clang-20.
```
error: definition of implicit copy constructor for 'Streams' is deprecated because it has a user-declared copy assignment operator [-Werror,-Wdeprecated-copy]
```
Copy constructor or move constructor is called when std::vector re-allocates
memory. In this case, move constructor should be called, because copying
Streams instances breaks file-descriptor management.
Communication class is modified as well, since it's instance is a member of
Streams class.
The commit a32c0f3df4b6bcd1d2e93f19e8f380bb890cd507 introduced code to
silence MSVC's "warning C4996: The POSIX name for this item is
deprecated."
However, it exhibits several issues:
1. The aliases may leak into code outside the `subprocess.hpp` header.
2. They are unnecessarily applied when using the MinGW-w64 toolchain.
3. The fix is incomplete: downstream projects still see C4996 warnings.
4. The implementation lacks documentation.
This change addresses all of the above shortcomings.
Co-authored-by: Luke Dashjr <luke-jr+git@utopios.org>
When passing in a rvalue reference, compiler
considers it ambiguous between std::string and
std::string&&. Making one of them take a lvalue
reference makes compilers correctly pick the right
one depending on whether the passed in value binds
to a rvalue or lvalue reference.
This requires making cwd arg be either narrow or
wide char depending on platform and plumbing the
argument to CreateProcessW. Since `env_char_t` and
`env_str_t` is now being used beyond just env,
I've renamed those types to `platform_char_t` and
`platform_str_t`. `env_char_t` and `env_str_t` are
provided as alias to the new name for backwards
compatibility.
* Fix exception when `CreateProcessW` fails
This change makes the behavior on Windows consistent with the behavior
on Linux.
* test: Add `test_exception`
* Added 'call' overload
* Use CREATE_NO_WINDOW flag for process creation in Win32
* Change way of quoting arguments so explorer /select can be called
(should find a better way to do this)
---------
Co-authored-by: Santiago <san@san.san>
It's useful to be able to know the exit code of the process when it
fails with a non-zero exit code.
To get this to work, I had to fix a bug in the implementation of
check_output. Previously, check_output would call both `p.communicate()`
and `p.poll()`. The former has the effect of waiting for EOF on the
input and then waiting for the child to exit, reaping it with
`waitpid(2)`. Unfortunately, `p.poll()` was hoping to be able to also
use `waitpid(2)` to retrieve the exit code of the process. But since the
child had already been reaped, the given pid no longer existed, and thus
`waitpid(2)` would return `ECHILD`.
Luckily the call to `p.poll()` is unnecessary, as the process already
provides `p.retcode()` for retrieving the exit code.
* Fixed: forked subprocess not exited if execve failed
In lengthy processes (daemons, etc) this bug keeps open this subprocess. The subprocess continues to work (parallel to parent process) from after failed command start
* Fixed: deadlock on using multithreaded application
For example if application uses spdlog logger library and set spdlog::flush_every(std::chrono::seconds(1)); then it starts it's own thread which flushes logs every 1 second. In this case if execve failed to execute given command, then parent and subprocess deadlocked.
C++11 started to deprecate the use of throw function identifiers. In
C++17, this header no longer compiles due to the deprecation.
Signed-off-by: Ben Dang <me@bdang.it>