From ac63271d5c51b95a00cb104e187d00d35f9d5e0b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nicolas=20M=2E=20Thi=C3=A9ry?= <nthiery@users.sf.net>
Date: Mon, 23 Nov 2015 11:29:56 +0100
Subject: [PATCH] =?UTF-8?q?Debarasse=20de=20docker=5Fold=5Fexec=20en=20ger?=
 =?UTF-8?q?ant=20la=20redirection=20=C3=A0=20la=20main?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../docker-compile-and-run.cpp                | 58 ++++++++++++++-----
 1 file changed, 43 insertions(+), 15 deletions(-)

diff --git a/test~coding~readingCppPrograms.fr/docker-compile-and-run.cpp b/test~coding~readingCppPrograms.fr/docker-compile-and-run.cpp
index 2ecce18..b0584b8 100644
--- a/test~coding~readingCppPrograms.fr/docker-compile-and-run.cpp
+++ b/test~coding~readingCppPrograms.fr/docker-compile-and-run.cpp
@@ -4,9 +4,10 @@
 #include <sstream>
 using namespace std;
 
-#include <unistd.h>
 #include <sys/types.h>
-
+#include <sys/wait.h>
+#include <unistd.h>
+#include <stdio.h>
 
 /**
  * TODO:
@@ -32,9 +33,7 @@ int system(string command) {
     std::system(command.c_str());
 }
 
-#include <stdio.h>
-
-void exec(string cmd, const vector<string> args) {
+int exec(string cmd, const vector<string> args, const string in, const string out, const string err) {
     cerr << "Running (exec): "+cmd;
     for (auto arg: args)
         cerr << " " << arg;
@@ -47,10 +46,45 @@ void exec(string cmd, const vector<string> args) {
 
     const vector<const char *> argv2(argv.begin(), argv.end());
 
-    int pid = fork();
-    if (pid==0) {
+    // Taken from man waitpid
+    int status;
+    pid_t w;
+    pid_t cpid = fork();
+    if (cpid == -1) {
+        perror("fork");
+        exit(EXIT_FAILURE);
+    }
+    if (cpid == 0) {            /* Code executed by child */
+        if ( in != "" ) {
+            FILE* f = fopen(in.c_str(), "r");
+            dup2(fileno(f), STDIN_FILENO);
+            fclose(f);
+        }
         execv(cmd.c_str(), (char * const*)argv.data());
     }
+    do {
+        // TODO: this could be simplified for our purposes
+        w = waitpid(cpid, &status, WUNTRACED | WCONTINUED);
+        if (w == -1) {
+            perror("waitpid");
+            exit(EXIT_FAILURE);
+        }
+
+        if (WIFEXITED(status)) {
+            cerr << "exited, status=" << WEXITSTATUS(status) << endl;
+        } else if (WIFSIGNALED(status)) {
+            cerr << "killed by signal=" << WTERMSIG(status) << endl;
+        } else if (WIFSTOPPED(status)) {
+            cerr << "stopped by signal " << WSTOPSIG(status) << endl;
+        } else if (WIFCONTINUED(status)) {
+            cerr << "continued" << endl;
+        }
+    } while (!WIFEXITED(status) && !WIFSIGNALED(status));
+    return EXIT_SUCCESS;
+}
+
+int exec(string cmd, const vector<string> args) {
+    return exec(cmd, args, "", "", "");
 }
 
 std::string pexec(const string cmd) {
@@ -74,12 +108,6 @@ string docker_run(string container, string command) {
     return ID;
 }
 
-void docker_oldexec(string docker_id, string command) {
-    string cmd = docker+" exec -i "+ docker_id+ " "+ command;
-    cerr << "Running (docker_oldexec): "+cmd << endl;
-    system(cmd);
-}
-
 void docker_exec(string docker_id, vector<string> args) {
     vector<string> docker_args = {"exec", "-i", docker_id};
     for (auto arg: args)
@@ -91,7 +119,8 @@ void docker_exec(string docker_id, vector<string> args) {
 void docker_cp(string docker_id, string source, string target) {
     // See http://stackoverflow.com/questions/22907231/copying-files-from-host-to-docker-container
     // Better replace with 'docker cp' of docker 1.8
-    docker_oldexec(docker_id, " /bin/bash -c 'cat > "+target+"' < "+source);
+    exec(docker, {"exec", "-i", docker_id, "/bin/bash",  "-c", "cat > "+target,},
+         source, "", "");
 }
 
 void docker_rm(string docker_id) {
@@ -117,7 +146,6 @@ int main(int argc, char **argv) {
     docker_cp(docker_id, program, program);
     docker_exec(docker_id, { "chmod", "700", compile_and_run });
     docker_exec(docker_id, { "./"+compile_and_run, program});
-    //docker_oldexec(docker_id, "./"+compile_and_run+" "+program);
     docker_rm(docker_id);
     cout.flush();
     return 0;
-- 
GitLab