From: Rafael Espindola Date: Fri, 26 Jul 2013 16:21:31 +0000 (+0000) Subject: Extend the lifetime of the strings passed to posix_spawn_file_actions_addopen. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=105a4096795e4c974bc1018b3a665c18423d790f;p=oota-llvm.git 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 --- diff --git a/lib/Support/Unix/Program.inc b/lib/Support/Unix/Program.inc index 8676642b74a..0605d531ca5 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.