diff options
author | Shinichiro Hamaji <shinichiro.hamaji@gmail.com> | 2016-02-18 17:20:08 +0900 |
---|---|---|
committer | Shinichiro Hamaji <shinichiro.hamaji@gmail.com> | 2016-02-18 17:21:26 +0900 |
commit | 348a960f31d42c63ec6fff68a27c5b161b59a89f (patch) | |
tree | 867a4d5127635d88c9e9399ea7d774dd9d6f2340 | |
parent | 3deff5bf54db9c5d36b775beffadbae33381d1b1 (diff) | |
download | android_build_kati-348a960f31d42c63ec6fff68a27c5b161b59a89f.tar.gz android_build_kati-348a960f31d42c63ec6fff68a27c5b161b59a89f.tar.bz2 android_build_kati-348a960f31d42c63ec6fff68a27c5b161b59a89f.zip |
[C++] Handle multi-word SHELL in $(shell)
-rw-r--r-- | fileutil.cc | 11 | ||||
-rw-r--r-- | ninja.cc | 30 | ||||
-rw-r--r-- | strutil.cc | 30 | ||||
-rw-r--r-- | strutil.h | 2 | ||||
-rw-r--r-- | testcase/shell_var_with_args.mk | 7 |
5 files changed, 47 insertions, 33 deletions
diff --git a/fileutil.cc b/fileutil.cc index 42e81a2..a2a0d09 100644 --- a/fileutil.cc +++ b/fileutil.cc @@ -32,6 +32,7 @@ #include <unordered_map> #include "log.h" +#include "strutil.h" bool Exists(StringPiece filename) { CHECK(filename.size() < PATH_MAX); @@ -62,6 +63,13 @@ double GetTimestamp(StringPiece filename) { int RunCommand(const string& shell, const string& cmd, RedirectStderr redirect_stderr, string* s) { + string cmd_escaped = cmd; + EscapeShell(&cmd_escaped); + string cmd_with_shell = shell + " -c \"" + cmd_escaped + "\""; + const char* argv[] = { + "/bin/sh", "-c", cmd_with_shell.c_str(), NULL + }; + int pipefd[2]; if (pipe(pipefd) != 0) PERROR("pipe failed"); @@ -106,9 +114,6 @@ int RunCommand(const string& shell, const string& cmd, PERROR("dup2 failed"); close(pipefd[1]); - const char* argv[] = { - shell.c_str(), "-c", cmd.c_str(), NULL - }; execvp(argv[0], const_cast<char**>(argv)); PLOG("execvp for %s failed", argv[0]); kill(getppid(), SIGTERM); @@ -543,36 +543,6 @@ class NinjaGenerator { return r; } - void EscapeShell(string* s) const { - if (s->find_first_of("$`\\\"") == string::npos) - return; - string r; - bool last_dollar = false; - for (char c : *s) { - switch (c) { - case '$': - if (last_dollar) { - r += c; - last_dollar = false; - } else { - r += '\\'; - r += c; - last_dollar = true; - } - break; - case '`': - case '"': - case '\\': - r += '\\'; - // fall through. - default: - r += c; - last_dollar = false; - } - } - s->swap(r); - } - void EmitBuild(NinjaNode* nn, const string& rule_name, bool use_local_pool, ostringstream* o) { const DepNode* node = nn->node; @@ -521,3 +521,33 @@ string EchoEscape(const string str) { } return buf; } + +void EscapeShell(string* s) { + if (s->find_first_of("$`\\\"") == string::npos) + return; + string r; + bool last_dollar = false; + for (char c : *s) { + switch (c) { + case '$': + if (last_dollar) { + r += c; + last_dollar = false; + } else { + r += '\\'; + r += c; + last_dollar = true; + } + break; + case '`': + case '"': + case '\\': + r += '\\'; + // fall through. + default: + r += c; + last_dollar = false; + } + } + s->swap(r); +} @@ -142,4 +142,6 @@ string ConcatDir(StringPiece b, StringPiece n); string EchoEscape(const string str); +void EscapeShell(string* s); + #endif // STRUTIL_H_ diff --git a/testcase/shell_var_with_args.mk b/testcase/shell_var_with_args.mk new file mode 100644 index 0000000..fd391f3 --- /dev/null +++ b/testcase/shell_var_with_args.mk @@ -0,0 +1,7 @@ +# TODO(go): Fix + +SHELL := PS4="cmd: " /bin/bash -x +$(info $(shell echo foo)) + +test: + @echo baz |