diff options
Diffstat (limited to 'libbutl/process.cxx')
-rw-r--r-- | libbutl/process.cxx | 107 |
1 files changed, 57 insertions, 50 deletions
diff --git a/libbutl/process.cxx b/libbutl/process.cxx index f6433fb..e416807 100644 --- a/libbutl/process.cxx +++ b/libbutl/process.cxx @@ -1,9 +1,7 @@ // file : libbutl/process.cxx -*- C++ -*- // license : MIT; see accompanying LICENSE file -#ifndef __cpp_modules_ts -#include <libbutl/process.mxx> -#endif +#include <libbutl/process.hxx> #include <errno.h> @@ -49,6 +47,14 @@ # elif defined(__NetBSD__) && __NetBSD__ >= 6 # define LIBBUTL_POSIX_SPAWN // +// On OpenBSD posix_spawn() appeared in 5.2 (see the man page for details). +// +# elif defined(__OpenBSD__) +# include <sys/param.h> // OpenBSD (yyyymm) +# if OpenBSD >= 201211 // 5.2 released on 1 Nov 2012. +# define LIBBUTL_POSIX_SPAWN +# endif +// // posix_spawn() appeared in Version 3 of the Single UNIX Specification that // was implemented in MacOS 10.5 (see the man page for details). // @@ -87,29 +93,20 @@ # endif // _MSC_VER #endif -#include <cassert> - -#ifndef __cpp_lib_modules_ts -#include <string> -#include <vector> -#include <chrono> -#include <cstdint> -#include <cstddef> -#include <system_error> - #include <ios> // ios_base::failure +#include <memory> // unique_ptr #include <cstring> // strlen(), strchr(), strpbrk(), strncmp() #include <utility> // move() #include <ostream> +#include <cassert> #ifndef _WIN32 -#include <thread> // this_thread::sleep_for() +# include <thread> // this_thread::sleep_for() #else -#include <map> -#include <ratio> // milli -#include <cstdlib> // __argv[] -#include <algorithm> // find() -#endif +# include <map> +# include <ratio> // milli +# include <cstdlib> // __argv[] +# include <algorithm> // find() #endif #include <libbutl/process-details.hxx> @@ -119,32 +116,8 @@ namespace butl shared_mutex process_spawn_mutex; // Out of module purview. } -#ifdef __cpp_modules_ts -module butl.process; - -// Only imports additional to interface. -#ifdef __clang__ -#ifdef __cpp_lib_modules_ts -import std.core; -import std.io; -import std.threading; // Clang wants it in purview (see process-details.hxx). -#endif -import butl.path; -import butl.fdstream; -import butl.vector_view; -import butl.small_vector; -#endif - -#ifndef _WIN32 -import std.threading; -#endif - -import butl.utility; // icasecmp() -import butl.fdstream; // fdopen_null() -#else -#include <libbutl/utility.mxx> -#include <libbutl/fdstream.mxx> -#endif +#include <libbutl/utility.hxx> // icasecmp() +#include <libbutl/fdstream.hxx> // fdopen_null() using namespace std; @@ -217,7 +190,7 @@ namespace butl } void process:: - print (ostream& o, const char* const args[], size_t n) + print (ostream& o, const char* const* args, size_t n) { size_t m (0); const char* const* p (args); @@ -410,7 +383,7 @@ namespace butl } process:: - process (const process_path& pp, const char* args[], + process (const process_path& pp, const char* const* args, pipe pin, pipe pout, pipe perr, const char* cwd, const char* const* evars) @@ -670,6 +643,10 @@ namespace butl { // Child. // + // NOTE: make sure not to call anything that may acquire a mutex that + // could be already acquired in another thread, most notably + // malloc(). @@ What about exceptions (all the fail() calls)? + // Duplicate the user-supplied (fd > -1) or the created pipe descriptor // to the standard stream descriptor (read end for STDIN_FILENO, write // end otherwise). Close the pipe afterwards. @@ -729,6 +706,9 @@ namespace butl try { + // @@ TODO: redo without allocation (PATH_MAX?) Maybe + // also using C API to avoid exceptions. + // if (e != nullptr) setenv (string (v, e - v), e + 1); else @@ -736,6 +716,8 @@ namespace butl } catch (const system_error& e) { + // @@ Should we assume this cannot throw? + // throw process_child_error (e.code ().value ()); } } @@ -776,6 +758,13 @@ namespace butl { if (handle != 0) { + // First close any open pipe ends for good measure but ignore any + // errors. + // + out_fd.reset (); + in_ofd.reset (); + in_efd.reset (); + int es; int r (waitpid (handle, &es, 0)); handle = 0; // We have tried. @@ -857,6 +846,12 @@ namespace butl return getpid (); } + process::handle_type process:: + current_handle () + { + return getpid (); + } + // process_exit // process_exit:: @@ -1383,7 +1378,7 @@ namespace butl static map<string, bool> detect_msys_cache_; process:: - process (const process_path& pp, const char* args[], + process (const process_path& pp, const char* const* args, pipe pin, pipe pout, pipe perr, const char* cwd, const char* const* evars) @@ -1812,7 +1807,6 @@ namespace butl using namespace chrono; - // Retry for about 1 hour. // system_clock::duration timeout (1h); @@ -1898,7 +1892,7 @@ namespace butl return PeekNamedPipe (h, &c, 1, &n, nullptr, nullptr) && n == 1; }; - // Hidden by butl::duration that is introduced via fdstream.mxx. + // Hidden by butl::duration that is introduced via fdstream.hxx. // using milli_duration = chrono::duration<DWORD, milli>; @@ -1979,6 +1973,10 @@ namespace butl { if (handle != 0) { + out_fd.reset (); + in_ofd.reset (); + in_efd.reset (); + DWORD es; DWORD e (NO_ERROR); if (WaitForSingleObject (handle, INFINITE) != WAIT_OBJECT_0 || @@ -2086,6 +2084,15 @@ namespace butl return GetCurrentProcessId (); } + process::handle_type process:: + current_handle () + { + // Note that the returned handle is a pseudo handle (-1) that does not + // need to be closed. + // + return GetCurrentProcess (); + } + // process_exit // process_exit:: |