123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223 |
- #pragma once
- #include <chrono>
- #include <cstdint>
- #include <cstdio>
- #include <memory>
- #include <system_error>
- #include <utility>
- #include <reproc++/arguments.hpp>
- #include <reproc++/env.hpp>
- #include <reproc++/export.hpp>
- #include <reproc++/input.hpp>
- // Forward declare `reproc_t` so we don't have to include reproc.h in the
- // header.
- struct reproc_t;
- /*! The `reproc` namespace wraps all reproc++ declarations. `process` wraps
- reproc's API inside a C++ class. To avoid exposing reproc's API when using
- reproc++ all structs, enums and constants of reproc have a replacement in
- reproc++. Only differences in behaviour compared to reproc are documented. Refer
- to reproc.h and the examples for general information on how to use reproc. */
- namespace reproc {
- /*! Conversion from reproc `errno` constants to `std::errc` constants:
- https://en.cppreference.com/w/cpp/error/errc */
- using error = std::errc;
- namespace signal {
- REPROCXX_EXPORT extern const int kill;
- REPROCXX_EXPORT extern const int terminate;
- }
- /*! Timeout values are passed as `reproc::milliseconds` instead of `int` in
- reproc++. */
- using milliseconds = std::chrono::duration<int, std::milli>;
- REPROCXX_EXPORT extern const milliseconds infinite;
- REPROCXX_EXPORT extern const milliseconds deadline;
- enum class stop {
- noop,
- wait,
- terminate,
- kill,
- };
- struct stop_action {
- stop action;
- milliseconds timeout;
- };
- struct stop_actions {
- stop_action first;
- stop_action second;
- stop_action third;
- };
- #if defined(_WIN32)
- using handle = void *;
- #else
- using handle = int;
- #endif
- struct redirect {
- enum type {
- default_, // Unfortunately, both `default` and `auto` are keywords.
- pipe,
- parent,
- discard,
- // stdout would conflict with a macro on Windows.
- stdout_,
- // Unfortunately, class members and nested enum members can't have the same
- // name.
- handle_,
- file_,
- path_,
- };
- enum type type;
- reproc::handle handle;
- FILE *file;
- const char *path;
- };
- struct options {
- struct {
- env::type behavior;
- /*! Implicitly converts from any STL container of string pairs to the
- environment format expected by `reproc_start`. */
- class env extra;
- } env = {};
- const char *working_directory = nullptr;
- struct {
- redirect in;
- redirect out;
- redirect err;
- bool parent;
- bool discard;
- FILE *file;
- const char *path;
- } redirect = {};
- struct stop_actions stop = {};
- reproc::milliseconds timeout = reproc::milliseconds(0);
- reproc::milliseconds deadline = reproc::milliseconds(0);
- /*! Implicitly converts from string literals to the pointer size pair expected
- by `reproc_start`. */
- class input input;
- bool nonblocking = false;
- /*! Make a shallow copy of `options`. */
- static options clone(const options &other)
- {
- struct options clone;
- clone.env.behavior = other.env.behavior;
- // Make sure we make a shallow copy of `environment`.
- clone.env.extra = other.env.extra.data();
- clone.working_directory = other.working_directory;
- clone.redirect = other.redirect;
- clone.stop = other.stop;
- clone.timeout = other.timeout;
- clone.deadline = other.deadline;
- clone.input = other.input;
- return clone;
- }
- };
- enum class stream {
- in,
- out,
- 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;
- };
- }
- 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 {
- public:
- REPROCXX_EXPORT process();
- REPROCXX_EXPORT ~process() noexcept;
- // Enforce unique ownership of child processes.
- REPROCXX_EXPORT process(process &&other) noexcept;
- REPROCXX_EXPORT process &operator=(process &&other) noexcept;
- /*! `reproc_start` but implicitly converts from STL containers to the
- arguments format expected by `reproc_start`. */
- REPROCXX_EXPORT std::error_code start(const arguments &arguments,
- const options &options = {}) noexcept;
- REPROCXX_EXPORT std::pair<int, std::error_code> pid() noexcept;
- /*! Sets the `fork` option in `reproc_options` and calls `start`. Returns
- `true` in the child process and `false` in the parent process. */
- REPROCXX_EXPORT std::pair<bool, std::error_code>
- fork(const options &options = {}) noexcept;
- /*! Shorthand for `reproc::poll` that only polls this process. Returns a pair
- of (events, error). */
- REPROCXX_EXPORT std::pair<int, std::error_code>
- poll(int interests, milliseconds timeout = infinite);
- /*! `reproc_read` but returns a pair of (bytes read, error). */
- REPROCXX_EXPORT std::pair<size_t, std::error_code>
- read(stream stream, uint8_t *buffer, size_t size) noexcept;
- /*! reproc_write` but returns a pair of (bytes_written, error). */
- REPROCXX_EXPORT std::pair<size_t, std::error_code>
- write(const uint8_t *buffer, size_t size) noexcept;
- REPROCXX_EXPORT std::error_code close(stream stream) noexcept;
- /*! `reproc_wait` but returns a pair of (status, error). */
- REPROCXX_EXPORT std::pair<int, std::error_code>
- wait(milliseconds timeout) noexcept;
- REPROCXX_EXPORT std::error_code terminate() noexcept;
- REPROCXX_EXPORT std::error_code kill() noexcept;
- /*! `reproc_stop` but returns a pair of (status, error). */
- REPROCXX_EXPORT std::pair<int, std::error_code>
- stop(stop_actions stop) noexcept;
- private:
- REPROCXX_EXPORT friend std::error_code
- poll(event::source *sources, size_t num_sources, milliseconds timeout);
- std::unique_ptr<reproc_t, reproc_t *(*) (reproc_t *)> impl_;
- };
- }
|