Compare commits

...

9 Commits

3 changed files with 55 additions and 45 deletions

View File

@@ -1,4 +1,8 @@
#pragma once #pragma once
#ifdef __cplusplus
extern "C"
{
#endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h> #include <stdint.h>
@@ -18,9 +22,12 @@ typedef struct {
uniproc_process uniproc_create_process(const char* cmd, const size_t num_args, const char** argv); uniproc_process uniproc_create_process(const char* cmd, const size_t num_args, const char** argv);
void uniproc_await_processes(const uniproc_process* p, int* return_codes, const size_t num_processes); void uniproc_await_processes(const uniproc_process* p, int* return_codes, const size_t num_processes);
void uniproc_close_process(uniproc_process* p); void uniproc_close_process(uniproc_process* p);
bool uniproc_are_processes_finished(const uniproc_process* p, const size_t num_processes); int uniproc_are_processes_finished(const uniproc_process* p, const size_t num_processes);
void uniproc_nullify_processes(uniproc_process* p, const size_t num_processes); void uniproc_nullify_processes(uniproc_process* p, const size_t num_processes);
bool uniproc_is_process_null(const uniproc_process* p); int uniproc_is_process_null(const uniproc_process* p);
void uniproc_await_any_processes(const uniproc_process* p, const size_t num_processes); void uniproc_await_any_processes(const uniproc_process* p, const size_t num_processes);
void uniproc_set_userdata(uniproc_process* p, void const* userdata); void uniproc_set_userdata(uniproc_process* p, void const* userdata);
void* uniproc_get_userdata(uniproc_process* p); void* uniproc_get_userdata(uniproc_process* p);
#ifdef __cplusplus
}
#endif

View File

@@ -9,6 +9,8 @@
uniproc_process uniproc_create_process(const char* cmd, const size_t num_args, const char** argv) uniproc_process uniproc_create_process(const char* cmd, const size_t num_args, const char** argv)
{ {
(void)num_args; (void)num_args;
uniproc_process p;
// Create pipes // Create pipes
int stdin_pipe[2]; int stdin_pipe[2];
int stdout_pipe[2]; int stdout_pipe[2];
@@ -16,22 +18,21 @@ uniproc_process uniproc_create_process(const char* cmd, const size_t num_args, c
if (pipe(stdin_pipe) == -1) if (pipe(stdin_pipe) == -1)
{ {
uniproc_nullify_processes(p, 1); uniproc_nullify_processes(&p, 1);
return p; return p;
} }
if (pipe(stdout_pipe) == -1) if (pipe(stdout_pipe) == -1)
{ {
uniproc_nullify_processes(p, 1); uniproc_nullify_processes(&p, 1);
return p; return p;
} }
if (pipe(stderr_pipe) == -1) if (pipe(stderr_pipe) == -1)
{ {
uniproc_nullify_processes(p, 1); uniproc_nullify_processes(&p, 1);
return p; return p;
} }
// Fork process // Fork process
uniproc_process p;
p.in = stdin_pipe[1]; // Write handle p.in = stdin_pipe[1]; // Write handle
p.out = stdout_pipe[0]; // Read handle p.out = stdout_pipe[0]; // Read handle
p.err = stderr_pipe[0]; // Read handle p.err = stderr_pipe[0]; // Read handle
@@ -39,7 +40,7 @@ uniproc_process uniproc_create_process(const char* cmd, const size_t num_args, c
pid_t pid = fork(); pid_t pid = fork();
if (pid == -1) if (pid == -1)
{ {
uniproc_nullify_processes(p, 1); uniproc_nullify_processes(&p, 1);
return p; return p;
} }
// Child // Child
@@ -48,17 +49,17 @@ uniproc_process uniproc_create_process(const char* cmd, const size_t num_args, c
// Redirect the child's std. files to the pipes created above // Redirect the child's std. files to the pipes created above
if (dup2(stdin_pipe[0], STDIN_FILENO) == -1) if (dup2(stdin_pipe[0], STDIN_FILENO) == -1)
{ {
uniproc_nullify_processes(p, 1); uniproc_nullify_processes(&p, 1);
return p; return p;
} }
if (dup2(stdout_pipe[1], STDOUT_FILENO) == -1) if (dup2(stdout_pipe[1], STDOUT_FILENO) == -1)
{ {
uniproc_nullify_processes(p, 1); uniproc_nullify_processes(&p, 1);
return p; return p;
} }
if (dup2(stdout_pipe[2], STDERR_FILENO) == -1) if (dup2(stdout_pipe[2], STDERR_FILENO) == -1)
{ {
uniproc_nullify_processes(p, 1); uniproc_nullify_processes(&p, 1);
return p; return p;
} }
@@ -73,7 +74,7 @@ uniproc_process uniproc_create_process(const char* cmd, const size_t num_args, c
// And execute the command provided // And execute the command provided
if (execvp(cmd, argv) == -1) if (execvp(cmd, argv) == -1)
{ {
uniproc_nullify_processes(p, 1); uniproc_nullify_processes(&p, 1);
return p; return p;
} }
@@ -120,9 +121,9 @@ void uniproc_close_process(uniproc_process* p)
uniproc_nullify_processes(p, 1); uniproc_nullify_processes(p, 1);
} }
bool uniproc_are_processes_finished(const uniproc_process* p, const size_t num_processes) int uniproc_are_processes_finished(const uniproc_process* p, const size_t num_processes)
{ {
bool res = true; int res = 1;
for (size_t i = 0; i < num_processes; ++i) for (size_t i = 0; i < num_processes; ++i)
res &&= uniproc_is_process_null(p + i) || waitpid(p[i]._proc_hdl, nullptr, WNOHANG | WIFEXITED | WIFSIGNALED | WCOREDUMP); res &&= uniproc_is_process_null(p + i) || waitpid(p[i]._proc_hdl, nullptr, WNOHANG | WIFEXITED | WIFSIGNALED | WCOREDUMP);
@@ -133,7 +134,7 @@ bool uniproc_are_processes_finished(const uniproc_process* p, const size_t num_p
void uniproc_nullify_processes(uniproc_process* p, const size_t num_processes) void uniproc_nullify_processes(uniproc_process* p, const size_t num_processes)
{ memset(p, 0, sizeof(uniproc_process) * mum_processes); } { memset(p, 0, sizeof(uniproc_process) * mum_processes); }
bool uniproc_is_process_null(const uniproc_process* p) int uniproc_is_process_null(const uniproc_process* p)
{ return p->_proc_hdl == NULL; } { return p->_proc_hdl == NULL; }
void uniproc_await_any_processes(const uniproc_process* p, const size_t num_processes) void uniproc_await_any_processes(const uniproc_process* p, const size_t num_processes)

View File

@@ -6,6 +6,8 @@
uniproc_process uniproc_create_process(const char* cmd, const size_t num_args, const char** argv) uniproc_process uniproc_create_process(const char* cmd, const size_t num_args, const char** argv)
{ {
uniproc_process p;
// Create pipes // Create pipes
HANDLE child_in; HANDLE child_in;
HANDLE in; HANDLE in;
@@ -22,14 +24,14 @@ uniproc_process uniproc_create_process(const char* cmd, const size_t num_args, c
// Actually create the pipes // Actually create the pipes
if (!CreatePipe(&out, &child_out, &pipe_attribs, 0)) if (!CreatePipe(&out, &child_out, &pipe_attribs, 0))
{ {
uniproc_nullify_processes(p, 1); uniproc_nullify_processes(&p, 1);
return p; return p;
} }
if (!CreatePipe(&err, &child_err, &pipe_attribs, 0)) if (!CreatePipe(&err, &child_err, &pipe_attribs, 0))
{ {
CloseHandle(child_out); CloseHandle(child_out);
CloseHandle(out); CloseHandle(out);
uniproc_nullify_processes(p, 1); uniproc_nullify_processes(&p, 1);
return p; return p;
} }
if (!CreatePipe(&child_in, &in, &pipe_attribs, 0)) if (!CreatePipe(&child_in, &in, &pipe_attribs, 0))
@@ -38,7 +40,7 @@ uniproc_process uniproc_create_process(const char* cmd, const size_t num_args, c
CloseHandle(out); CloseHandle(out);
CloseHandle(child_err); CloseHandle(child_err);
CloseHandle(err); CloseHandle(err);
uniproc_nullify_processes(p, 1); uniproc_nullify_processes(&p, 1);
return p; return p;
} }
@@ -51,7 +53,7 @@ uniproc_process uniproc_create_process(const char* cmd, const size_t num_args, c
CloseHandle(out); CloseHandle(out);
CloseHandle(child_err); CloseHandle(child_err);
CloseHandle(err); CloseHandle(err);
uniproc_nullify_processes(p, 1); uniproc_nullify_processes(&p, 1);
return p; return p;
} }
if (!SetHandleInformation(err, HANDLE_FLAG_INHERIT, 0)) if (!SetHandleInformation(err, HANDLE_FLAG_INHERIT, 0))
@@ -62,7 +64,7 @@ uniproc_process uniproc_create_process(const char* cmd, const size_t num_args, c
CloseHandle(out); CloseHandle(out);
CloseHandle(child_err); CloseHandle(child_err);
CloseHandle(err); CloseHandle(err);
uniproc_nullify_processes(p, 1); uniproc_nullify_processes(&p, 1);
return p; return p;
} }
if (!SetHandleInformation(in, HANDLE_FLAG_INHERIT, 0)) if (!SetHandleInformation(in, HANDLE_FLAG_INHERIT, 0))
@@ -73,12 +75,10 @@ uniproc_process uniproc_create_process(const char* cmd, const size_t num_args, c
CloseHandle(out); CloseHandle(out);
CloseHandle(child_err); CloseHandle(child_err);
CloseHandle(err); CloseHandle(err);
uniproc_nullify_processes(p, 1); uniproc_nullify_processes(&p, 1);
return p; return p;
} }
// Create child process
uniproc_process p;
// Create p_cmd by appending all argv's to cmd // Create p_cmd by appending all argv's to cmd
size_t x = strlen(cmd); size_t x = strlen(cmd);
@@ -131,7 +131,7 @@ uniproc_process uniproc_create_process(const char* cmd, const size_t num_args, c
CloseHandle(out); CloseHandle(out);
CloseHandle(child_err); CloseHandle(child_err);
CloseHandle(err); CloseHandle(err);
uniproc_nullify_processes(p, 1); uniproc_nullify_processes(&p, 1);
return p; return p;
} }
@@ -148,7 +148,7 @@ uniproc_process uniproc_create_process(const char* cmd, const size_t num_args, c
return p; return p;
} }
void uniproc_await_processes(uniproc_process* p, int* return_codes, size_t num_processes) void uniproc_await_processes(const uniproc_process* p, int* return_codes, const size_t num_processes)
{ {
size_t num_valid_handles = 0; size_t num_valid_handles = 0;
HANDLE* h = (HANDLE*)malloc(num_processes*sizeof(HANDLE)); HANDLE* h = (HANDLE*)malloc(num_processes*sizeof(HANDLE));
@@ -158,7 +158,7 @@ void uniproc_await_processes(uniproc_process* p, int* return_codes, size_t num_p
h[i] = (HANDLE)p[i]._proc_hdl; h[i] = (HANDLE)p[i]._proc_hdl;
num_valid_handles++; num_valid_handles++;
} }
if (num_valid_handles == 0) return;
WaitForMultipleObjects(num_valid_handles, h, 1, INFINITE); WaitForMultipleObjects(num_valid_handles, h, 1, INFINITE);
free(h); free(h);
@@ -181,7 +181,7 @@ void uniproc_close_process(uniproc_process* p)
uniproc_nullify_processes(p, 1); uniproc_nullify_processes(p, 1);
} }
bool uniproc_are_processes_finished(const uniproc_process* p, const size_t num_processes) int uniproc_are_processes_finished(const uniproc_process* p, const size_t num_processes)
{ {
HANDLE* h = (HANDLE*)malloc(num_processes*sizeof(HANDLE)); HANDLE* h = (HANDLE*)malloc(num_processes*sizeof(HANDLE));
size_t num_valid_handles = 0; size_t num_valid_handles = 0;
@@ -191,7 +191,8 @@ bool uniproc_are_processes_finished(const uniproc_process* p, const size_t num_p
h[i] = (HANDLE)p[i]._proc_hdl; h[i] = (HANDLE)p[i]._proc_hdl;
num_valid_handles++; num_valid_handles++;
} }
DWORD ret = WaitForMultipleObjects(num_valid_handles, h, true, 0); if (num_valid_handles == 0) return 1;
DWORD ret = WaitForMultipleObjects(num_valid_handles, h, 1, 0);
free(h); free(h);
return ret >= WAIT_OBJECT_0 && ret < WAIT_OBJECT_0 + num_valid_handles; return ret >= WAIT_OBJECT_0 && ret < WAIT_OBJECT_0 + num_valid_handles;
} }
@@ -199,7 +200,7 @@ bool uniproc_are_processes_finished(const uniproc_process* p, const size_t num_p
void uniproc_nullify_processes(uniproc_process* p, const size_t num_processes) void uniproc_nullify_processes(uniproc_process* p, const size_t num_processes)
{ memset(p, 0, num_processes * sizeof(uniproc_process)); } { memset(p, 0, num_processes * sizeof(uniproc_process)); }
void uniproc_is_process_null(const uniproc_process* p) int uniproc_is_process_null(const uniproc_process* p)
{ return p->_proc_hdl == NULL; } { return p->_proc_hdl == NULL; }
void uniproc_await_any_processes(const uniproc_process* p, const size_t num_processes) void uniproc_await_any_processes(const uniproc_process* p, const size_t num_processes)
@@ -212,7 +213,8 @@ void uniproc_await_any_processes(const uniproc_process* p, const size_t num_proc
h[i] = (HANDLE)p[i]._proc_hdl; h[i] = (HANDLE)p[i]._proc_hdl;
num_valid_handles++; num_valid_handles++;
} }
WaitForMultipleObjects(num_valid_handles, h, false, INFINITE); if (num_valid_handles == 0) return;
WaitForMultipleObjects(num_valid_handles, h, 0, INFINITE);
free(h); free(h);
} }