#include "Unix.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/raw_ostream.h"
#include <llvm/Config/config.h>
#if HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
namespace llvm {
+
using namespace sys;
ProcessInfo::ProcessInfo() : Pid(0), ReturnCode(0) {}
// Get the path. If its empty, we can't do anything to find it.
const char *PathStr = getenv("PATH");
- if (PathStr == 0)
+ if (!PathStr)
return "";
// Now we have a colon separated list of directories to search; try them.
}
static bool RedirectIO(const StringRef *Path, int FD, std::string* ErrMsg) {
- if (Path == 0) // Noop
+ if (!Path) // Noop
return false;
std::string File;
if (Path->empty())
#ifdef HAVE_POSIX_SPAWN
static bool RedirectIO_PS(const std::string *Path, int FD, std::string *ErrMsg,
posix_spawn_file_actions_t *FileActions) {
- if (Path == 0) // Noop
+ if (!Path) // Noop
return false;
const char *File;
if (Path->empty())
#ifdef HAVE_POSIX_SPAWN
if (memoryLimit == 0) {
posix_spawn_file_actions_t FileActionsStore;
- posix_spawn_file_actions_t *FileActions = 0;
+ posix_spawn_file_actions_t *FileActions = nullptr;
// 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_spawn,
std::string RedirectsStorage[3];
if (redirects) {
- std::string *RedirectsStr[3] = {0, 0, 0};
+ std::string *RedirectsStr[3] = {nullptr, nullptr, nullptr};
for (int I = 0; I < 3; ++I) {
if (redirects[I]) {
RedirectsStorage[I] = *redirects[I];
if (RedirectIO_PS(RedirectsStr[0], 0, ErrMsg, FileActions) ||
RedirectIO_PS(RedirectsStr[1], 1, ErrMsg, FileActions))
return false;
- if (redirects[1] == 0 || redirects[2] == 0 ||
+ if (redirects[1] == nullptr || redirects[2] == nullptr ||
*redirects[1] != *redirects[2]) {
// Just redirect stderr
if (RedirectIO_PS(RedirectsStr[2], 2, ErrMsg, FileActions))
// Explicitly initialized to prevent what appears to be a valgrind false
// positive.
pid_t PID = 0;
- int Err = posix_spawn(&PID, Program.str().c_str(), FileActions, /*attrp*/0,
- const_cast<char **>(args), const_cast<char **>(envp));
+ int Err = posix_spawn(&PID, Program.str().c_str(), FileActions,
+ /*attrp*/nullptr, const_cast<char **>(args),
+ const_cast<char **>(envp));
if (FileActions)
posix_spawn_file_actions_destroy(FileActions);
// Execute!
std::string PathStr = Program;
- if (envp != 0)
+ if (envp != nullptr)
execve(PathStr.c_str(),
const_cast<char **>(args),
const_cast<char **>(envp));
pid_t ChildPid = PI.Pid;
if (WaitUntilTerminates) {
SecondsToWait = 0;
- ChildPid = -1; // mimic a wait() using waitpid()
} else if (SecondsToWait) {
// Install a timeout handler. The handler itself does nothing, but the
// simple fact of having a handler at all causes the wait below to return
// Parent process: Wait for the child process to terminate.
int status;
ProcessInfo WaitResult;
- WaitResult.Pid = waitpid(ChildPid, &status, WaitPidOptions);
+
+ do {
+ WaitResult.Pid = waitpid(ChildPid, &status, WaitPidOptions);
+ } while (WaitUntilTerminates && WaitResult.Pid == -1 && errno == EINTR);
+
if (WaitResult.Pid != PI.Pid) {
if (WaitResult.Pid == 0) {
// Non-blocking wait.
// Turn off the alarm and restore the signal handler
alarm(0);
- sigaction(SIGALRM, &Old, 0);
+ sigaction(SIGALRM, &Old, nullptr);
// Wait for child to die
if (wait(&status) != ChildPid)
// We exited normally without timeout, so turn off the timer.
if (SecondsToWait && !WaitUntilTerminates) {
alarm(0);
- sigaction(SIGALRM, &Old, 0);
+ sigaction(SIGALRM, &Old, nullptr);
}
// Return the proper exit status. Detect error conditions
#else
if (ErrMsg)
*ErrMsg = "Program::Wait is not implemented on this platform yet!";
+ ProcessInfo WaitResult;
WaitResult.ReturnCode = -2;
#endif
return WaitResult;
}
-error_code sys::ChangeStdinToBinary(){
+ std::error_code sys::ChangeStdinToBinary(){
// Do nothing, as Unix doesn't differentiate between text and binary.
- return make_error_code(errc::success);
+ return std::error_code();
}
-error_code sys::ChangeStdoutToBinary(){
+ std::error_code sys::ChangeStdoutToBinary(){
// Do nothing, as Unix doesn't differentiate between text and binary.
- return make_error_code(errc::success);
+ return std::error_code();
}
-error_code sys::ChangeStderrToBinary(){
- // Do nothing, as Unix doesn't differentiate between text and binary.
- return make_error_code(errc::success);
+std::error_code
+llvm::sys::writeFileWithEncoding(StringRef FileName, StringRef Contents,
+ WindowsEncodingMethod Encoding /*unused*/) {
+ std::error_code EC;
+ llvm::raw_fd_ostream OS(FileName, EC, llvm::sys::fs::OpenFlags::F_Text);
+
+ if (EC)
+ return EC;
+
+ OS << Contents;
+
+ if (OS.has_error())
+ return std::make_error_code(std::errc::io_error);
+
+ return EC;
}
bool llvm::sys::argumentsFitWithinSystemLimits(ArrayRef<const char*> Args) {
return true;
// Conservatively account for space required by environment variables.
- ArgMax /= 2;
+ long HalfArgMax = ArgMax / 2;
size_t ArgLength = 0;
for (ArrayRef<const char*>::iterator I = Args.begin(), E = Args.end();
I != E; ++I) {
ArgLength += strlen(*I) + 1;
- if (ArgLength > size_t(ArgMax)) {
+ if (ArgLength > size_t(HalfArgMax)) {
return false;
}
}