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