// Generated by gmmproc 2.82.0 -- DO NOT MODIFY! #ifndef _GIOMM_SUBPROCESS_H #define _GIOMM_SUBPROCESS_H #include #include #include /* Copyright (C) 2023 The gtkmm Development Team * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #include #include #include #include #include #include #include #include // std::pair #ifndef DOXYGEN_SHOULD_SKIP_THIS using GSubprocess = struct _GSubprocess; using GSubprocessClass = struct _GSubprocessClass; #endif /* DOXYGEN_SHOULD_SKIP_THIS */ #ifndef DOXYGEN_SHOULD_SKIP_THIS namespace Gio { class GIOMM_API Subprocess_Class; } // namespace Gio #endif //DOXYGEN_SHOULD_SKIP_THIS namespace Gio { /** Child processes. * * %Gio::Subprocess allows the creation of and interaction with child * processes. * * Processes can be communicated with using standard GIO-style APIs * (Gio::InputStream, Gio::OutputStream). There are GIO-style APIs to wait for * process termination (cancellable and with an asynchronous variant). * * There is an API to force a process to terminate, as well as a * race-free API for sending UNIX signals to a subprocess. * * One major advantage that GIO brings over the core GLib library is * comprehensive API for asynchronous I/O, such as * Gio::OutputStream::splice_async(). This makes %Gio::Subprocess * significantly more powerful and flexible than equivalent APIs in * some other languages such as the `subprocess.py` * included with Python. For example, using %Gio::Subprocess one could * create two child processes, reading standard output from the first, * processing it, and writing to the input stream of the second, all * without blocking the main loop. * * A powerful communicate() API is provided similar to the * `%communicate()` method of `subprocess.py`. This enables very easy * interaction with a subprocess that has been opened with pipes. * * %Gio::Subprocess defaults to tight control over the file descriptors open * in the child process, avoiding dangling-fd issues that are caused by * a simple fork()/exec(). The only open file descriptors in the * spawned process are ones that were explicitly specified by the * %Gio::Subprocess API (unless Gio::Subprocess::Flags::INHERIT_FDS was * specified). * * %Gio::Subprocess will quickly reap all child processes as they exit, * avoiding "zombie processes" remaining around for long periods of * time. wait() can be used to wait for this to happen, * but it will happen even without the call being explicitly made. * * As a matter of principle, %Gio::Subprocess has no API that accepts * shell-style space-separated strings. It will, however, match the * typical shell behaviour of searching the PATH for executables that do * not contain a directory separator in their name. By default, the `PATH` * of the current process is used. You can specify * Gio::Subprocess::Flags::SEARCH_PATH_FROM_ENVP to use the `PATH` of the * launcher environment instead. * * %Gio::Subprocess attempts to have a very simple API for most uses (ie: * spawning a subprocess with arguments and support for most typical * kinds of input and output redirection). See create(). The * Gio::SubprocessLauncher API is provided for more complicated cases * (advanced types of redirection, environment variable manipulation, * change of working directory, child setup functions, etc). * * A typical use of %Gio::Subprocess will involve calling create(), followed by * wait_async() or wait(). After the process exits, the status can be * checked using functions such as get_if_exited() (which are similar to * the familiar WIFEXITED-style POSIX macros). * * @see Gio::SubprocessLauncher * @newin{2,78} */ class GIOMM_API Subprocess : public Glib::Object, public Initable { #ifndef DOXYGEN_SHOULD_SKIP_THIS public: using CppObjectType = Subprocess; using CppClassType = Subprocess_Class; using BaseObjectType = GSubprocess; using BaseClassType = GSubprocessClass; // noncopyable Subprocess(const Subprocess&) = delete; Subprocess& operator=(const Subprocess&) = delete; private: friend class Subprocess_Class; static CppClassType subprocess_class_; protected: explicit Subprocess(const Glib::ConstructParams& construct_params); explicit Subprocess(GSubprocess* castitem); #endif /* DOXYGEN_SHOULD_SKIP_THIS */ public: Subprocess(Subprocess&& src) noexcept; Subprocess& operator=(Subprocess&& src) noexcept; ~Subprocess() noexcept override; /** Get the GType for this class, for use with the underlying GObject type system. */ static GType get_type() G_GNUC_CONST; #ifndef DOXYGEN_SHOULD_SKIP_THIS static GType get_base_type() G_GNUC_CONST; #endif ///Provides access to the underlying C GObject. GSubprocess* gobj() { return reinterpret_cast(gobject_); } ///Provides access to the underlying C GObject. const GSubprocess* gobj() const { return reinterpret_cast(gobject_); } ///Provides access to the underlying C instance. The caller is responsible for unrefing it. Use when directly setting fields in structs. GSubprocess* gobj_copy(); private: public: /** @addtogroup giommEnums giomm Enums and Flags */ /** * @var Flags::NONE * No flags. * * @var Flags::STDIN_PIPE * Create a pipe for the stdin of the * spawned process that can be accessed with * g_subprocess_get_stdin_pipe(). * * @var Flags::STDIN_INHERIT * Stdin is inherited from the * calling process. * * @var Flags::STDOUT_PIPE * Create a pipe for the stdout of the * spawned process that can be accessed with * g_subprocess_get_stdout_pipe(). * * @var Flags::STDOUT_SILENCE * Silence the stdout of the spawned * process (ie: redirect to `/dev/null`). * * @var Flags::STDERR_PIPE * Create a pipe for the stderr of the * spawned process that can be accessed with * g_subprocess_get_stderr_pipe(). * * @var Flags::STDERR_SILENCE * Silence the stderr of the spawned * process (ie: redirect to `/dev/null`). * * @var Flags::STDERR_MERGE * Merge the stderr of the spawned * process with whatever the stdout happens to be. This is a good way * of directing both streams to a common log file, for example. * * @var Flags::INHERIT_FDS * Spawned processes will inherit the * file descriptors of their parent, unless those descriptors have * been explicitly marked as close-on-exec. This flag has no effect * over the "standard" file descriptors (stdin, stdout, stderr). * * @var Flags::SEARCH_PATH_FROM_ENVP * If path searching is * needed when spawning the subprocess, use the `PATH` in the launcher * environment. (Since: 2.72). */ /** Flags to define the behaviour of a Subprocess. * * Note that the default for stdin is to redirect from `/dev/null`. For * stdout and stderr the default are for them to inherit the * corresponding descriptor from the calling process. * * Note that it is a programmer error to mix 'incompatible' flags. For * example, you may not request both Gio::Subprocess::Flags::STDOUT_PIPE and * Gio::Subprocess::Flags::STDOUT_SILENCE. * * @newin{2,78} * * @ingroup giommEnums * @par Bitwise operators: * Subprocess::Flags operator|(Subprocess::Flags, Subprocess::Flags)
* Subprocess::Flags operator&(Subprocess::Flags, Subprocess::Flags)
* Subprocess::Flags operator^(Subprocess::Flags, Subprocess::Flags)
* Subprocess::Flags operator~(Subprocess::Flags)
* Subprocess::Flags& operator|=(Subprocess::Flags&, Subprocess::Flags)
* Subprocess::Flags& operator&=(Subprocess::Flags&, Subprocess::Flags)
* Subprocess::Flags& operator^=(Subprocess::Flags&, Subprocess::Flags)
*/ enum class Flags { NONE = 0x0, STDIN_PIPE = (1u << 0), STDIN_INHERIT = (1u << 1), STDOUT_PIPE = (1u << 2), STDOUT_SILENCE = (1u << 3), STDERR_PIPE = (1u << 4), STDERR_SILENCE = (1u << 5), STDERR_MERGE = (1u << 6), INHERIT_FDS = (1u << 7), SEARCH_PATH_FROM_ENVP = (1u << 8) }; protected: // Handwritten to ignore the final GError** parameter in the g_subprocess_newv() function. // It can throw, due to its call to Initable::init(). explicit Subprocess(const std::vector& argv, Flags flags = Flags::NONE); public: /** Create a new process with the given flags and argument list. * * @newin{2,78} * * @param argv Commandline arguments for the subprocess. * @param flags Flags that define the behaviour of the subprocess. * @return A newly created Subprocess. On error, an exception is thrown. * * @throws Glib::Error */ static Glib::RefPtr create(const std::vector& argv, Flags flags = Flags::NONE); /** Gets the OutputStream that you can write to in order to give data * to the stdin of @a subprocess. * * The process must have been created with Gio::Subprocess::Flags::STDIN_PIPE and * not Gio::Subprocess::Flags::STDIN_INHERIT, otherwise nullptr will be returned. * * @newin{2,78} * * @return The stdout pipe. */ Glib::RefPtr get_stdin_pipe(); /** Gets the OutputStream that you can write to in order to give data * to the stdin of @a subprocess. * * The process must have been created with Gio::Subprocess::Flags::STDIN_PIPE and * not Gio::Subprocess::Flags::STDIN_INHERIT, otherwise nullptr will be returned. * * @newin{2,78} * * @return The stdout pipe. */ Glib::RefPtr get_stdin_pipe() const; /** Gets the InputStream from which to read the stdout output of * @a subprocess. * * The process must have been created with Gio::Subprocess::Flags::STDOUT_PIPE, * otherwise nullptr will be returned. * * @newin{2,78} * * @return The stdout pipe. */ Glib::RefPtr get_stdout_pipe(); /** Gets the InputStream from which to read the stdout output of * @a subprocess. * * The process must have been created with Gio::Subprocess::Flags::STDOUT_PIPE, * otherwise nullptr will be returned. * * @newin{2,78} * * @return The stdout pipe. */ Glib::RefPtr get_stdout_pipe() const; /** Gets the InputStream from which to read the stderr output of * @a subprocess. * * The process must have been created with Gio::Subprocess::Flags::STDERR_PIPE, * otherwise nullptr will be returned. * * @newin{2,78} * * @return The stderr pipe. */ Glib::RefPtr get_stderr_pipe(); /** Gets the InputStream from which to read the stderr output of * @a subprocess. * * The process must have been created with Gio::Subprocess::Flags::STDERR_PIPE, * otherwise nullptr will be returned. * * @newin{2,78} * * @return The stderr pipe. */ Glib::RefPtr get_stderr_pipe() const; /** On UNIX, returns the process ID as a decimal string. * On Windows, returns the result of GetProcessId() also as a string. * If the subprocess has terminated, this will return nullptr. * * @newin{2,78} * * @return The subprocess identifier, or nullptr if the subprocess * has terminated. */ Glib::ustring get_identifier() const; #ifdef G_OS_UNIX /** Sends the UNIX signal @a signal_num to the subprocess, if it is still * running. * * This API is race-free. If the subprocess has terminated, it will not * be signalled. * * This API is not available on Windows. * * @newin{2,78} * * @param signal_num The signal number to send. */ void send_signal(int signal_num); #endif // G_OS_UNIX /** Use an operating-system specific method to attempt an immediate, * forceful termination of the process. There is no mechanism to * determine whether or not the request itself was successful; * however, you can use g_subprocess_wait() to monitor the status of * the process after calling this function. * * On Unix, this function sends S::IGKILL. * * @newin{2,78} */ void force_exit(); /** Synchronously wait for the subprocess to terminate. * * After the process terminates you can query its exit status with * functions such as g_subprocess_get_if_exited() and * g_subprocess_get_exit_status(). * * This function does not fail in the case of the subprocess having * abnormal termination. See g_subprocess_wait_check() for that. * * Cancelling @a cancellable doesn't kill the subprocess. Call * g_subprocess_force_exit() if it is desirable. * * @newin{2,78} * * @param cancellable A Cancellable. * * @throws Glib::Error */ void wait(const Glib::RefPtr& cancellable = {}) const; /** Wait for the subprocess to terminate. * * This is the asynchronous version of g_subprocess_wait(). * * @newin{2,78} * * @param cancellable A Cancellable, or nullptr. * @param slot A SlotAsyncReady to call when the operation is complete. */ void wait_async(const SlotAsyncReady& slot, const Glib::RefPtr& cancellable = {}) const; /** Collects the result of a previous call to * g_subprocess_wait_async(). * * @newin{2,78} * * @param result The AsyncResult passed to your SlotAsyncReady. * * @throws Glib::Error */ void wait_finish(const Glib::RefPtr& result) const; /** Combines g_subprocess_wait() with Glib::spawn_check_wait_status(). * * @newin{2,78} * * @param cancellable A Cancellable. * * @throws Glib::Error */ void wait_check(const Glib::RefPtr& cancellable = {}) const; /** Combines g_subprocess_wait_async() with Glib::spawn_check_wait_status(). * * This is the asynchronous version of g_subprocess_wait_check(). * * @newin{2,78} * * @param cancellable A Cancellable, or nullptr. * @param slot A SlotAsyncReady to call when the operation is complete. */ void wait_check_async(const SlotAsyncReady& slot, const Glib::RefPtr& cancellable = {}) const; /** Collects the result of a previous call to * g_subprocess_wait_check_async(). * * @newin{2,78} * * @param result The AsyncResult passed to your SlotAsyncReady. * * @throws Glib::Error */ void wait_check_finish(const Glib::RefPtr& result) const; /** Gets the raw status code of the process, as from waitpid(). * * This value has no particular meaning, but it can be used with the * macros defined by the system headers such as WIFEXITED. It can also * be used with Glib::spawn_check_wait_status(). * * It is more likely that you want to use g_subprocess_get_if_exited() * followed by g_subprocess_get_exit_status(). * * It is an error to call this function before g_subprocess_wait() has * returned. * * @newin{2,78} * * @return The (meaningless) waitpid() exit status from the kernel. */ int get_status() const; /** Checks if the process was "successful". A process is considered * successful if it exited cleanly with an exit status of 0, either by * way of the exit() system call or return from main(). * * It is an error to call this function before g_subprocess_wait() has * returned. * * @newin{2,78} * * @return true if the process exited cleanly with a exit status of 0. */ bool get_successful() const; /** Check if the given subprocess exited normally (ie: by way of exit() * or return from main()). * * This is equivalent to the system WIFEXITED macro. * * It is an error to call this function before g_subprocess_wait() has * returned. * * @newin{2,78} * * @return true if the case of a normal exit. */ bool get_if_exited() const; /** Check the exit status of the subprocess, given that it exited * normally. This is the value passed to the exit() system call or the * return value from main. * * This is equivalent to the system WEXITSTATUS macro. * * It is an error to call this function before g_subprocess_wait() and * unless g_subprocess_get_if_exited() returned true. * * @newin{2,78} * * @return The exit status. */ int get_exit_status() const; /** Check if the given subprocess terminated in response to a signal. * * This is equivalent to the system WIFSIGNALED macro. * * It is an error to call this function before g_subprocess_wait() has * returned. * * @newin{2,78} * * @return true if the case of termination due to a signal. */ bool get_if_signaled() const; /** Get the signal number that caused the subprocess to terminate, given * that it terminated due to a signal. * * This is equivalent to the system WTERMSIG macro. * * It is an error to call this function before g_subprocess_wait() and * unless g_subprocess_get_if_signaled() returned true. * * @newin{2,78} * * @return The signal causing termination. */ int get_term_sig() const; /** Communicate with the subprocess until it terminates, and all input * and output has been completed. * * If @a stdin_buf is given, the subprocess must have been created with * Gio::Subprocess::Flags::STDIN_PIPE. The given data is fed to the * stdin of the subprocess and the pipe is closed (ie: EOF). * * At the same time (as not to cause blocking when dealing with large * amounts of data), if Gio::Subprocess::Flags::STDOUT_PIPE or * Gio::Subprocess::Flags::STDERR_PIPE were used, reads from those * streams. The data that was read is returned in @a stdout_buf and/or * the @a stderr_buf. * * If the subprocess was created with Gio::Subprocess::Flags::STDOUT_PIPE, * @a stdout_buf will contain the data read from stdout. Otherwise, for * subprocesses not created with Gio::Subprocess::Flags::STDOUT_PIPE, * @a stdout_buf will be set to an empty RefPtr. Similar provisions apply to * @a stderr_buf and Gio::Subprocess::Flags::STDERR_PIPE. * * If you desire the stdout and stderr data to be interleaved, create * the subprocess with Gio::Subprocess::Flags::STDOUT_PIPE and * Gio::Subprocess::Flags::STDERR_MERGE. The merged result will be returned * in @a stdout_buf, and @a stderr_buf will be set to an empty RefPtr. * * In case of any error (including cancellation), an exception will be thrown. * * After a normal return (no exception thrown), the subprocess has exited and the * exit status inspection APIs (eg: get_if_exited(), get_exit_status()) may be used. * * You should not attempt to use any of the subprocess pipes after * starting this function, since they may be left in strange states, * even if the operation was cancelled. You should especially not * attempt to interact with the pipes while the operation is in progress * (either from another thread or if using the asynchronous version). * * @newin{2,78} * * @param stdin_buf Data to send to the stdin of the subprocess, or an empty RefPtr. * @param cancellable A Cancellable. * @return {stdout_buf, stderr_buf} stdout data and stderr data. * Can be empty RefPtrs, if there are no data. * * @throws Glib::Error */ std::pair, Glib::RefPtr> communicate(const Glib::RefPtr& stdin_buf, const Glib::RefPtr& cancellable = {}); /** Asynchronous version of g_subprocess_communicate(). Complete * invocation with g_subprocess_communicate_finish(). * * @newin{2,78} * * @param stdin_buf Input data, or nullptr. * @param cancellable Cancellable. * @param slot Callback. */ void communicate_async(const Glib::RefPtr& stdin_buf, const SlotAsyncReady& slot, const Glib::RefPtr& cancellable = {}); /** Complete an invocation of communicate_async(). * * @newin{2,78} * * @param result Result. * @return {stdout_buf, stderr_buf} stdout data and stderr data. * Can be empty RefPtrs, if there are no data. * * @throws Glib::Error */ std::pair, Glib::RefPtr> communicate_finish(const Glib::RefPtr& result); /** Like communicate(), but validates the output of the * process as UTF-8, and returns it as a regular Glib::ustring. * * On error, an exception is thrown. * * @newin{2,78} * * @param stdin_buf Data to send to the stdin of the subprocess, or an empty string. * @param cancellable A Cancellable. * @return {stdout_buf, stderr_buf} stdout data and stderr data. * * @throws Glib::Error */ std::pair communicate_utf8(const Glib::ustring& stdin_buf, const Glib::RefPtr& cancellable = {}); /** Asynchronous version of g_subprocess_communicate_utf8(). Complete * invocation with g_subprocess_communicate_utf8_finish(). * * @newin{2,78} * * @param stdin_buf Input data, or nullptr. * @param cancellable Cancellable. * @param slot Callback. */ void communicate_utf8_async(const Glib::ustring& stdin_buf, const SlotAsyncReady& slot, const Glib::RefPtr& cancellable = {}); /** Complete an invocation of communicate_utf8_async(). * * @newin{2,78} * * @param result Result. * @return {stdout_buf, stderr_buf} stdout data and stderr data. * * @throws Glib::Error */ std::pair communicate_utf8_finish(const Glib::RefPtr& result); // _IGNORE_PROPERTY("flags", "argv") // write-only, construct-only public: public: //C++ methods used to invoke GTK+ virtual functions: protected: //GTK+ Virtual Functions (override these to change behaviour): //Default Signal Handlers:: }; } // namespace Gio namespace Gio { /** @ingroup giommEnums */ inline Subprocess::Flags operator|(Subprocess::Flags lhs, Subprocess::Flags rhs) { return static_cast(static_cast(lhs) | static_cast(rhs)); } /** @ingroup giommEnums */ inline Subprocess::Flags operator&(Subprocess::Flags lhs, Subprocess::Flags rhs) { return static_cast(static_cast(lhs) & static_cast(rhs)); } /** @ingroup giommEnums */ inline Subprocess::Flags operator^(Subprocess::Flags lhs, Subprocess::Flags rhs) { return static_cast(static_cast(lhs) ^ static_cast(rhs)); } /** @ingroup giommEnums */ inline Subprocess::Flags operator~(Subprocess::Flags flags) { return static_cast(~static_cast(flags)); } /** @ingroup giommEnums */ inline Subprocess::Flags& operator|=(Subprocess::Flags& lhs, Subprocess::Flags rhs) { return (lhs = static_cast(static_cast(lhs) | static_cast(rhs))); } /** @ingroup giommEnums */ inline Subprocess::Flags& operator&=(Subprocess::Flags& lhs, Subprocess::Flags rhs) { return (lhs = static_cast(static_cast(lhs) & static_cast(rhs))); } /** @ingroup giommEnums */ inline Subprocess::Flags& operator^=(Subprocess::Flags& lhs, Subprocess::Flags rhs) { return (lhs = static_cast(static_cast(lhs) ^ static_cast(rhs))); } } // namespace Gio #ifndef DOXYGEN_SHOULD_SKIP_THIS namespace Glib { template <> class GIOMM_API Value : public Glib::Value_Flags { public: static GType value_type() G_GNUC_CONST; }; } // namespace Glib #endif /* DOXYGEN_SHOULD_SKIP_THIS */ namespace Glib { /** A Glib::wrap() method for this object. * * @param object The C instance. * @param take_copy False if the result should take ownership of the C instance. True if it should take a new copy or ref. * @result A C++ instance that wraps this C instance. * * @relates Gio::Subprocess */ GIOMM_API Glib::RefPtr wrap(GSubprocess* object, bool take_copy = false); } #endif /* _GIOMM_SUBPROCESS_H */