]> git.localhorst.tv Git - blank.git/blobdiff - src/app/proc.cpp
test for invoking with unknown argument
[blank.git] / src / app / proc.cpp
index 8809856c2a8c3640f45c23e3737e3a79702b0d5e..f30c0cb2dcab508be7ee480fb63955f8fef721ff 100644 (file)
@@ -1,14 +1,16 @@
 #include "Process.hpp"
 
-#ifdef __WIN32
-#  error "TODO: windows implementation of Process"
+#ifdef _WIN32
+#  include <tchar.h>
+#  include <windows.h>
 #else
-#  include <cstdio>
 #  include <fcntl.h>
+#  include <signal.h>
 #  include <unistd.h>
 #  include <sys/wait.h>
 #endif
 
+#include <cstdio>
 #include <stdexcept>
 
 using namespace std;
@@ -20,17 +22,18 @@ struct Process::Impl {
 
        Impl(
                const string &path_in,
-               const vector<string> &args,
-               const vector<string> &env);
+               const Arguments &args,
+               const Environment &env);
        ~Impl();
 
        size_t WriteIn(const void *buffer, size_t max_len);
        size_t ReadOut(void *buffer, size_t max_len);
        size_t ReadErr(void *buffer, size_t max_len);
 
+       void Terminate();
        int Join();
 
-#ifdef __WIN32
+#ifdef _WIN32
        PROCESS_INFORMATION pi;
        HANDLE fd_in[2];
        HANDLE fd_out[2];
@@ -47,8 +50,8 @@ struct Process::Impl {
 
 Process::Process(
        const string &path,
-       const vector<string> &args,
-       const vector<string> &env)
+       const Arguments &args,
+       const Environment &env)
 : impl(new Impl(path, args, env))
 , joined(false)
 , status(0) {
@@ -72,6 +75,12 @@ size_t Process::ReadErr(void *buffer, size_t max_len) {
        return impl->ReadErr(buffer, max_len);
 }
 
+void Process::Terminate() {
+       if (!joined) {
+               impl->Terminate();
+       }
+}
+
 int Process::Join() {
        if (joined) {
                return status;
@@ -85,8 +94,8 @@ int Process::Join() {
 
 Process::Impl::Impl(
        const string &path_in,
-       const vector<string> &args,
-       const vector<string> &env
+       const Arguments &args,
+       const Environment &env
 ) {
        const char *path = path_in.c_str();
        char *envp[env.size() + 1];
@@ -94,7 +103,7 @@ Process::Impl::Impl(
                envp[i] = const_cast<char *>(env[i].c_str());
        }
        envp[env.size()] = nullptr;
-#ifdef __WIN32
+#ifdef _WIN32
        string cmdline;
        for (const auto &arg : args) {
                cmdline += '"';
@@ -207,7 +216,7 @@ Process::Impl::~Impl() {
 }
 
 size_t Process::Impl::WriteIn(const void *buffer, size_t max_len) {
-#ifdef __WIN32
+#ifdef _WIN32
        DWORD written;
        if (!WriteFile(fd_in[1], buffer, max_len, &written, nullptr)) {
                throw runtime_error("failed to write to child process' input stream");
@@ -227,7 +236,7 @@ size_t Process::Impl::WriteIn(const void *buffer, size_t max_len) {
 }
 
 size_t Process::Impl::ReadOut(void *buffer, size_t max_len) {
-#ifdef __WIN32
+#ifdef _WIN32
        DWORD ret;
        if (!ReadFile(fd_out[0], buffer, max_len, &ret, nullptr)) {
                throw runtime_error("failed to read from child process' output stream");
@@ -247,7 +256,7 @@ size_t Process::Impl::ReadOut(void *buffer, size_t max_len) {
 }
 
 size_t Process::Impl::ReadErr(void *buffer, size_t max_len) {
-#ifdef __WIN32
+#ifdef _WIN32
        DWORD ret;
        if (!ReadFile(fd_err[0], buffer, max_len, &ret, nullptr)) {
                throw runtime_error("failed to read from child process' error stream");
@@ -266,8 +275,18 @@ size_t Process::Impl::ReadErr(void *buffer, size_t max_len) {
 #endif
 }
 
+void Process::Impl::Terminate() {
+#ifdef _WIN32
+       if (!TerminateProcess(pi.hProcess, -1)) {
+#else
+       if (kill(pid, SIGTERM) == -1) {
+#endif
+               throw runtime_error("failed to terminate child process");
+       }
+}
+
 int Process::Impl::Join() {
-#ifdef __WIN32
+#ifdef _WIN32
        CloseHandle(fd_in[1]);
        CloseHandle(fd_out[0]);
        CloseHandle(fd_err[0]);