{"id":15297007,"url":"https://github.com/daandemeyer/reproc","last_synced_at":"2025-05-16T06:04:46.983Z","repository":{"id":33440706,"uuid":"136356865","full_name":"DaanDeMeyer/reproc","owner":"DaanDeMeyer","description":"A cross-platform (C99/C++11) process library","archived":false,"fork":false,"pushed_at":"2024-04-07T08:27:55.000Z","size":2017,"stargazers_count":580,"open_issues_count":25,"forks_count":70,"subscribers_count":18,"default_branch":"main","last_synced_at":"2025-05-16T06:04:41.706Z","etag":null,"topics":["c","cmake","cpp","cross-platform","library","posix","processes","windows"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DaanDeMeyer.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-06-06T16:32:21.000Z","updated_at":"2025-04-22T03:30:37.000Z","dependencies_parsed_at":"2024-01-14T06:25:27.953Z","dependency_job_id":"6b461f90-6dc7-44e3-9450-4c5adf19b29c","html_url":"https://github.com/DaanDeMeyer/reproc","commit_stats":{"total_commits":1560,"total_committers":14,"mean_commits":"111.42857142857143","dds":"0.010897435897435859","last_synced_commit":"9f399675b821e175f85ac3ee6e3fd2e6056573eb"},"previous_names":[],"tags_count":45,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DaanDeMeyer%2Freproc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DaanDeMeyer%2Freproc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DaanDeMeyer%2Freproc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DaanDeMeyer%2Freproc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DaanDeMeyer","download_url":"https://codeload.github.com/DaanDeMeyer/reproc/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254478186,"owners_count":22077675,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c","cmake","cpp","cross-platform","library","posix","processes","windows"],"created_at":"2024-09-30T19:14:06.167Z","updated_at":"2025-05-16T06:04:46.964Z","avatar_url":"https://github.com/DaanDeMeyer.png","language":"C","readme":"# reproc\n\n- [What is reproc?](#what-is-reproc)\n- [Features](#features)\n- [Questions](#questions)\n- [Installation](#installation)\n- [Dependencies](#dependencies)\n- [CMake options](#cmake-options)\n- [Documentation](#documentation)\n- [Error handling](#error-handling)\n- [Multithreading](#multithreading)\n- [Gotchas](#gotchas)\n\n## What is reproc?\n\nreproc (Redirected Process) is a cross-platform C/C++ library that simplifies\nstarting, stopping and communicating with external programs. The main use case\nis executing command line applications directly from C or C++ code and\nretrieving their output.\n\nreproc consists out of two libraries: reproc and reproc++. reproc is a C99\nlibrary that contains the actual code for working with external programs.\nreproc++ depends on reproc and adapts its API to an idiomatic C++11 API. It also\nadds a few extras that simplify working with external programs from C++.\n\n## Features\n\n- Start any program directly from C or C++ code.\n- Communicate with a program via its standard streams.\n- Wait for a program to exit or forcefully stop it yourself. When forcefully\n  stopping a process you can either allow the process to clean up its resources\n  or stop it immediately.\n- The core library (reproc) is written in C99. An optional C++11 wrapper library\n  (reproc++) with extra features is available for use in C++ applications.\n- Multiple installation methods. Either build reproc as part of your project or\n  use a system installed version of reproc.\n\n## Usage\n\n```c\n#include \u003creproc/run.h\u003e\n\nint main(void)\n{\n  const char *args[] = { \"echo\", \"Hello, world!\", NULL };\n  return reproc_run(args, (reproc_options) { 0 });\n}\n```\n\n## Questions\n\nIf you have any questions after reading the readme and documentation you can\neither make an issue or ask questions directly in the reproc\n[gitter](https://gitter.im/reproc/Lobby) channel.\n\n## Installation\n\n**Note: Building reproc requires CMake 3.12 or higher.**\n\nThere are multiple ways to get reproc into your project. One way is to build\nreproc as part of your project using CMake. To do this, we first have to get the\nreproc source code into the project. This can be done using any of the following\noptions:\n\n- When using CMake 3.11 or later, you can use the CMake `FetchContent` API to\n  download reproc when running CMake. See\n  \u003chttps://cliutils.gitlab.io/modern-cmake/chapters/projects/fetch.html\u003e for an\n  example.\n- Another option is to include reproc's repository as a git submodule.\n  \u003chttps://cliutils.gitlab.io/modern-cmake/chapters/projects/submodule.html\u003e\n  provides more information.\n- A very simple solution is to just include reproc's source code in your\n  repository. You can download a zip of the source code without the git history\n  and add it to your repository in a separate directory.\n\nAfter including reproc's source code in your project, it can be built from the\nroot CMakeLists.txt file as follows:\n\n```cmake\nadd_subdirectory(\u003cpath-to-reproc\u003e) # For example: add_subdirectory(external/reproc)\n```\n\nCMake options can be specified before calling `add_subdirectory`:\n\n```cmake\nset(REPROC++ ON)\nadd_subdirectory(\u003cpath-to-reproc\u003e)\n```\n\n**Note: If the option has already been cached in a previous CMake run, you'll\nhave to clear CMake's cache to apply the new default value.**\n\nFor more information on configuring reproc's build, see\n[CMake options](#cmake-options).\n\nYou can also depend on an installed version of reproc. You can either build and\ninstall reproc yourself or install reproc via a package manager. reproc is\navailable in the following package repositories:\n\n- Arch User Repository (\u003chttps://aur.archlinux.org/packages/reproc\u003e)\n- vcpkg (https://github.com/microsoft/vcpkg/tree/master/ports/reproc)\n\nIf using a package manager is not an option, you can build and install reproc\nfrom source (CMake 3.13+):\n\n```sh\ncmake -B build\ncmake --build build\ncmake --install build\n```\n\nEnable the `REPROC_TEST` option and build the `test` target to run the tests\n(CMake 3.13+):\n\n```sh\ncmake -B build -DREPROC_TEST=ON\ncmake --build build\ncmake --build build --target test\n```\n\nAfter installing reproc your build system will have to find it. reproc provides\nboth CMake config files and pkg-config files to simplify finding a reproc\ninstallation using CMake and pkg-config respectively. Note that reproc and\nreproc++ are separate libraries and as a result have separate config files as\nwell. Make sure to search for the one you want to use.\n\nTo find an installed version of reproc using CMake:\n\n```cmake\nfind_package(reproc) # Find reproc.\nfind_package(reproc++) # Find reproc++.\n```\n\nAfter building reproc as part of your project or finding a installed version of\nreproc, you can link against it from within your CMakeLists.txt file as follows:\n\n```cmake\ntarget_link_libraries(myapp reproc) # Link against reproc.\ntarget_link_libraries(myapp reproc++) # Link against reproc++.\n```\n\nFrom Meson 0.53.2 onwards, reproc can be included as a CMake subproject in Meson\nbuild scripts. See https://mesonbuild.com/CMake-module.html for more\ninformation.\n\n## Dependencies\n\nBy default, reproc has a dependency on pthreads on POSIX systems (`-pthread`)\nand a dependency on Winsock 2.2 on Windows systems (`-lws2_32`). CMake and\npkg-config handle these dependencies automatically.\n\n## CMake options\n\nreproc's build can be configured using the following CMake options:\n\n### User\n\n- `REPROC++`: Build reproc++ (default: `${REPROC_DEVELOP}`)\n- `REPROC_TEST`: Build tests (default: `${REPROC_DEVELOP}`)\n\n  Run the tests by running the `test` binary which can be found in the build\n  directory after building reproc.\n\n- `REPROC_EXAMPLES`: Build examples (default: `${REPROC_DEVELOP}`)\n\n  The resulting binaries will be located in the examples folder of each project\n  subdirectory in the build directory after building reproc.\n\n### Advanced\n\n- `REPROC_OBJECT_LIBRARIES`: Build CMake object libraries (default:\n  `${REPROC_DEVELOP}`)\n\n  This is useful to directly include reproc in another library. When building\n  reproc as a static or shared library, it has to be installed alongside the\n  consuming library which makes distributing the consuming library harder. When\n  using object libraries, reproc's object files are included directly into the\n  consuming library and no extra installation is necessary.\n\n  **Note: reproc's object libraries will only link correctly from CMake 3.14\n  onwards.**\n\n  **Note: This option overrides `BUILD_SHARED_LIBS`.**\n\n- `REPROC_INSTALL`: Generate installation rules (default: `ON` unless\n  `REPROC_OBJECT_LIBRARIES` is enabled)\n- `REPROC_INSTALL_CMAKECONFIGDIR`: CMake config files installation directory\n  (default: `${CMAKE_INSTALL_LIBDIR}/cmake`)\n- `REPROC_INSTALL_PKGCONFIG`: Install pkg-config files (default: `ON`)\n- `REPROC_INSTALL_PKGCONFIGDIR`: pkg-config files installation directory\n  (default: `${CMAKE_INSTALL_LIBDIR}/pkgconfig`)\n\n- `REPROC_MULTITHREADED`: Use `pthread_sigmask` and link against the system's\n  thread library (default: `ON`)\n\n### Developer\n\n- `REPROC_DEVELOP`: Configure option default values for development (default:\n  `OFF` unless the `REPROC_DEVELOP` environment variable is set)\n- `REPROC_SANITIZERS`: Build with sanitizers (default: `${REPROC_DEVELOP}`)\n- `REPROC_TIDY`: Run clang-tidy when building (default: `${REPROC_DEVELOP}`)\n- `REPROC_WARNINGS`: Enable compiler warnings (default: `${REPROC_DEVELOP}`)\n- `REPROC_WARNINGS_AS_ERRORS`: Add -Werror or equivalent to the compile flags\n  and clang-tidy (default: `OFF`)\n\n## Documentation\n\nEach function and class is documented extensively in its header file. Examples\ncan be found in the examples subdirectory of [reproc](reproc/examples) and\n[reproc++](reproc++/examples).\n\n## Error handling\n\nOn failure, Most functions in reproc's API return a negative `errno` (POSIX) or\n`GetLastError` (Windows) style error code. For actionable errors, reproc\nprovides constants (`REPROC_ETIMEDOUT`, `REPROC_EPIPE`, ...) that can be used to\nmatch against the error without having to write platform-specific code. To get a\nstring representation of an error, pass it to `reproc_strerror`.\n\nreproc++'s API integrates with the C++ standard library error codes mechanism\n(`std::error_code` and `std::error_condition`). Most methods in reproc++'s API\nreturn `std::error_code` values that contain the actual system error that\noccurred. You can test against these error codes using values from the\n`std::errc` enum.\n\nSee the examples for more information on how to handle errors when using reproc.\n\nNote:\n\nBoth reproc and reproc++ APIs take `options` argument that may define one or more\n`stop` actions such as `terminate` or `kill`.\nFor that reason if the child process is being terminated or killed using a signal\non POSIX, the error code will **not** reflect an error.\n\nIt's up to the downstream project to *interpret* status codes reflecting unexpected\nbehaviors alongside error codes (see this [example](https://github.com/DaanDeMeyer/reproc/issues/68#issuecomment-959074504)).\n\n## Multithreading\n\nDon't call the same operation on the same child process from more than one\nthread at the same time. For example: reading and writing to a child process\nfrom different threads is fine but waiting on the same child process from two\ndifferent threads at the same time will result in issues.\n\n## Gotchas\n\n- (POSIX) It is strongly recommended to not call `waitpid` on pids of processes\n  started by reproc.\n\n  reproc uses `waitpid` to wait until a process has exited. Unfortunately,\n  `waitpid` cannot be called twice on the same process. This means that\n  `reproc_wait` won't work correctly if `waitpid` has already been called on a\n  child process beforehand outside of reproc.\n\n- It is strongly recommended to make sure each child process actually exits\n  using `reproc_wait` or `reproc_stop`.\n\n  On POSIX, a child process that has exited is a zombie process until the parent\n  process waits on it using `waitpid`. A zombie process takes up resources and\n  can be seen as a resource leak so it is important to make sure all processes\n  exit correctly in a timely fashion.\n\n- It is strongly recommended to try terminating a child process by waiting for\n  it to exit or by calling `reproc_terminate` before resorting to `reproc_kill`.\n\n  When using `reproc_kill` the child process does not receive a chance to\n  perform cleanup which could result in resources being leaked. Chief among\n  these leaks is that the child process will not be able to stop its own child\n  processes. Always try to let a child process exit normally by calling\n  `reproc_terminate` before calling `reproc_kill`. `reproc_stop` is a handy\n  helper function that can be used to perform multiple stop actions in a row\n  with timeouts inbetween.\n\n- (POSIX) It is strongly recommended to ignore the `SIGPIPE` signal in the\n  parent process.\n\n  On POSIX, writing to a closed stdin pipe of a child process will terminate the\n  parent process with the `SIGPIPE` signal by default. To avoid this, the\n  `SIGPIPE` signal has to be ignored in the parent process. If the `SIGPIPE`\n  signal is ignored `reproc_write` will return `REPROC_EPIPE` as expected when\n  writing to a closed stdin pipe.\n\n- While `reproc_terminate` allows the child process to perform cleanup it is up\n  to the child process to correctly clean up after itself. reproc only sends a\n  termination signal to the child process. The child process itself is\n  responsible for cleaning up its own child processes and other resources.\n\n- (Windows) `reproc_kill` is not guaranteed to kill a child process immediately\n  on Windows. For more information, read the Remarks section in the\n  documentation of the Windows `TerminateProcess` function that reproc uses to\n  kill child processes on Windows.\n\n- Child processes spawned via reproc inherit a single extra file handle which is\n  used to wait for the child process to exit. If the child process closes this\n  file handle manually, reproc will wrongly detect the child process has exited.\n  If this handle is further inherited by other processes that outlive the child\n  process, reproc will detect the child process is still running even if it has\n  exited. If data is written to this handle, reproc will also wrongly detect the\n  child process has exited.\n\n- (Windows) It's not possible to detect if a child process closes its stdout or\n  stderr stream before exiting. The parent process will only be notified that a\n  child process output stream is closed once that child process exits.\n\n- (Windows) reproc assumes that Windows creates sockets that are usable as file\n  system objects. More specifically, the default sockets returned by `WSASocket`\n  should have the `XP1_IFS_HANDLES ` flag set. This might not be the case if\n  there are external LSP providers installed on a Windows machine. If this is\n  the case, we recommend removing the software that's providing the extra\n  service providers since they're deprecated and should not be used anymore (see\n  https://docs.microsoft.com/en-us/windows/win32/winsock/categorizing-layered-service-providers-and-applications).\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdaandemeyer%2Freproc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdaandemeyer%2Freproc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdaandemeyer%2Freproc/lists"}