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 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 process::fork(const options &options) noexcept std::pair 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"