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.
* 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>
1. When more than 2 streams are piped, we use threads to read/write data
parallely. In this scenariod read_atmost_n API was being used instead of
read_all.
2. Another issue with check_output argument validation fixed.