#include "errcode.h"
#include "util.h"
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <windows.h>
int run(const char *file, char *const argv[])
{
int errcode;
int i;
size_t size, len;
char *args;
STARTUPINFO si;
PROCESS_INFORMATION pi;
DWORD exit_code;
DWORD dwret;
BOOL bret;
errcode = 0;
if (bug_on(!file)) {
errcode = -err_internal;
goto out;
}
if (bug_on(!argv)) {
errcode = -err_internal;
goto out;
}
size = 0;
for (i = 0; argv[i]; ++i) {
len = strnlen(argv[i], FILENAME_MAX);
if (FILENAME_MAX <= len) {
errcode = -err_internal;
goto out;
}
size += len + 3;
}
args = calloc(size, 1);
if (!args)
return -err_no_mem;
size = 0;
for (i = 0; argv[i]; ++i) {
len = strnlen(argv[i], FILENAME_MAX);
if (FILENAME_MAX <= len) {
errcode = -err_internal;
goto out;
}
args[size++] = '"';
memcpy(args + size, argv[i], len);
size += len;
args[size++] = '"';
args[size++] = ' ';
}
args[--size] = '\0';
memset(&pi, 0, sizeof(pi));
memset(&si, 0, sizeof(si));
si.cb = sizeof(si);
bret = CreateProcess(NULL, args,
NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
if (!bret) {
errcode = -err_other;
goto out_args;
}
dwret = WaitForSingleObject(pi.hProcess, INFINITE);
if (dwret == WAIT_FAILED) {
errcode = -err_other;
goto out_handles;
}
bret = GetExitCodeProcess(pi.hProcess, &exit_code);
if (!bret) {
errcode = -err_other;
goto out_handles;
}
if (exit_code != 0)
errcode = -err_run;
out_handles:
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
out_args:
free(args);
out:
return errcode;
}