|
@@ -0,0 +1,289 @@
|
|
|
|
+diff --git a/.clang-tidy b/.clang-tidy
|
|
|
|
+index 35bb58f..de92997 100644
|
|
|
|
+--- a/.clang-tidy
|
|
|
|
++++ b/.clang-tidy
|
|
|
|
+@@ -34,6 +34,7 @@ Checks:
|
|
|
|
+ -performance-no-int-to-ptr,
|
|
|
|
+ -readability-else-after-return,
|
|
|
|
+ -readability-function-cognitive-complexity,
|
|
|
|
++-readability-identifier-length,
|
|
|
|
+ -readability-magic-numbers,
|
|
|
|
+ '
|
|
|
|
+ HeaderFilterRegex: '.*reproc\+\+.*$'
|
|
|
|
+diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
|
|
|
|
+index 4000454..3858f59 100644
|
|
|
|
+--- a/.github/workflows/main.yml
|
|
|
|
++++ b/.github/workflows/main.yml
|
|
|
|
+@@ -74,7 +74,7 @@ jobs:
|
|
|
|
+ - name: Install (Windows)
|
|
|
|
+ if: runner.os == 'Windows'
|
|
|
|
+ run: |
|
|
|
|
+- Invoke-Expression (New-Object System.Net.WebClient).DownloadString('https://get.scoop.sh')
|
|
|
|
++ iex "& {$(irm get.scoop.sh)} -RunAsAdmin"
|
|
|
|
+ scoop install ninja llvm --global
|
|
|
|
+
|
|
|
|
+ if ("${{ matrix.compiler }}" -eq "gcc") {
|
|
|
|
+diff --git a/README.md b/README.md
|
|
|
|
+index 62cc299..e7e940d 100644
|
|
|
|
+--- a/README.md
|
|
|
|
++++ b/README.md
|
|
|
|
+@@ -225,6 +225,16 @@ occurred. You can test against these error codes using values from the
|
|
|
|
+
|
|
|
|
+ See the examples for more information on how to handle errors when using reproc.
|
|
|
|
+
|
|
|
|
++Note:
|
|
|
|
++
|
|
|
|
++Both reproc and reproc++ APIs take `options` argument that may define one or more
|
|
|
|
++`stop` actions such as `terminate` or `kill`.
|
|
|
|
++For that reason if the child process is being terminated or killed using a signal
|
|
|
|
++on POSIX, the error code will **not** reflect an error.
|
|
|
|
++
|
|
|
|
++It's up to the downstream project to *interpret* status codes reflecting unexpected
|
|
|
|
++behaviors alongside error codes (see this [example](https://github.com/DaanDeMeyer/reproc/issues/68#issuecomment-959074504)).
|
|
|
|
++
|
|
|
|
+ ## Multithreading
|
|
|
|
+
|
|
|
|
+ Don't call the same operation on the same child process from more than one
|
|
|
|
+diff --git a/reproc++/include/reproc++/reproc.hpp b/reproc++/include/reproc++/reproc.hpp
|
|
|
|
+index ab6f139..f722245 100644
|
|
|
|
+--- a/reproc++/include/reproc++/reproc.hpp
|
|
|
|
++++ b/reproc++/include/reproc++/reproc.hpp
|
|
|
|
+@@ -88,18 +88,18 @@ struct redirect {
|
|
|
|
+
|
|
|
|
+ struct options {
|
|
|
|
+ struct {
|
|
|
|
+- env::type behavior;
|
|
|
|
++ reproc::env::type behavior;
|
|
|
|
+ /*! Implicitly converts from any STL container of string pairs to the
|
|
|
|
+ environment format expected by `reproc_start`. */
|
|
|
|
+- class env extra;
|
|
|
|
++ reproc::env extra;
|
|
|
|
+ } env = {};
|
|
|
|
+
|
|
|
|
+ const char *working_directory = nullptr;
|
|
|
|
+
|
|
|
|
+ struct {
|
|
|
|
+- redirect in;
|
|
|
|
+- redirect out;
|
|
|
|
+- redirect err;
|
|
|
|
++ struct redirect in;
|
|
|
|
++ struct redirect out;
|
|
|
|
++ struct redirect err;
|
|
|
|
+ bool parent;
|
|
|
|
+ bool discard;
|
|
|
|
+ FILE *file;
|
|
|
|
+@@ -138,30 +138,12 @@ enum class stream {
|
|
|
|
+ err,
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+-class process;
|
|
|
|
+-
|
|
|
|
+ namespace event {
|
|
|
|
+
|
|
|
|
+-enum {
|
|
|
|
+- in = 1 << 0,
|
|
|
|
+- out = 1 << 1,
|
|
|
|
+- err = 1 << 2,
|
|
|
|
+- exit = 1 << 3,
|
|
|
|
+- deadline = 1 << 4,
|
|
|
|
+-};
|
|
|
|
+-
|
|
|
|
+-struct source {
|
|
|
|
+- class process &process;
|
|
|
|
+- int interests;
|
|
|
|
+- int events;
|
|
|
|
+-};
|
|
|
|
++struct source;
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+-REPROCXX_EXPORT std::error_code poll(event::source *sources,
|
|
|
|
+- size_t num_sources,
|
|
|
|
+- milliseconds timeout = infinite);
|
|
|
|
+-
|
|
|
|
+ /*! Improves on reproc's API by adding RAII and changing the API of some
|
|
|
|
+ functions to be more idiomatic C++. */
|
|
|
|
+ class process {
|
|
|
|
+@@ -220,4 +202,26 @@ private:
|
|
|
|
+ std::unique_ptr<reproc_t, reproc_t *(*) (reproc_t *)> impl_;
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
++namespace event {
|
|
|
|
++
|
|
|
|
++enum {
|
|
|
|
++ in = 1 << 0,
|
|
|
|
++ out = 1 << 1,
|
|
|
|
++ err = 1 << 2,
|
|
|
|
++ exit = 1 << 3,
|
|
|
|
++ deadline = 1 << 4,
|
|
|
|
++};
|
|
|
|
++
|
|
|
|
++struct source {
|
|
|
|
++ class process process;
|
|
|
|
++ int interests;
|
|
|
|
++ int events;
|
|
|
|
++};
|
|
|
|
++
|
|
|
|
++}
|
|
|
|
++
|
|
|
|
++REPROCXX_EXPORT std::error_code poll(event::source *sources,
|
|
|
|
++ size_t num_sources,
|
|
|
|
++ milliseconds timeout = infinite);
|
|
|
|
++
|
|
|
|
+ }
|
|
|
|
+diff --git a/reproc++/src/reproc.cpp b/reproc++/src/reproc.cpp
|
|
|
|
+index e4eed1a..534e9fb 100644
|
|
|
|
+--- a/reproc++/src/reproc.cpp
|
|
|
|
++++ b/reproc++/src/reproc.cpp
|
|
|
|
+@@ -86,8 +86,9 @@ std::pair<bool, std::error_code> process::fork(const options &options) noexcept
|
|
|
|
+ std::pair<int, std::error_code> process::poll(int interests,
|
|
|
|
+ milliseconds timeout)
|
|
|
|
+ {
|
|
|
|
+- event::source source{ *this, interests, 0 };
|
|
|
|
++ event::source source{ std::move(*this), interests, 0 };
|
|
|
|
+ std::error_code ec = ::reproc::poll(&source, 1, timeout);
|
|
|
|
++ *this = std::move(source.process);
|
|
|
|
+ return { source.events, ec };
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+diff --git a/reproc/CMakeLists.txt b/reproc/CMakeLists.txt
|
|
|
|
+index 949cc88..1bb4798 100644
|
|
|
|
+--- a/reproc/CMakeLists.txt
|
|
|
|
++++ b/reproc/CMakeLists.txt
|
|
|
|
+@@ -1,6 +1,6 @@
|
|
|
|
+ if(WIN32)
|
|
|
|
+ set(REPROC_WINSOCK_LIBRARY ws2_32)
|
|
|
|
+-elseif(NOT APPLE)
|
|
|
|
++elseif(CMAKE_SYSTEM_NAME MATCHES Linux)
|
|
|
|
+ set(REPROC_RT_LIBRARY rt) # clock_gettime
|
|
|
|
+ endif()
|
|
|
|
+
|
|
|
|
+diff --git a/reproc/src/clock.windows.c b/reproc/src/clock.windows.c
|
|
|
|
+index 3130f85..8c6c85a 100644
|
|
|
|
+--- a/reproc/src/clock.windows.c
|
|
|
|
++++ b/reproc/src/clock.windows.c
|
|
|
|
+@@ -1,4 +1,8 @@
|
|
|
|
+-#define _WIN32_WINNT _WIN32_WINNT_VISTA
|
|
|
|
++#ifndef _WIN32_WINNT
|
|
|
|
++ #define _WIN32_WINNT 0x0600 // _WIN32_WINNT_VISTA
|
|
|
|
++#elif _WIN32_WINNT < 0x0600
|
|
|
|
++ #error "_WIN32_WINNT must be greater than _WIN32_WINNT_VISTA (0x0600)"
|
|
|
|
++#endif
|
|
|
|
+
|
|
|
|
+ #include "clock.h"
|
|
|
|
+
|
|
|
|
+diff --git a/reproc/src/error.windows.c b/reproc/src/error.windows.c
|
|
|
|
+index b8d8234..9459027 100644
|
|
|
|
+--- a/reproc/src/error.windows.c
|
|
|
|
++++ b/reproc/src/error.windows.c
|
|
|
|
+@@ -1,4 +1,8 @@
|
|
|
|
+-#define _WIN32_WINNT _WIN32_WINNT_VISTA
|
|
|
|
++#ifndef _WIN32_WINNT
|
|
|
|
++ #define _WIN32_WINNT 0x0600 // _WIN32_WINNT_VISTA
|
|
|
|
++#elif _WIN32_WINNT < 0x0600
|
|
|
|
++ #error "_WIN32_WINNT must be greater than _WIN32_WINNT_VISTA (0x0600)"
|
|
|
|
++#endif
|
|
|
|
+
|
|
|
|
+ #include "error.h"
|
|
|
|
+
|
|
|
|
+diff --git a/reproc/src/handle.windows.c b/reproc/src/handle.windows.c
|
|
|
|
+index e0cd500..f0fbe56 100644
|
|
|
|
+--- a/reproc/src/handle.windows.c
|
|
|
|
++++ b/reproc/src/handle.windows.c
|
|
|
|
+@@ -1,4 +1,8 @@
|
|
|
|
+-#define _WIN32_WINNT _WIN32_WINNT_VISTA
|
|
|
|
++#ifndef _WIN32_WINNT
|
|
|
|
++ #define _WIN32_WINNT 0x0600 // _WIN32_WINNT_VISTA
|
|
|
|
++#elif _WIN32_WINNT < 0x0600
|
|
|
|
++ #error "_WIN32_WINNT must be greater than _WIN32_WINNT_VISTA (0x0600)"
|
|
|
|
++#endif
|
|
|
|
+
|
|
|
|
+ #include "handle.h"
|
|
|
|
+
|
|
|
|
+diff --git a/reproc/src/init.windows.c b/reproc/src/init.windows.c
|
|
|
|
+index 8357b7c..52519bf 100644
|
|
|
|
+--- a/reproc/src/init.windows.c
|
|
|
|
++++ b/reproc/src/init.windows.c
|
|
|
|
+@@ -1,4 +1,8 @@
|
|
|
|
+-#define _WIN32_WINNT _WIN32_WINNT_VISTA
|
|
|
|
++#ifndef _WIN32_WINNT
|
|
|
|
++ #define _WIN32_WINNT 0x0600 // _WIN32_WINNT_VISTA
|
|
|
|
++#elif _WIN32_WINNT < 0x0600
|
|
|
|
++ #error "_WIN32_WINNT must be greater than _WIN32_WINNT_VISTA (0x0600)"
|
|
|
|
++#endif
|
|
|
|
+
|
|
|
|
+ #include "init.h"
|
|
|
|
+
|
|
|
|
+diff --git a/reproc/src/pipe.windows.c b/reproc/src/pipe.windows.c
|
|
|
|
+index bb355be..befeaf1 100644
|
|
|
|
+--- a/reproc/src/pipe.windows.c
|
|
|
|
++++ b/reproc/src/pipe.windows.c
|
|
|
|
+@@ -1,4 +1,8 @@
|
|
|
|
+-#define _WIN32_WINNT _WIN32_WINNT_VISTA
|
|
|
|
++#ifndef _WIN32_WINNT
|
|
|
|
++ #define _WIN32_WINNT 0x0600 // _WIN32_WINNT_VISTA
|
|
|
|
++#elif _WIN32_WINNT < 0x0600
|
|
|
|
++ #error "_WIN32_WINNT must be greater than _WIN32_WINNT_VISTA (0x0600)"
|
|
|
|
++#endif
|
|
|
|
+
|
|
|
|
+ #include "pipe.h"
|
|
|
|
+
|
|
|
|
+diff --git a/reproc/src/process.posix.c b/reproc/src/process.posix.c
|
|
|
|
+index 0f0fe0d..8dcbfd1 100644
|
|
|
|
+--- a/reproc/src/process.posix.c
|
|
|
|
++++ b/reproc/src/process.posix.c
|
|
|
|
+@@ -17,6 +17,8 @@
|
|
|
|
+ #include "pipe.h"
|
|
|
|
+ #include "strv.h"
|
|
|
|
+
|
|
|
|
++#define CWD_BUF_SIZE_INCREMENT 4096
|
|
|
|
++
|
|
|
|
+ const pid_t PROCESS_INVALID = -1;
|
|
|
|
+
|
|
|
|
+ static int signal_mask(int how, const sigset_t *newmask, sigset_t *oldmask)
|
|
|
|
+@@ -51,7 +53,7 @@ static char *path_prepend_cwd(const char *path)
|
|
|
|
+ ASSERT(path);
|
|
|
|
+
|
|
|
|
+ size_t path_size = strlen(path);
|
|
|
|
+- size_t cwd_size = PATH_MAX;
|
|
|
|
++ size_t cwd_size = CWD_BUF_SIZE_INCREMENT;
|
|
|
|
+
|
|
|
|
+ // We always allocate sufficient space for `path` but do not include this
|
|
|
|
+ // space in `cwd_size` so we can be sure that when `getcwd` succeeds there is
|
|
|
|
+@@ -70,7 +72,7 @@ static char *path_prepend_cwd(const char *path)
|
|
|
|
+ return NULL;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+- cwd_size += PATH_MAX;
|
|
|
|
++ cwd_size += CWD_BUF_SIZE_INCREMENT;
|
|
|
|
+
|
|
|
|
+ char *result = realloc(cwd, cwd_size + path_size + 1);
|
|
|
|
+ if (result == NULL) {
|
|
|
|
+diff --git a/reproc/src/process.windows.c b/reproc/src/process.windows.c
|
|
|
|
+index 666f3cb..6e28589 100644
|
|
|
|
+--- a/reproc/src/process.windows.c
|
|
|
|
++++ b/reproc/src/process.windows.c
|
|
|
|
+@@ -1,4 +1,8 @@
|
|
|
|
+-#define _WIN32_WINNT _WIN32_WINNT_VISTA
|
|
|
|
++#ifndef _WIN32_WINNT
|
|
|
|
++ #define _WIN32_WINNT 0x0600 // _WIN32_WINNT_VISTA
|
|
|
|
++#elif _WIN32_WINNT < 0x0600
|
|
|
|
++ #error "_WIN32_WINNT must be greater than _WIN32_WINNT_VISTA (0x0600)"
|
|
|
|
++#endif
|
|
|
|
+
|
|
|
|
+ #include "process.h"
|
|
|
|
+
|
|
|
|
+diff --git a/reproc/src/redirect.windows.c b/reproc/src/redirect.windows.c
|
|
|
|
+index c634145..151f407 100644
|
|
|
|
+--- a/reproc/src/redirect.windows.c
|
|
|
|
++++ b/reproc/src/redirect.windows.c
|
|
|
|
+@@ -1,4 +1,8 @@
|
|
|
|
+-#define _WIN32_WINNT _WIN32_WINNT_VISTA
|
|
|
|
++#ifndef _WIN32_WINNT
|
|
|
|
++ #define _WIN32_WINNT 0x0600 // _WIN32_WINNT_VISTA
|
|
|
|
++#elif _WIN32_WINNT < 0x0600
|
|
|
|
++ #error "_WIN32_WINNT must be greater than _WIN32_WINNT_VISTA (0x0600)"
|
|
|
|
++#endif
|
|
|
|
+
|
|
|
|
+ #include "redirect.h"
|
|
|
|
+
|