mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-05-28 17:16:29 +03:00
251 lines
9.6 KiB
C++
251 lines
9.6 KiB
C++
#ifndef EE_SYSTEM_PROCESS_HPP
|
|
#define EE_SYSTEM_PROCESS_HPP
|
|
|
|
#include <eepp/config.hpp>
|
|
#include <eepp/system/mutex.hpp>
|
|
#include <eepp/system/time.hpp>
|
|
#include <functional>
|
|
#include <string>
|
|
#include <thread>
|
|
#include <unordered_map>
|
|
|
|
namespace EE { namespace System {
|
|
|
|
class EE_API Process {
|
|
public:
|
|
enum Options {
|
|
// stdout and stderr are the same FILE.
|
|
CombinedStdoutStderr = 0x1,
|
|
|
|
// The child process should inherit the environment variables of the parent.
|
|
InheritEnvironment = 0x2,
|
|
|
|
// Enable asynchronous reading of stdout/stderr before it has completed.
|
|
EnableAsync = 0x4,
|
|
|
|
// Enable the child process to be spawned with no window visible if supported
|
|
// by the platform.
|
|
NoWindow = 0x8,
|
|
|
|
// Search for program names in the PATH variable. Always enabled on Windows.
|
|
// Note: this will **not** search for paths in any provided custom environment
|
|
// and instead uses the PATH of the spawning process.
|
|
SearchUserPath = 0x10
|
|
};
|
|
|
|
static inline constexpr Uint32 getDefaultOptions() {
|
|
return Options::SearchUserPath | Options::InheritEnvironment | Options::NoWindow;
|
|
}
|
|
|
|
struct Config {
|
|
size_t bufferSize = 131072;
|
|
Uint32 options = getDefaultOptions();
|
|
};
|
|
|
|
typedef std::function<void( const char* bytes, size_t n )> ReadFn;
|
|
|
|
static std::vector<std::string> parseArgs( const std::string& str );
|
|
|
|
Process();
|
|
|
|
/** @brief Create a process.
|
|
** @param command Command line to execute for this process.
|
|
** @param options A bit field of Options's to pass. */
|
|
Process( const std::string& command, Uint32 options = getDefaultOptions(),
|
|
const std::unordered_map<std::string, std::string>& environment = {},
|
|
const std::string& workingDirectory = "", const size_t& bufferSize = 132072 );
|
|
|
|
/** @brief Create a process.
|
|
** @param command Command line to execute for this process.
|
|
** @param args Command line arguments
|
|
** @param options A bit field of Options's to pass. */
|
|
Process( const std::string& command, const std::vector<std::string>& args,
|
|
Uint32 options = getDefaultOptions(),
|
|
const std::unordered_map<std::string, std::string>& environment = {},
|
|
const std::string& workingDirectory = "", const size_t& bufferSize = 132072 );
|
|
|
|
~Process();
|
|
|
|
/** @brief Create a process.
|
|
** @param command Command line to execute for this process.
|
|
** @param options A bit field of Options's to pass.
|
|
** @return On success true is returned. */
|
|
bool create( const std::string& command, Uint32 options = getDefaultOptions(),
|
|
const std::unordered_map<std::string, std::string>& environment = {},
|
|
const std::string& workingDirectory = "" );
|
|
|
|
/** @brief Create a process.
|
|
** @param command Command line to execute for this process.
|
|
** @param args Command line arguments to execute for this process.
|
|
** @param options A bit field of Options's to pass.
|
|
** @return On success true is returned. */
|
|
bool create( const std::string& command, const std::string& args,
|
|
Uint32 options = getDefaultOptions(),
|
|
const std::unordered_map<std::string, std::string>& environment = {},
|
|
const std::string& workingDirectory = "" );
|
|
|
|
/** @brief Create a process.
|
|
** @param command Command line to execute for this process.
|
|
** @param args Command line arguments to execute for this process.
|
|
** @param options A bit field of Options's to pass.
|
|
** @return On success true is returned. */
|
|
bool create( const std::string& command, const std::vector<std::string>& args,
|
|
Uint32 options = getDefaultOptions(),
|
|
const std::unordered_map<std::string, std::string>& environment = {},
|
|
const std::string& workingDirectory = "" );
|
|
|
|
/** @brief Starts a new thread to receive all stdout and stderr data */
|
|
void startAsyncRead( ReadFn readStdOut = nullptr, ReadFn readStdErr = nullptr );
|
|
|
|
/** @brief Read all standard output from the child process.
|
|
** @param buffer The buffer to read into.
|
|
** @return The number of bytes actually read into buffer. Can only be 0 if the
|
|
** process has complete.
|
|
**
|
|
** The only safe way to read from the standard output of a process during it's
|
|
** execution is to use the `Option::EnableAsync` option in
|
|
** conjuction with this method. */
|
|
size_t readAllStdOut( std::string& buffer, Time timeout = Time::Zero );
|
|
|
|
/** @brief Read the standard output from the child process.
|
|
** @param buffer The buffer to read into.
|
|
** @return The number of bytes actually read into buffer. Can only be 0 if the
|
|
** process has complete.
|
|
**
|
|
** The only safe way to read from the standard output of a process during it's
|
|
** execution is to use the `Option::EnableAsync` option in
|
|
** conjuction with this method. */
|
|
size_t readStdOut( std::string& buffer );
|
|
|
|
/** @brief Read the standard output from the child process.
|
|
** @param buffer The buffer to read into.
|
|
** @param size The maximum number of bytes to read.
|
|
** @return The number of bytes actually read into buffer. Can only be 0 if the
|
|
** process has complete.
|
|
**
|
|
** The only safe way to read from the standard output of a process during it's
|
|
** execution is to use the `Option::EnableAsync` option in
|
|
** conjuction with this method. */
|
|
size_t readStdOut( char* const buffer, const size_t& size );
|
|
|
|
/** @brief Read all the standard error from the child process.
|
|
** @param buffer The buffer to read into.
|
|
** @return The number of bytes actually read into buffer. Can only be 0 if the
|
|
** process has complete.
|
|
**
|
|
** The only safe way to read from the standard error of a process during it's
|
|
** execution is to use the `Option::EnableAsync` option in
|
|
** conjuction with this method. */
|
|
size_t readAllStdErr( std::string& buffer, Time timeout = Time::Zero );
|
|
|
|
/** @brief Read the standard error from the child process.
|
|
** @param buffer The buffer to read into.
|
|
** @return The number of bytes actually read into buffer. Can only be 0 if the
|
|
** process has complete.
|
|
**
|
|
** The only safe way to read from the standard error of a process during it's
|
|
** execution is to use the `Option::EnableAsync` option in
|
|
** conjuction with this method. */
|
|
size_t readStdErr( std::string& buffer );
|
|
|
|
/** @brief Read the standard error from the child process.
|
|
** @param buffer The buffer to read into.
|
|
** @param size The maximum number of bytes to read.
|
|
** @return The number of bytes actually read into buffer. Can only be 0 if the
|
|
** process has complete.
|
|
**
|
|
** The only safe way to read from the standard error of a process during it's
|
|
** execution is to use the `Option::EnableAsync` option in
|
|
** conjuction with this method. */
|
|
size_t readStdErr( char* const buffer, const size_t& size );
|
|
|
|
/** @brief Write the standard output from the child process.
|
|
** @param buffer The buffer to write into.
|
|
** @param size The number of bytes to write.
|
|
** @return The number of bytes actually written into buffer. */
|
|
size_t write( const char* buffer, const size_t& size );
|
|
|
|
/** @brief Write the standard output from the child process.
|
|
** @param buffer The buffer to write into.
|
|
** @return The number of bytes actually written into buffer. */
|
|
size_t write( const std::string& buffer );
|
|
|
|
/** @brief Write the standard output from the child process.
|
|
** @param buffer The buffer to write into.
|
|
** @return The number of bytes actually written into buffer. */
|
|
size_t write( const std::string_view& buffer );
|
|
|
|
/** @brief Wait for a process to finish execution.
|
|
** @param returnCodeOut The return code of the returned process (can be nullptr).
|
|
** @return On success true is returned.
|
|
**
|
|
** Joining a process will close the stdin pipe to the process. */
|
|
bool join( int* const returnCodeOut );
|
|
|
|
/** @brief Terminate a previously created process.
|
|
** @return On success true is returned.
|
|
**
|
|
** If the process to be destroyed had not finished execution, it will be
|
|
** terminated (i.e killed). */
|
|
bool kill();
|
|
|
|
/** @brief Destroy a previously created process.
|
|
** @return On success true is returned.
|
|
**
|
|
** If the process to be destroyed had not finished execution, it may out live
|
|
** the parent process. */
|
|
bool destroy();
|
|
|
|
/** @brief Returns if the subprocess is currently still alive and executing.
|
|
** @return If the process is still alive true returned. */
|
|
bool isAlive();
|
|
|
|
/** @brief Get the standard input file for a process.
|
|
** @return The file for standard input of the process.
|
|
**
|
|
** The file returned can be written to by the parent process to feed data to
|
|
** the standard input of the process. */
|
|
FILE* getStdIn() const;
|
|
|
|
/** @brief Get the standard output file for a process.
|
|
** @return The file for standard output of the process.
|
|
**
|
|
** The file returned can be read from by the parent process to read data from
|
|
** the standard output of the child process. */
|
|
FILE* getStdOut() const;
|
|
|
|
/** @brief Get the standard error file for a process.
|
|
** @return The file for standard error of the process.
|
|
**
|
|
** The file returned can be read from by the parent process to read data from
|
|
** the standard error of the child process.
|
|
**
|
|
** If the process was created with the Option::CombinedStdoutStderr
|
|
** option bit set, this function will return NULL, and the getStdOut
|
|
** function should be used for both the standard output and error combined. */
|
|
FILE* getStdErr() const;
|
|
|
|
/** Indicates that the process must start its shutdown */
|
|
void startShutdown();
|
|
|
|
/** Indicates if the process started its shutdown */
|
|
bool isShuttingDown() const;
|
|
|
|
protected:
|
|
void* mProcess{ nullptr };
|
|
bool mShuttingDown{ false };
|
|
bool mIsAsync{ false };
|
|
size_t mBufferSize{ 131072 };
|
|
std::thread mStdOutThread;
|
|
std::thread mStdErrThread;
|
|
Mutex mStdInMutex;
|
|
ReadFn mReadStdOutFn;
|
|
ReadFn mReadStdErrFn;
|
|
|
|
size_t readAll( std::string& buffer, bool readErr, Time timeout = Time::Zero );
|
|
};
|
|
|
|
}} // namespace EE::System
|
|
|
|
#endif // EE_SYSTEM_PROCESS_HPP
|