#ifndef SC_PROCESS_H #define SC_PROCESS_H #include "common.h" #include #ifdef _WIN32 // not needed here, but winsock2.h must never be included AFTER windows.h # include # include # define SC_PRIexitcode "lu" // # define SC_PRIsizet "Iu" # define SC_PROCESS_NONE NULL # define SC_EXIT_CODE_NONE -1u // max value as unsigned typedef HANDLE sc_pid; typedef DWORD sc_exit_code; typedef HANDLE sc_pipe; #else # include # define SC_PRIsizet "zu" # define SC_PRIexitcode "d" # define SC_PROCESS_NONE -1 # define SC_EXIT_CODE_NONE -1 typedef pid_t sc_pid; typedef int sc_exit_code; typedef int sc_pipe; #endif enum sc_process_result { SC_PROCESS_SUCCESS, SC_PROCESS_ERROR_GENERIC, SC_PROCESS_ERROR_MISSING_BINARY, }; /** * Execute the command and write the process id to `pid` */ enum sc_process_result sc_process_execute(const char *const argv[], sc_pid *pid); /** * Execute the command and write the process id to `pid` * * If not NULL, provide a pipe for stdin (`pin`), stdout (`pout`) and stderr * (`perr`). */ enum sc_process_result sc_process_execute_p(const char *const argv[], sc_pid *pid, sc_pipe *pin, sc_pipe *pout, sc_pipe *perr); /** * Kill the process */ bool sc_process_terminate(sc_pid pid); /** * Wait and close the process (similar to waitpid()) * * The `close` flag indicates if the process must be _closed_ (reaped) (passing * false is equivalent to enable WNOWAIT in waitid()). */ sc_exit_code sc_process_wait(sc_pid pid, bool close); /** * Close (reap) the process * * Semantically: * sc_process_wait(close) = sc_process_wait(noclose) + sc_process_close() */ void sc_process_close(sc_pid pid); /** * Convenience function to wait for a successful process execution * * Automatically log process errors with the provided process name. */ bool sc_process_check_success(sc_pid pid, const char *name, bool close); /** * Read from the pipe * * Same semantic as read(). */ ssize_t sc_pipe_read(sc_pipe pipe, char *data, size_t len); /** * Read exactly `len` chars from a pipe (unless EOF) */ ssize_t sc_pipe_read_all(sc_pipe pipe, char *data, size_t len); /** * Close the pipe */ void sc_pipe_close(sc_pipe pipe); #endif