@@ -272,11 +272,11 @@ namespace util
272272
273273 // Create a pipe for the child process's STDIN.
274274 if (!CreatePipe (read_handle, write_handle, &saAttr,0 ))
275- throw OSError (" Stdin CreatePipe" , 0 );
275+ throw OSError (" CreatePipe" , 0 );
276276
277277 // Ensure the write handle to the pipe for STDIN is not inherited.
278- if (!SetHandleInformation (child_handle, HANDLE_FLAG_INHERIT, 0 ))
279- throw OSError (" Stdin SetHandleInformation" , 0 );
278+ if (!SetHandleInformation (* child_handle, HANDLE_FLAG_INHERIT, 0 ))
279+ throw OSError (" SetHandleInformation" , 0 );
280280 }
281281#endif
282282
@@ -1131,6 +1131,26 @@ class Popen
11311131 if (!defer_process_start_) execute_process ();
11321132 }
11331133
1134+ template <typename ... Args>
1135+ Popen (std::vector<std::string> vargs_, Args &&... args) : vargs_(vargs_)
1136+ {
1137+ init_args (std::forward<Args>(args)...);
1138+
1139+ // Setup the communication channels of the Popen class
1140+ stream_.setup_comm_channels ();
1141+
1142+ if (!defer_process_start_) execute_process ();
1143+ }
1144+
1145+ /*
1146+ ~Popen()
1147+ {
1148+ #ifdef _MSC_VER
1149+ CloseHandle(this->process_handle_);
1150+ #endif
1151+ }
1152+ */
1153+
11341154 void start_process () noexcept (false );
11351155
11361156 int pid () const noexcept { return child_pid_; }
@@ -1409,43 +1429,21 @@ inline void Popen::execute_process() noexcept(false)
14091429
14101430 this ->process_handle_ = piProcInfo.hProcess ;
14111431
1412- try {
1413- char err_buf[SP_MAX_ERR_BUF_SIZ] = { 0 ,} ;
1432+ std::async (std::launch::async, [ this ] {
1433+ WaitForSingleObject ( this -> process_handle_ , INFINITE) ;
14141434
1415- int read_bytes = util::read_atmost_n (
1416- this ->error (),
1417- err_buf,
1418- SP_MAX_ERR_BUF_SIZ);
1419- fclose (this ->error ());
1420-
1421- if (read_bytes || strlen (err_buf)) {
1422- // Throw whatever information we have about child failure
1423- throw CalledProcessError (err_buf);
1424- }
1425- } catch (std::exception& exp) {
1426- stream_.cleanup_fds ();
1427- throw ;
1428- }
1435+ CloseHandle (this ->stream_ .g_hChildStd_ERR_Wr );
1436+ CloseHandle (this ->stream_ .g_hChildStd_OUT_Wr );
1437+ CloseHandle (this ->stream_ .g_hChildStd_IN_Rd );
1438+ });
14291439
14301440/*
1431- this->hExited_ =
1432- std::shared_future<int>(std::async(std::launch::async, [this] {
1433- WaitForSingleObject(this->hProcess_, INFINITE);
1434-
1435- CloseHandle(this->stream_.g_hChildStd_ERR_Wr);
1436- CloseHandle(this->stream_.g_hChildStd_OUT_Wr);
1437- CloseHandle(this->stream_.g_hChildStd_IN_Rd);
1438-
1439- DWORD exit_code;
1440- if (FALSE == GetExitCodeProcess(this->hProcess_, &exit_code))
1441- throw OSError("GetExitCodeProcess", 0);
1442-
1443- CloseHandle(this->hProcess_);
1444-
1445- return (int)exit_code;
1446- }));
1441+ NOTE: In the linux version, there is a check to make sure that the process
1442+ has been started. Here, we do nothing because CreateProcess will throw
1443+ if we fail to create the process.
14471444*/
14481445
1446+
14491447#else
14501448
14511449 int err_rd_pipe, err_wr_pipe;
@@ -1683,7 +1681,7 @@ namespace detail {
16831681 inline void Streams::setup_comm_channels ()
16841682 {
16851683#ifdef _MSC_VER
1686- util::configure_pipe (this ->g_hChildStd_IN_Rd , &this ->g_hChildStd_IN_Wr , &this ->g_hChildStd_IN_Wr );
1684+ util::configure_pipe (& this ->g_hChildStd_IN_Rd , &this ->g_hChildStd_IN_Wr , &this ->g_hChildStd_IN_Wr );
16871685 this ->input (util::file_from_handle (this ->g_hChildStd_IN_Wr , " w" ));
16881686 this ->write_to_child_ = _fileno (this ->input ());
16891687
@@ -1935,6 +1933,12 @@ OutBuffer check_output(const std::string& arg, Args&&... args)
19351933 return (detail::check_output_impl (arg, std::forward<Args>(args)...));
19361934}
19371935
1936+ template <typename ... Args>
1937+ OutBuffer check_output (std::vector<std::string> plist, Args &&... args)
1938+ {
1939+ return (detail::check_output_impl (plist, std::forward<Args>(args)...));
1940+ }
1941+
19381942
19391943/* !
19401944 * An easy way to pipeline easy commands.
0 commit comments