Improve process API

Prefix symbols and constants names and improve documentation.
This commit is contained in:
Romain Vimont
2021-11-11 17:48:41 +01:00
parent 7e93abcf6d
commit aa011832c1
10 changed files with 240 additions and 215 deletions

View File

@@ -10,9 +10,9 @@
#include "util/log.h"
enum process_result
process_execute_redirect(const char *const argv[], pid_t *pid, int *pipe_stdin,
int *pipe_stdout, int *pipe_stderr) {
enum sc_process_result
sc_process_execute_p(const char *const argv[], sc_pid *pid,
int *pin, int *pout, int *perr) {
int in[2];
int out[2];
int err[2];
@@ -20,44 +20,44 @@ process_execute_redirect(const char *const argv[], pid_t *pid, int *pipe_stdin,
if (pipe(internal) == -1) {
perror("pipe");
return PROCESS_ERROR_GENERIC;
return SC_PROCESS_ERROR_GENERIC;
}
if (pipe_stdin) {
if (pin) {
if (pipe(in) == -1) {
perror("pipe");
close(internal[0]);
close(internal[1]);
return PROCESS_ERROR_GENERIC;
return SC_PROCESS_ERROR_GENERIC;
}
}
if (pipe_stdout) {
if (pout) {
if (pipe(out) == -1) {
perror("pipe");
// clean up
if (pipe_stdin) {
if (pin) {
close(in[0]);
close(in[1]);
}
close(internal[0]);
close(internal[1]);
return PROCESS_ERROR_GENERIC;
return SC_PROCESS_ERROR_GENERIC;
}
}
if (pipe_stderr) {
if (perr) {
if (pipe(err) == -1) {
perror("pipe");
// clean up
if (pipe_stdout) {
if (pout) {
close(out[0]);
close(out[1]);
}
if (pipe_stdin) {
if (pin) {
close(in[0]);
close(in[1]);
}
close(internal[0]);
close(internal[1]);
return PROCESS_ERROR_GENERIC;
return SC_PROCESS_ERROR_GENERIC;
}
}
@@ -65,39 +65,39 @@ process_execute_redirect(const char *const argv[], pid_t *pid, int *pipe_stdin,
if (*pid == -1) {
perror("fork");
// clean up
if (pipe_stderr) {
if (perr) {
close(err[0]);
close(err[1]);
}
if (pipe_stdout) {
if (pout) {
close(out[0]);
close(out[1]);
}
if (pipe_stdin) {
if (pin) {
close(in[0]);
close(in[1]);
}
close(internal[0]);
close(internal[1]);
return PROCESS_ERROR_GENERIC;
return SC_PROCESS_ERROR_GENERIC;
}
if (*pid == 0) {
if (pipe_stdin) {
if (pin) {
if (in[0] != STDIN_FILENO) {
dup2(in[0], STDIN_FILENO);
close(in[0]);
}
close(in[1]);
}
if (pipe_stdout) {
if (pout) {
if (out[1] != STDOUT_FILENO) {
dup2(out[1], STDOUT_FILENO);
close(out[1]);
}
close(out[0]);
}
if (pipe_stderr) {
if (perr) {
if (err[1] != STDERR_FILENO) {
dup2(err[1], STDERR_FILENO);
close(err[1]);
@@ -105,15 +105,15 @@ process_execute_redirect(const char *const argv[], pid_t *pid, int *pipe_stdin,
close(err[0]);
}
close(internal[0]);
enum process_result err;
enum sc_process_result err;
if (fcntl(internal[1], F_SETFD, FD_CLOEXEC) == 0) {
execvp(argv[0], (char *const *) argv);
perror("exec");
err = errno == ENOENT ? PROCESS_ERROR_MISSING_BINARY
: PROCESS_ERROR_GENERIC;
err = errno == ENOENT ? SC_PROCESS_ERROR_MISSING_BINARY
: SC_PROCESS_ERROR_GENERIC;
} else {
perror("fcntl");
err = PROCESS_ERROR_GENERIC;
err = SC_PROCESS_ERROR_GENERIC;
}
// send err to the parent
if (write(internal[1], &err, sizeof(err)) == -1) {
@@ -128,25 +128,25 @@ process_execute_redirect(const char *const argv[], pid_t *pid, int *pipe_stdin,
close(internal[1]);
enum process_result res = PROCESS_SUCCESS;
enum sc_process_result res = SC_PROCESS_SUCCESS;
// wait for EOF or receive err from child
if (read(internal[0], &res, sizeof(res)) == -1) {
perror("read");
res = PROCESS_ERROR_GENERIC;
res = SC_PROCESS_ERROR_GENERIC;
}
close(internal[0]);
if (pipe_stdin) {
if (pin) {
close(in[0]);
*pipe_stdin = in[1];
*pin = in[1];
}
if (pipe_stdout) {
*pipe_stdout = out[0];
if (pout) {
*pout = out[0];
close(out[1]);
}
if (pipe_stderr) {
*pipe_stderr = err[0];
if (perr) {
*perr = err[0];
close(err[1]);
}
@@ -154,7 +154,7 @@ process_execute_redirect(const char *const argv[], pid_t *pid, int *pipe_stdin,
}
bool
process_terminate(pid_t pid) {
sc_process_terminate(pid_t pid) {
if (pid <= 0) {
LOGC("Requested to kill %d, this is an error. Please report the bug.\n",
(int) pid);
@@ -163,8 +163,8 @@ process_terminate(pid_t pid) {
return kill(pid, SIGKILL) != -1;
}
exit_code_t
process_wait(pid_t pid, bool close) {
sc_exit_code
sc_process_wait(pid_t pid, bool close) {
int code;
int options = WEXITED;
if (!close) {
@@ -175,7 +175,7 @@ process_wait(pid_t pid, bool close) {
int r = waitid(P_PID, pid, &info, options);
if (r == -1 || info.si_code != CLD_EXITED) {
// could not wait, or exited unexpectedly, probably by a signal
code = NO_EXIT_CODE;
code = SC_EXIT_CODE_NONE;
} else {
code = info.si_status;
}
@@ -183,17 +183,17 @@ process_wait(pid_t pid, bool close) {
}
void
process_close(pid_t pid) {
process_wait(pid, true); // ignore exit code
sc_process_close(pid_t pid) {
sc_process_wait(pid, true); // ignore exit code
}
ssize_t
read_pipe(int pipe, char *data, size_t len) {
sc_pipe_read(int pipe, char *data, size_t len) {
return read(pipe, data, len);
}
void
close_pipe(int pipe) {
sc_pipe_close(int pipe) {
if (close(pipe)) {
perror("close pipe");
}

View File

@@ -15,17 +15,16 @@ build_cmd(char *cmd, size_t len, const char *const argv[]) {
// (don't handle escaping nor quotes)
size_t ret = xstrjoin(cmd, argv, ' ', len);
if (ret >= len) {
LOGE("Command too long (%" PRIsizet " chars)", len - 1);
LOGE("Command too long (%" SC_PRIsizet " chars)", len - 1);
return false;
}
return true;
}
enum process_result
process_execute_redirect(const char *const argv[], HANDLE *handle,
HANDLE *pipe_stdin, HANDLE *pipe_stdout,
HANDLE *pipe_stderr) {
enum process_result ret = PROCESS_ERROR_GENERIC;
enum sc_process_result
sc_process_execute_p(const char *const argv[], HANDLE *handle,
HANDLE *pin, HANDLE *pout, HANDLE *perr) {
enum sc_process_result ret = SC_PROCESS_ERROR_GENERIC;
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
@@ -35,32 +34,32 @@ process_execute_redirect(const char *const argv[], HANDLE *handle,
HANDLE stdin_read_handle;
HANDLE stdout_write_handle;
HANDLE stderr_write_handle;
if (pipe_stdin) {
if (!CreatePipe(&stdin_read_handle, pipe_stdin, &sa, 0)) {
if (pin) {
if (!CreatePipe(&stdin_read_handle, pin, &sa, 0)) {
perror("pipe");
return PROCESS_ERROR_GENERIC;
return SC_PROCESS_ERROR_GENERIC;
}
if (!SetHandleInformation(*pipe_stdin, HANDLE_FLAG_INHERIT, 0)) {
if (!SetHandleInformation(*pin, HANDLE_FLAG_INHERIT, 0)) {
LOGE("SetHandleInformation stdin failed");
goto error_close_stdin;
}
}
if (pipe_stdout) {
if (!CreatePipe(pipe_stdout, &stdout_write_handle, &sa, 0)) {
if (pout) {
if (!CreatePipe(pout, &stdout_write_handle, &sa, 0)) {
perror("pipe");
goto error_close_stdin;
}
if (!SetHandleInformation(*pipe_stdout, HANDLE_FLAG_INHERIT, 0)) {
if (!SetHandleInformation(*pout, HANDLE_FLAG_INHERIT, 0)) {
LOGE("SetHandleInformation stdout failed");
goto error_close_stdout;
}
}
if (pipe_stderr) {
if (!CreatePipe(pipe_stderr, &stderr_write_handle, &sa, 0)) {
if (perr) {
if (!CreatePipe(perr, &stderr_write_handle, &sa, 0)) {
perror("pipe");
goto error_close_stdout;
}
if (!SetHandleInformation(*pipe_stderr, HANDLE_FLAG_INHERIT, 0)) {
if (!SetHandleInformation(*perr, HANDLE_FLAG_INHERIT, 0)) {
LOGE("SetHandleInformation stderr failed");
goto error_close_stderr;
}
@@ -70,15 +69,15 @@ process_execute_redirect(const char *const argv[], HANDLE *handle,
PROCESS_INFORMATION pi;
memset(&si, 0, sizeof(si));
si.cb = sizeof(si);
if (pipe_stdin || pipe_stdout || pipe_stderr) {
if (pin || pout || perr) {
si.dwFlags = STARTF_USESTDHANDLES;
if (pipe_stdin) {
if (pin) {
si.hStdInput = stdin_read_handle;
}
if (pipe_stdout) {
if (pout) {
si.hStdOutput = stdout_write_handle;
}
if (pipe_stderr) {
if (perr) {
si.hStdError = stderr_write_handle;
}
}
@@ -102,40 +101,40 @@ process_execute_redirect(const char *const argv[], HANDLE *handle,
*handle = NULL;
if (GetLastError() == ERROR_FILE_NOT_FOUND) {
ret = PROCESS_ERROR_MISSING_BINARY;
ret = SC_PROCESS_ERROR_MISSING_BINARY;
}
goto error_close_stderr;
}
// These handles are used by the child process, close them for this process
if (pipe_stdin) {
if (pin) {
CloseHandle(stdin_read_handle);
}
if (pipe_stdout) {
if (pout) {
CloseHandle(stdout_write_handle);
}
if (pipe_stderr) {
if (perr) {
CloseHandle(stderr_write_handle);
}
free(wide);
*handle = pi.hProcess;
return PROCESS_SUCCESS;
return SC_PROCESS_SUCCESS;
error_close_stderr:
if (pipe_stderr) {
CloseHandle(*pipe_stderr);
if (perr) {
CloseHandle(*perr);
CloseHandle(stderr_write_handle);
}
error_close_stdout:
if (pipe_stdout) {
CloseHandle(*pipe_stdout);
if (pout) {
CloseHandle(*pout);
CloseHandle(stdout_write_handle);
}
error_close_stdin:
if (pipe_stdin) {
CloseHandle(*pipe_stdin);
if (pin) {
CloseHandle(*pin);
CloseHandle(stdin_read_handle);
}
@@ -143,17 +142,17 @@ error_close_stdin:
}
bool
process_terminate(HANDLE handle) {
sc_process_terminate(HANDLE handle) {
return TerminateProcess(handle, 1);
}
exit_code_t
process_wait(HANDLE handle, bool close) {
sc_exit_code
sc_process_wait(HANDLE handle, bool close) {
DWORD code;
if (WaitForSingleObject(handle, INFINITE) != WAIT_OBJECT_0
|| !GetExitCodeProcess(handle, &code)) {
// could not wait or retrieve the exit code
code = NO_EXIT_CODE; // max value, it's unsigned
code = SC_EXIT_CODE_NONE;
}
if (close) {
CloseHandle(handle);
@@ -162,14 +161,14 @@ process_wait(HANDLE handle, bool close) {
}
void
process_close(HANDLE handle) {
sc_process_close(HANDLE handle) {
bool closed = CloseHandle(handle);
assert(closed);
(void) closed;
}
ssize_t
read_pipe(HANDLE pipe, char *data, size_t len) {
sc_read_pipe(HANDLE pipe, char *data, size_t len) {
DWORD r;
if (!ReadFile(pipe, data, len, &r, NULL)) {
return -1;
@@ -178,7 +177,7 @@ read_pipe(HANDLE pipe, char *data, size_t len) {
}
void
close_pipe(HANDLE pipe) {
sc_close_pipe(HANDLE pipe) {
if (!CloseHandle(pipe)) {
LOGW("Cannot close pipe");
}