From 1a9fcf925ed1aac7c5ac4786c7c48388ffdcf926 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 12:53:12 +0100 Subject: [PATCH] =?UTF-8?q?Debarasse=20de=20popen=20en=20gerant=20la=20red?= =?UTF-8?q?irection=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 | 101 ++++++++++++------ 1 file changed, 66 insertions(+), 35 deletions(-) diff --git a/test~coding~readingCppPrograms.fr/docker-compile-and-run.cpp b/test~coding~readingCppPrograms.fr/docker-compile-and-run.cpp index bc0fde9..fe588f6 100644 --- a/test~coding~readingCppPrograms.fr/docker-compile-and-run.cpp +++ b/test~coding~readingCppPrograms.fr/docker-compile-and-run.cpp @@ -33,18 +33,26 @@ int system(string command) { std::system(command.c_str()); } -int exec(string cmd, const vector<string> args, const string in, const string out, const string err) { - cerr << "Running (exec): "+cmd; +void report(string comment, string cmd, vector<string> args) { + cerr << comment; + cerr << cmd; for (auto arg: args) cerr << " " << arg; cerr << endl; +} + +int cpp_exec(string cmd, const vector<string> args) { vector<const char*> argv; argv.push_back(cmd.c_str()); for ( auto &s: args ) argv.push_back(s.c_str()); argv.push_back((char *) 0); - const vector<const char *> argv2(argv.begin(), argv.end()); + return execv(cmd.c_str(), (char * const*)argv.data()); +} + +int exec(string cmd, const vector<string> args, const string in, const string out, const string err) { + report("exec: ", cmd, args); // Taken from man waitpid int status; @@ -60,26 +68,20 @@ int exec(string cmd, const vector<string> args, const string in, const string ou 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; + if ( out != "" ) { + FILE* f = fopen(in.c_str(), "w"); + dup2(fileno(f), STDOUT_FILENO); + fclose(f); } - } while (!WIFEXITED(status) && !WIFSIGNALED(status)); + cpp_exec(cmd, args); + perror("exec"); + exit(EXIT_FAILURE); + } + w = waitpid(cpid, &status, 0); + if (w == -1) { + perror("waitpid"); + exit(EXIT_FAILURE); + } return EXIT_SUCCESS; } @@ -87,22 +89,49 @@ int exec(string cmd, const vector<string> args) { return exec(cmd, args, "", "", ""); } -std::string pexec(const string cmd) { - cerr << "Running (pexec): "+cmd << endl; - FILE* pipe = popen(cmd.c_str(), "r"); - if (!pipe) return "ERROR"; +std::string pexec(const string cmd, vector<string> args) { + report("pexec: ", cmd, args); + + int pipefd[2]; + pid_t cpid; + + if (pipe(pipefd) == -1) { + perror("pipe"); + exit(EXIT_FAILURE); + } + + cpid = fork(); + if (cpid == -1) { + perror("fork"); + exit(EXIT_FAILURE); + } + + if (cpid == 0) { /* Child writes to pipe */ + close(pipefd[0]); /* Close unused read end */ + dup2(pipefd[1], STDOUT_FILENO); + cpp_exec(cmd, args); + perror("exec"); + exit(EXIT_FAILURE); + } + + close(pipefd[1]); /* Close unused write end */ + char buffer[128]; std::string result = ""; - while (!feof(pipe)) { - if (fgets(buffer, 128, pipe) != NULL) - result += buffer; + int n; + while ((n = read(pipefd[0], buffer, sizeof(buffer))) > 0) { + buffer[n] = 0; + result += buffer; } - pclose(pipe); + wait(NULL); /* Wait for child */ return result; } -string docker_run(string container, string command) { - string ID = pexec(docker + " run -d "+container+" "+command); +string docker_run(string container, string cmd, vector<string> args) { + vector<string> docker_args = {"run", "-d", container, cmd}; + for (auto arg: args) + docker_args.push_back(arg); + string ID = pexec(docker, docker_args); // see http://stackoverflow.com/questions/216823/whats-the-best-way-to-trim-stdstring ID.erase(ID.find_last_not_of(" \n\r\t")+1); return ID; @@ -124,10 +153,12 @@ void docker_cp(string docker_id, string source, string target) { } void docker_rm(string docker_id) { - exec(docker, {"rm", "-f", docker_id}); + exec(docker, {"rm", "-f", docker_id}, "", "/dev/null", ""); } int main(int argc, char **argv) { + //cout << pexec("/usr/bin/id", {}) << "|" << endl; + //printf("egid: %d\n", getegid()); //exec("/usr/bin/id", {}); @@ -140,8 +171,8 @@ int main(int argc, char **argv) { string program=argv[1]; - string docker_id = docker_run("crosbymichael/build-essential", "sleep 1000"); - // cout << "docker_id: " << docker_id << endl; + string docker_id = docker_run("crosbymichael/build-essential", "sleep", {"1000"}); + cout << "docker_id: " << docker_id << endl; docker_cp(docker_id, bin_dir+compile_and_run, compile_and_run); docker_cp(docker_id, program, program); docker_exec(docker_id, { "chmod", "700", compile_and_run }); -- GitLab