diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2013-07-26 16:21:31 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2013-07-26 16:21:31 +0000 |
commit | 105a4096795e4c974bc1018b3a665c18423d790f (patch) | |
tree | f34878deb94caff090e25687b30a4a50b481923f /lib/Support | |
parent | 71b1c76cdf349b1cc838336a62374ca8e06db5a0 (diff) | |
download | external_llvm-105a4096795e4c974bc1018b3a665c18423d790f.zip external_llvm-105a4096795e4c974bc1018b3a665c18423d790f.tar.gz external_llvm-105a4096795e4c974bc1018b3a665c18423d790f.tar.bz2 |
Extend the lifetime of the strings passed to posix_spawn_file_actions_addopen.
Thanks to Hal Finkel for finding the bug and for the initial patch.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@187208 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Support')
-rw-r--r-- | lib/Support/Unix/Program.inc | 28 |
1 files changed, 21 insertions, 7 deletions
diff --git a/lib/Support/Unix/Program.inc b/lib/Support/Unix/Program.inc index 8676642..0605d53 100644 --- a/lib/Support/Unix/Program.inc +++ b/lib/Support/Unix/Program.inc @@ -122,19 +122,19 @@ static bool RedirectIO(const StringRef *Path, int FD, std::string* ErrMsg) { } #ifdef HAVE_POSIX_SPAWN -static bool RedirectIO_PS(const StringRef *Path, int FD, std::string *ErrMsg, +static bool RedirectIO_PS(const std::string *Path, int FD, std::string *ErrMsg, posix_spawn_file_actions_t *FileActions) { if (Path == 0) // Noop return false; - std::string File; + const char *File; if (Path->empty()) // Redirect empty paths to /dev/null File = "/dev/null"; else - File = *Path; + File = Path->c_str(); if (int Err = posix_spawn_file_actions_addopen( - FileActions, FD, File.c_str(), + FileActions, FD, File, FD == 0 ? O_RDONLY : O_WRONLY | O_CREAT, 0666)) return MakeErrMsg(ErrMsg, "Cannot dup2", Err); return false; @@ -185,18 +185,32 @@ static bool Execute(void **Data, StringRef Program, const char **args, posix_spawn_file_actions_t FileActionsStore; posix_spawn_file_actions_t *FileActions = 0; + // If we call posix_spawn_file_actions_addopen we have to make sure the + // c strings we pass to it stay alive until the call to posix_spaw, + // so we copy any StringRefs into this variable. + std::string RedirectsStorage[3]; + if (redirects) { + std::string *RedirectsStr[3] = {0, 0, 0}; + for (int I = 0; I < 3; ++I) { + if (redirects[I]) { + RedirectsStorage[I] = *redirects[I]; + RedirectsStr[I] = &RedirectsStorage[I]; + } + } + FileActions = &FileActionsStore; posix_spawn_file_actions_init(FileActions); // Redirect stdin/stdout. - if (RedirectIO_PS(redirects[0], 0, ErrMsg, FileActions) || - RedirectIO_PS(redirects[1], 1, ErrMsg, FileActions)) + if (RedirectIO_PS(RedirectsStr[0], 0, ErrMsg, FileActions) || + RedirectIO_PS(RedirectsStr[1], 1, ErrMsg, FileActions)) return false; if (redirects[1] == 0 || redirects[2] == 0 || *redirects[1] != *redirects[2]) { // Just redirect stderr - if (RedirectIO_PS(redirects[2], 2, ErrMsg, FileActions)) return false; + if (RedirectIO_PS(RedirectsStr[2], 2, ErrMsg, FileActions)) + return false; } else { // If stdout and stderr should go to the same place, redirect stderr // to the FD already open for stdout. |