//===----------------------------------------------------------------------===//
#include <llvm/Config/config.h>
+#include "llvm/Support/FileSystem.h"
#include "Unix.h"
#if HAVE_SYS_STAT_H
#include <sys/stat.h>
#ifdef HAVE_POSIX_SPAWN
static bool RedirectIO_PS(const Path *Path, int FD, std::string *ErrMsg,
- posix_spawn_file_actions_t &FileActions) {
+ posix_spawn_file_actions_t *FileActions) {
if (Path == 0) // Noop
return false;
const char *File;
else
File = Path->c_str();
- if (int Err = posix_spawn_file_actions_addopen(&FileActions, FD,
+ if (int Err = posix_spawn_file_actions_addopen(FileActions, FD,
File, FD == 0 ? O_RDONLY : O_WRONLY|O_CREAT, 0666))
return MakeErrMsg(ErrMsg, "Cannot dup2", Err);
return false;
// posix_spawn. It is more efficient than fork/exec.
#ifdef HAVE_POSIX_SPAWN
if (memoryLimit == 0) {
- posix_spawn_file_actions_t FileActions;
- posix_spawn_file_actions_init(&FileActions);
+ posix_spawn_file_actions_t FileActionsStore;
+ posix_spawn_file_actions_t *FileActions = 0;
if (redirects) {
+ 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))
} else {
// If stdout and stderr should go to the same place, redirect stderr
// to the FD already open for stdout.
- if (int Err = posix_spawn_file_actions_adddup2(&FileActions, 1, 2))
+ if (int Err = posix_spawn_file_actions_adddup2(FileActions, 1, 2))
return !MakeErrMsg(ErrMsg, "Can't redirect stderr to stdout", Err);
}
}
// Explicitly initialized to prevent what appears to be a valgrind false
// positive.
pid_t PID = 0;
- int Err = posix_spawn(&PID, path.c_str(), &FileActions, /*attrp*/0,
+ int Err = posix_spawn(&PID, path.c_str(), FileActions, /*attrp*/0,
const_cast<char **>(args), const_cast<char **>(envp));
- posix_spawn_file_actions_destroy(&FileActions);
+ if (FileActions)
+ posix_spawn_file_actions_destroy(FileActions);
if (Err)
return !MakeErrMsg(ErrMsg, "posix_spawn failed", Err);
// Create a child process.
int child = fork();
switch (child) {
- // An error occured: Return to the caller.
+ // An error occurred: Return to the caller.
case -1:
MakeErrMsg(ErrMsg, "Couldn't fork");
return false;
else
MakeErrMsg(ErrMsg, "Child timed out", 0);
- return -1; // Timeout detected
+ return -2; // Timeout detected
} else if (errno != EINTR) {
MakeErrMsg(ErrMsg, "Error waiting for child process");
return -1;
// Following the POSIX convention for command-line tools (which posix_spawn
// itself apparently does not), check to see if the failure was due to some
// reason other than the file not existing, and return 126 in this case.
- if (result == 127 && path.exists())
+ bool Exists;
+ if (result == 127 && !llvm::sys::fs::exists(path.str(), Exists) && Exists)
result = 126;
#endif
if (result == 127) {
*ErrMsg += " (core dumped)";
#endif
}
- return -1;
+ // Return a special value to indicate that the process received an unhandled
+ // signal during execution as opposed to failing to execute.
+ return -2;
}
return result;
#else
return false;
}
-bool Program::ChangeStdinToBinary(){
+error_code Program::ChangeStdinToBinary(){
// Do nothing, as Unix doesn't differentiate between text and binary.
- return false;
+ return make_error_code(errc::success);
}
-bool Program::ChangeStdoutToBinary(){
+error_code Program::ChangeStdoutToBinary(){
// Do nothing, as Unix doesn't differentiate between text and binary.
- return false;
+ return make_error_code(errc::success);
}
-bool Program::ChangeStderrToBinary(){
+error_code Program::ChangeStderrToBinary(){
// Do nothing, as Unix doesn't differentiate between text and binary.
- return false;
+ return make_error_code(errc::success);
}
}