Implemented windows implementation of uniproc
This commit is contained in:
13
.gitignore
vendored
Normal file
13
.gitignore
vendored
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
################################################################################
|
||||||
|
# This .gitignore file was automatically created by Microsoft(R) Visual Studio.
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
/.vs/uniproc/FileContentIndex
|
||||||
|
/.vs/uniproc/v17/ipch/AutoPCH
|
||||||
|
/.vs
|
||||||
|
/CppProperties.json
|
||||||
|
/include/tmp.cpp
|
||||||
|
/test.exe
|
||||||
|
/test.ilk
|
||||||
|
/test.pdb
|
||||||
|
/src/main.c
|
||||||
18
include/uniproc.h
Normal file
18
include/uniproc.h
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <Windows.h>
|
||||||
|
typedef struct {
|
||||||
|
FILE* in;
|
||||||
|
FILE* out;
|
||||||
|
FILE* err;
|
||||||
|
|
||||||
|
// OS-dependent handle to the process
|
||||||
|
uint32_t _proc_hdl;
|
||||||
|
|
||||||
|
} uniproc_process;
|
||||||
|
|
||||||
|
uniproc_process uniproc_create_process(const char* cmd);
|
||||||
|
void uniproc_await_processes(uniproc_process* p, int* return_codes, size_t num_processes);
|
||||||
|
void uniproc_close_process(uniproc_process* p);
|
||||||
110
src/uniproc_win64.c
Normal file
110
src/uniproc_win64.c
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
|
#include "uniproc.h"
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <io.h>
|
||||||
|
|
||||||
|
uniproc_process uniproc_create_process(const char* cmd)
|
||||||
|
{
|
||||||
|
// Create pipes
|
||||||
|
HANDLE child_in;
|
||||||
|
HANDLE in;
|
||||||
|
HANDLE child_out;
|
||||||
|
HANDLE out;
|
||||||
|
HANDLE child_err;
|
||||||
|
HANDLE err;
|
||||||
|
|
||||||
|
SECURITY_ATTRIBUTES pipe_attribs;
|
||||||
|
pipe_attribs.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||||
|
pipe_attribs.bInheritHandle = 1;
|
||||||
|
pipe_attribs.lpSecurityDescriptor = NULL;
|
||||||
|
|
||||||
|
// Actually create the pipes
|
||||||
|
if (!CreatePipe(&out, &child_out, &pipe_attribs, 0))
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
if (!CreatePipe(&err, &child_err, &pipe_attribs, 0))
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
if (!CreatePipe(&child_in, &in, &pipe_attribs, 0))
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
|
// Unset inherrit flags for the pipes
|
||||||
|
if (!SetHandleInformation(out, HANDLE_FLAG_INHERIT, 0))
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
if (!SetHandleInformation(err, HANDLE_FLAG_INHERIT, 0))
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
if (!SetHandleInformation(in, HANDLE_FLAG_INHERIT, 0))
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
|
// Create child process
|
||||||
|
uniproc_process p;
|
||||||
|
|
||||||
|
size_t cmd_len = strlen(cmd);
|
||||||
|
char* p_cmd = malloc((cmd_len+1) * sizeof(char));
|
||||||
|
memcpy(p_cmd, cmd, cmd_len * sizeof(char));
|
||||||
|
p_cmd[cmd_len] = '\0';
|
||||||
|
|
||||||
|
PROCESS_INFORMATION p_info;
|
||||||
|
STARTUPINFOA p_startup;
|
||||||
|
memset(&p_info, 0, sizeof(PROCESS_INFORMATION));
|
||||||
|
memset(&p_startup, 0, sizeof(STARTUPINFOA));
|
||||||
|
|
||||||
|
p_startup.cb = sizeof(STARTUPINFOA);
|
||||||
|
p_startup.dwFlags |= STARTF_USESTDHANDLES;
|
||||||
|
p_startup.hStdInput = child_in;
|
||||||
|
p_startup.hStdOutput = child_out;
|
||||||
|
p_startup.hStdError = child_err;
|
||||||
|
|
||||||
|
int is_ok = CreateProcessA(
|
||||||
|
NULL,// Application name
|
||||||
|
p_cmd, // Command to execute
|
||||||
|
NULL,// Security attributes
|
||||||
|
NULL,// Primary thread security
|
||||||
|
1, // Inherrit handles
|
||||||
|
0, // Creation flags
|
||||||
|
NULL,// Environment (use parent's)
|
||||||
|
NULL,// Current directory (use parent's)
|
||||||
|
&p_startup,
|
||||||
|
&p_info
|
||||||
|
);
|
||||||
|
free(p_cmd);
|
||||||
|
|
||||||
|
if (!is_ok)
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
|
p.err = _fdopen(_open_osfhandle((intptr_t)err, _O_RDONLY), "r");
|
||||||
|
p.out = _fdopen(_open_osfhandle((intptr_t)out, _O_RDONLY), "r");
|
||||||
|
p.in = _fdopen(_open_osfhandle( (intptr_t)in, _O_WRONLY), "w");
|
||||||
|
p._proc_hdl = (uint32_t)p_info.hProcess;
|
||||||
|
|
||||||
|
CloseHandle(child_in);
|
||||||
|
CloseHandle(child_out);
|
||||||
|
CloseHandle(child_err);
|
||||||
|
CloseHandle(p_info.hThread);
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
void uniproc_await_processes(uniproc_process* p, int* return_codes, size_t num_processes)
|
||||||
|
{
|
||||||
|
HANDLE* h = (HANDLE*)malloc(num_processes*sizeof(HANDLE));
|
||||||
|
for (size_t i = 0; i < num_processes; ++i)
|
||||||
|
h[i] = (HANDLE)p[i]._proc_hdl;
|
||||||
|
|
||||||
|
WaitForMultipleObjects(num_processes, h, 1, INFINITE);
|
||||||
|
free(h);
|
||||||
|
|
||||||
|
if (return_codes == NULL) return;
|
||||||
|
for (size_t i = 0; i < num_processes; ++i)
|
||||||
|
GetExitCodeProcess((HANDLE)p[i]._proc_hdl, (LPDWORD)(return_codes+i));
|
||||||
|
}
|
||||||
|
|
||||||
|
void uniproc_close_process(uniproc_process* p)
|
||||||
|
{
|
||||||
|
fclose(p->in);
|
||||||
|
fclose(p->out);
|
||||||
|
fclose(p->err);
|
||||||
|
|
||||||
|
CloseHandle((HANDLE)p->_proc_hdl);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user