mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-02 00:16:25 +00:00
Remove the program class.
It was only used to implement ExecuteAndWait and ExecuteNoWait. Expose just those two functions and make Execute and Wait implementations details. llvm-svn: 183864
This commit is contained in:
parent
dc7ca853fc
commit
5b921b1aa1
@ -22,49 +22,42 @@
|
||||
namespace llvm {
|
||||
class error_code;
|
||||
namespace sys {
|
||||
/// This static constructor (factory) will attempt to locate a program in
|
||||
/// the operating system's file system using some pre-determined set of
|
||||
/// locations to search (e.g. the PATH on Unix). Paths with slashes are
|
||||
/// returned unmodified.
|
||||
/// @returns A Path object initialized to the path of the program or a
|
||||
/// Path object that is empty (invalid) if the program could not be found.
|
||||
/// @brief Construct a Program by finding it by name.
|
||||
Path FindProgramByName(const std::string& name);
|
||||
|
||||
// TODO: Add operations to communicate with the process, redirect its I/O,
|
||||
// etc.
|
||||
// These functions change the specified standard stream (stdin, stdout, or
|
||||
// stderr) to binary mode. They return errc::success if the specified stream
|
||||
// was changed. Otherwise a platform dependent error is returned.
|
||||
error_code ChangeStdinToBinary();
|
||||
error_code ChangeStdoutToBinary();
|
||||
error_code ChangeStderrToBinary();
|
||||
|
||||
/// This class provides an abstraction for programs that are executable by the
|
||||
/// operating system. It provides a platform generic way to find executable
|
||||
/// programs from the path and to execute them in various ways. The sys::Path
|
||||
/// class is used to specify the location of the Program.
|
||||
/// @since 1.4
|
||||
/// @brief An abstraction for finding and executing programs.
|
||||
class Program {
|
||||
/// Opaque handle for target specific data.
|
||||
void *Data_;
|
||||
|
||||
// Noncopyable.
|
||||
Program(const Program& other) LLVM_DELETED_FUNCTION;
|
||||
Program& operator=(const Program& other) LLVM_DELETED_FUNCTION;
|
||||
|
||||
/// @name Methods
|
||||
/// @{
|
||||
|
||||
Program();
|
||||
~Program();
|
||||
|
||||
/// This function executes the program using the \p arguments provided. The
|
||||
/// invoked program will inherit the stdin, stdout, and stderr file
|
||||
/// descriptors, the environment and other configuration settings of the
|
||||
/// invoking program. If Path::executable() does not return true when this
|
||||
/// function is called then a std::string is thrown.
|
||||
/// @returns false in case of error, true otherwise.
|
||||
/// @see FindProgramByName
|
||||
/// @brief Executes the program with the given set of \p args.
|
||||
bool Execute
|
||||
( const Path& path, ///< sys::Path object providing the path of the
|
||||
/// This function executes the program using the arguments provided. The
|
||||
/// invoked program will inherit the stdin, stdout, and stderr file
|
||||
/// descriptors, the environment and other configuration settings of the
|
||||
/// invoking program.
|
||||
/// This function waits the program to finish.
|
||||
/// @returns an integer result code indicating the status of the program.
|
||||
/// A zero or positive value indicates the result code of the program.
|
||||
/// -1 indicates failure to execute
|
||||
/// -2 indicates a crash during execution or timeout
|
||||
int ExecuteAndWait(
|
||||
const Path &path, ///< sys::Path object providing the path of the
|
||||
///< program to be executed. It is presumed this is the result of
|
||||
///< the FindProgramByName method.
|
||||
const char** args, ///< A vector of strings that are passed to the
|
||||
const char **args, ///< A vector of strings that are passed to the
|
||||
///< program. The first element should be the name of the program.
|
||||
///< The list *must* be terminated by a null char* entry.
|
||||
const char ** env = 0, ///< An optional vector of strings to use for
|
||||
const char **env = 0, ///< An optional vector of strings to use for
|
||||
///< the program's environment. If not provided, the current program's
|
||||
///< environment will be used.
|
||||
const sys::Path** redirects = 0, ///< An optional array of pointers to
|
||||
const sys::Path **redirects = 0, ///< An optional array of pointers to
|
||||
///< Paths. If the array is null, no redirection is done. The array
|
||||
///< should have a size of at least three. If the pointer in the array
|
||||
///< are not null, then the inferior process's stdin(0), stdout(1),
|
||||
@ -72,95 +65,25 @@ namespace sys {
|
||||
///< When an empty Path is passed in, the corresponding file
|
||||
///< descriptor will be disconnected (ie, /dev/null'd) in a portable
|
||||
///< way.
|
||||
unsigned memoryLimit = 0, ///< If non-zero, this specifies max. amount
|
||||
///< of memory can be allocated by process. If memory usage will be
|
||||
///< higher limit, the child is killed and this call returns. If zero
|
||||
///< - no memory limit.
|
||||
std::string* ErrMsg = 0 ///< If non-zero, provides a pointer to a string
|
||||
///< instance in which error messages will be returned. If the string
|
||||
///< is non-empty upon return an error occurred while invoking the
|
||||
///< program.
|
||||
);
|
||||
|
||||
/// This function waits for the program to exit. This function will block
|
||||
/// the current program until the invoked program exits.
|
||||
/// @returns an integer result code indicating the status of the program.
|
||||
/// A zero or positive value indicates the result code of the program.
|
||||
/// -1 indicates failure to execute
|
||||
/// -2 indicates a crash during execution or timeout
|
||||
/// @see Execute
|
||||
/// @brief Waits for the program to exit.
|
||||
int Wait
|
||||
( const Path& path, ///< The path to the child process executable.
|
||||
unsigned secondsToWait, ///< If non-zero, this specifies the amount
|
||||
unsigned secondsToWait = 0, ///< If non-zero, this specifies the amount
|
||||
///< of time to wait for the child process to exit. If the time
|
||||
///< expires, the child is killed and this call returns. If zero,
|
||||
///< this function will wait until the child finishes or forever if
|
||||
///< it doesn't.
|
||||
std::string* ErrMsg ///< If non-zero, provides a pointer to a string
|
||||
unsigned memoryLimit = 0, ///< If non-zero, this specifies max. amount
|
||||
///< of memory can be allocated by process. If memory usage will be
|
||||
///< higher limit, the child is killed and this call returns. If zero
|
||||
///< - no memory limit.
|
||||
std::string *ErrMsg = 0, ///< If non-zero, provides a pointer to a string
|
||||
///< instance in which error messages will be returned. If the string
|
||||
///< is non-empty upon return an error occurred while waiting.
|
||||
);
|
||||
///< is non-empty upon return an error occurred while invoking the
|
||||
///< program.
|
||||
bool *ExecutionFailed = 0);
|
||||
|
||||
public:
|
||||
/// This static constructor (factory) will attempt to locate a program in
|
||||
/// the operating system's file system using some pre-determined set of
|
||||
/// locations to search (e.g. the PATH on Unix). Paths with slashes are
|
||||
/// returned unmodified.
|
||||
/// @returns A Path object initialized to the path of the program or a
|
||||
/// Path object that is empty (invalid) if the program could not be found.
|
||||
/// @brief Construct a Program by finding it by name.
|
||||
static Path FindProgramByName(const std::string& name);
|
||||
|
||||
// These methods change the specified standard stream (stdin, stdout, or
|
||||
// stderr) to binary mode. They return errc::success if the specified stream
|
||||
// was changed. Otherwise a platform dependent error is returned.
|
||||
static error_code ChangeStdinToBinary();
|
||||
static error_code ChangeStdoutToBinary();
|
||||
static error_code ChangeStderrToBinary();
|
||||
|
||||
/// A convenience function equivalent to Program prg; prg.Execute(..);
|
||||
/// prg.Wait(..);
|
||||
/// @see Execute, Wait
|
||||
static int ExecuteAndWait(const Path& path,
|
||||
const char** args,
|
||||
const char ** env = 0,
|
||||
const sys::Path** redirects = 0,
|
||||
unsigned secondsToWait = 0,
|
||||
unsigned memoryLimit = 0,
|
||||
std::string* ErrMsg = 0,
|
||||
bool *ExecutionFailed = 0);
|
||||
|
||||
/// A convenience function equivalent to Program prg; prg.Execute(..);
|
||||
/// @see Execute
|
||||
static void ExecuteNoWait(const Path& path,
|
||||
const char** args,
|
||||
const char ** env = 0,
|
||||
const sys::Path** redirects = 0,
|
||||
unsigned memoryLimit = 0,
|
||||
std::string* ErrMsg = 0);
|
||||
|
||||
/// @}
|
||||
|
||||
};
|
||||
|
||||
inline int ExecuteAndWait(const Path &path, const char **args,
|
||||
const char **env = 0,
|
||||
const sys::Path **redirects = 0,
|
||||
unsigned secondsToWait = 0,
|
||||
unsigned memoryLimit = 0, std::string *ErrMsg = 0,
|
||||
bool *ExecutionFailed = 0) {
|
||||
return Program::ExecuteAndWait(path, args, env, redirects, secondsToWait,
|
||||
memoryLimit, ErrMsg, ExecutionFailed);
|
||||
}
|
||||
|
||||
inline Path FindProgramByName(const std::string& name) {
|
||||
return Program::FindProgramByName(name);
|
||||
}
|
||||
|
||||
inline error_code ChangeStdoutToBinary() {
|
||||
return Program::ChangeStdoutToBinary();
|
||||
}
|
||||
/// Similar to ExecuteAndWait, but return immediately.
|
||||
void ExecuteNoWait(const Path &path, const char **args, const char **env = 0,
|
||||
const sys::Path **redirects = 0, unsigned memoryLimit = 0,
|
||||
std::string *ErrMsg = 0);
|
||||
|
||||
// Return true if the given arguments fit within system-specific
|
||||
// argument length limits.
|
||||
|
@ -66,7 +66,7 @@ public:
|
||||
error_code OpenFile(const std::string &Filename) {
|
||||
if (Filename == "-") {
|
||||
Fd = 0;
|
||||
sys::Program::ChangeStdinToBinary();
|
||||
sys::ChangeStdinToBinary();
|
||||
return error_code::success();
|
||||
}
|
||||
|
||||
|
@ -69,7 +69,7 @@ static bool LLVM_ATTRIBUTE_UNUSED
|
||||
ExecGraphViewer(const sys::Path &ExecPath, std::vector<const char*> &args,
|
||||
const sys::Path &Filename, bool wait, std::string &ErrMsg) {
|
||||
if (wait) {
|
||||
if (sys::Program::ExecuteAndWait(ExecPath, &args[0],0,0,0,0,&ErrMsg)) {
|
||||
if (sys::ExecuteAndWait(ExecPath, &args[0],0,0,0,0,&ErrMsg)) {
|
||||
errs() << "Error: " << ErrMsg << "\n";
|
||||
return false;
|
||||
}
|
||||
@ -77,7 +77,7 @@ ExecGraphViewer(const sys::Path &ExecPath, std::vector<const char*> &args,
|
||||
errs() << " done. \n";
|
||||
}
|
||||
else {
|
||||
sys::Program::ExecuteNoWait(ExecPath, &args[0],0,0,0,&ErrMsg);
|
||||
sys::ExecuteNoWait(ExecPath, &args[0],0,0,0,&ErrMsg);
|
||||
errs() << "Remember to erase graph file: " << Filename.str() << "\n";
|
||||
}
|
||||
return true;
|
||||
|
@ -419,7 +419,7 @@ error_code MemoryBuffer::getSTDIN(OwningPtr<MemoryBuffer> &result) {
|
||||
//
|
||||
// FIXME: That isn't necessarily true, we should try to mmap stdin and
|
||||
// fallback if it fails.
|
||||
sys::Program::ChangeStdinToBinary();
|
||||
sys::ChangeStdinToBinary();
|
||||
|
||||
return getMemoryBufferForStream(0, "<stdin>", result);
|
||||
}
|
||||
|
@ -22,33 +22,31 @@ using namespace sys;
|
||||
//=== independent code.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
int
|
||||
Program::ExecuteAndWait(const Path& path,
|
||||
const char** args,
|
||||
const char** envp,
|
||||
const Path** redirects,
|
||||
unsigned secondsToWait,
|
||||
unsigned memoryLimit,
|
||||
std::string* ErrMsg,
|
||||
static bool Execute(void *&Data, const Path &path, const char **args,
|
||||
const char **env, const sys::Path **redirects,
|
||||
unsigned memoryLimit, std::string *ErrMsg);
|
||||
|
||||
static int Wait(void *&Data, const Path &path, unsigned secondsToWait,
|
||||
std::string *ErrMsg);
|
||||
|
||||
int sys::ExecuteAndWait(const Path &path, const char **args, const char **envp,
|
||||
const Path **redirects, unsigned secondsToWait,
|
||||
unsigned memoryLimit, std::string *ErrMsg,
|
||||
bool *ExecutionFailed) {
|
||||
Program prg;
|
||||
if (prg.Execute(path, args, envp, redirects, memoryLimit, ErrMsg)) {
|
||||
void *Data;
|
||||
if (Execute(Data, path, args, envp, redirects, memoryLimit, ErrMsg)) {
|
||||
if (ExecutionFailed) *ExecutionFailed = false;
|
||||
return prg.Wait(path, secondsToWait, ErrMsg);
|
||||
return Wait(Data, path, secondsToWait, ErrMsg);
|
||||
}
|
||||
if (ExecutionFailed) *ExecutionFailed = true;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
Program::ExecuteNoWait(const Path& path,
|
||||
const char** args,
|
||||
const char** envp,
|
||||
const Path** redirects,
|
||||
unsigned memoryLimit,
|
||||
std::string* ErrMsg) {
|
||||
Program prg;
|
||||
prg.Execute(path, args, envp, redirects, memoryLimit, ErrMsg);
|
||||
void sys::ExecuteNoWait(const Path &path, const char **args, const char **envp,
|
||||
const Path **redirects, unsigned memoryLimit,
|
||||
std::string *ErrMsg) {
|
||||
void *Data;
|
||||
Execute(Data, path, args, envp, redirects, memoryLimit, ErrMsg);
|
||||
}
|
||||
|
||||
// Include the platform-specific parts of this class.
|
||||
|
@ -47,13 +47,9 @@
|
||||
namespace llvm {
|
||||
using namespace sys;
|
||||
|
||||
Program::Program() : Data_(0) {}
|
||||
|
||||
Program::~Program() {}
|
||||
|
||||
// This function just uses the PATH environment variable to find the program.
|
||||
Path
|
||||
Program::FindProgramByName(const std::string& progName) {
|
||||
sys::FindProgramByName(const std::string& progName) {
|
||||
|
||||
// Check some degenerate cases
|
||||
if (progName.length() == 0) // no program
|
||||
@ -180,10 +176,11 @@ static void SetMemoryLimits (unsigned size)
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
Program::Execute(const Path &path, const char **args, const char **envp,
|
||||
const Path **redirects, unsigned memoryLimit,
|
||||
std::string *ErrMsg) {
|
||||
}
|
||||
|
||||
static bool Execute(void *&Data, const Path &path, const char **args,
|
||||
const char **envp, const Path **redirects,
|
||||
unsigned memoryLimit, std::string *ErrMsg) {
|
||||
// If this OS has posix_spawn and there is no memory limit being implied, use
|
||||
// posix_spawn. It is more efficient than fork/exec.
|
||||
#ifdef HAVE_POSIX_SPAWN
|
||||
@ -231,7 +228,7 @@ Program::Execute(const Path &path, const char **args, const char **envp,
|
||||
if (Err)
|
||||
return !MakeErrMsg(ErrMsg, "posix_spawn failed", Err);
|
||||
|
||||
Data_ = reinterpret_cast<void*>(PID);
|
||||
Data = reinterpret_cast<void*>(PID);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
@ -293,20 +290,17 @@ Program::Execute(const Path &path, const char **args, const char **envp,
|
||||
break;
|
||||
}
|
||||
|
||||
Data_ = reinterpret_cast<void*>(child);
|
||||
Data = reinterpret_cast<void*>(child);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int
|
||||
Program::Wait(const sys::Path &path,
|
||||
unsigned secondsToWait,
|
||||
std::string* ErrMsg)
|
||||
{
|
||||
static int Wait(void *&Data, const sys::Path &path, unsigned secondsToWait,
|
||||
std::string *ErrMsg) {
|
||||
#ifdef HAVE_SYS_WAIT_H
|
||||
struct sigaction Act, Old;
|
||||
|
||||
if (Data_ == 0) {
|
||||
if (Data == 0) {
|
||||
MakeErrMsg(ErrMsg, "Process not started!");
|
||||
return -1;
|
||||
}
|
||||
@ -324,7 +318,7 @@ Program::Wait(const sys::Path &path,
|
||||
|
||||
// Parent process: Wait for the child process to terminate.
|
||||
int status;
|
||||
uint64_t pid = reinterpret_cast<uint64_t>(Data_);
|
||||
uint64_t pid = reinterpret_cast<uint64_t>(Data);
|
||||
pid_t child = static_cast<pid_t>(pid);
|
||||
while (waitpid(pid, &status, 0) != child)
|
||||
if (secondsToWait && errno == EINTR) {
|
||||
@ -397,17 +391,19 @@ Program::Wait(const sys::Path &path,
|
||||
#endif
|
||||
}
|
||||
|
||||
error_code Program::ChangeStdinToBinary(){
|
||||
namespace llvm {
|
||||
|
||||
error_code sys::ChangeStdinToBinary(){
|
||||
// Do nothing, as Unix doesn't differentiate between text and binary.
|
||||
return make_error_code(errc::success);
|
||||
}
|
||||
|
||||
error_code Program::ChangeStdoutToBinary(){
|
||||
error_code sys::ChangeStdoutToBinary(){
|
||||
// Do nothing, as Unix doesn't differentiate between text and binary.
|
||||
return make_error_code(errc::success);
|
||||
}
|
||||
|
||||
error_code Program::ChangeStderrToBinary(){
|
||||
error_code sys::ChangeStderrToBinary(){
|
||||
// Do nothing, as Unix doesn't differentiate between text and binary.
|
||||
return make_error_code(errc::success);
|
||||
}
|
||||
|
@ -442,7 +442,7 @@ raw_fd_ostream::raw_fd_ostream(const char *Filename, std::string &ErrorInfo,
|
||||
// If user requested binary then put stdout into binary mode if
|
||||
// possible.
|
||||
if (Flags & F_Binary)
|
||||
sys::Program::ChangeStdoutToBinary();
|
||||
sys::ChangeStdoutToBinary();
|
||||
// Close stdout when we're done, to detect any output errors.
|
||||
ShouldClose = true;
|
||||
return;
|
||||
|
@ -148,7 +148,7 @@ bool BugDriver::runPasses(Module *Program,
|
||||
return 1;
|
||||
}
|
||||
|
||||
sys::Path tool = sys::Program::FindProgramByName("opt");
|
||||
sys::Path tool = sys::FindProgramByName("opt");
|
||||
if (tool.empty()) {
|
||||
errs() << "Cannot find `opt' in PATH!\n";
|
||||
return 1;
|
||||
@ -196,7 +196,7 @@ bool BugDriver::runPasses(Module *Program,
|
||||
|
||||
sys::Path prog;
|
||||
if (UseValgrind)
|
||||
prog = sys::Program::FindProgramByName("valgrind");
|
||||
prog = sys::FindProgramByName("valgrind");
|
||||
else
|
||||
prog = tool;
|
||||
|
||||
@ -204,9 +204,9 @@ bool BugDriver::runPasses(Module *Program,
|
||||
sys::Path Nowhere;
|
||||
const sys::Path *Redirects[3] = {0, &Nowhere, &Nowhere};
|
||||
|
||||
int result = sys::Program::ExecuteAndWait(prog, Args.data(), 0,
|
||||
(SilencePasses ? Redirects : 0),
|
||||
Timeout, MemoryLimit, &ErrMsg);
|
||||
int result =
|
||||
sys::ExecuteAndWait(prog, Args.data(), 0, (SilencePasses ? Redirects : 0),
|
||||
Timeout, MemoryLimit, &ErrMsg);
|
||||
|
||||
// If we are supposed to delete the bitcode file or if the passes crashed,
|
||||
// remove it now. This may fail if the file was never created, but that's ok.
|
||||
|
@ -75,9 +75,8 @@ static int RunProgramWithTimeout(const sys::Path &ProgramPath,
|
||||
}
|
||||
#endif
|
||||
|
||||
return
|
||||
sys::Program::ExecuteAndWait(ProgramPath, Args, 0, redirects,
|
||||
NumSeconds, MemoryLimit, ErrMsg);
|
||||
return sys::ExecuteAndWait(ProgramPath, Args, 0, redirects, NumSeconds,
|
||||
MemoryLimit, ErrMsg);
|
||||
}
|
||||
|
||||
/// RunProgramRemotelyWithTimeout - This function runs the given program
|
||||
@ -108,8 +107,8 @@ static int RunProgramRemotelyWithTimeout(const sys::Path &RemoteClientPath,
|
||||
#endif
|
||||
|
||||
// Run the program remotely with the remote client
|
||||
int ReturnCode = sys::Program::ExecuteAndWait(RemoteClientPath, Args,
|
||||
0, redirects, NumSeconds, MemoryLimit);
|
||||
int ReturnCode = sys::ExecuteAndWait(RemoteClientPath, Args, 0, redirects,
|
||||
NumSeconds, MemoryLimit);
|
||||
|
||||
// Has the remote client fail?
|
||||
if (255 == ReturnCode) {
|
||||
@ -398,7 +397,7 @@ static void lexCommand(std::string &Message, const std::string &CommandLine,
|
||||
pos = CommandLine.find_first_of(delimiters, lastPos);
|
||||
}
|
||||
|
||||
CmdPath = sys::Program::FindProgramByName(Command).str();
|
||||
CmdPath = sys::FindProgramByName(Command).str();
|
||||
if (CmdPath.empty()) {
|
||||
Message =
|
||||
std::string("Cannot find '") + Command +
|
||||
@ -875,7 +874,7 @@ int GCC::MakeSharedObject(const std::string &InputFile, FileType fileType,
|
||||
GCC *GCC::create(std::string &Message,
|
||||
const std::string &GCCBinary,
|
||||
const std::vector<std::string> *Args) {
|
||||
sys::Path GCCPath = sys::Program::FindProgramByName(GCCBinary);
|
||||
sys::Path GCCPath = sys::FindProgramByName(GCCBinary);
|
||||
if (GCCPath.isEmpty()) {
|
||||
Message = "Cannot find `"+ GCCBinary +"' in PATH!\n";
|
||||
return 0;
|
||||
@ -883,7 +882,7 @@ GCC *GCC::create(std::string &Message,
|
||||
|
||||
sys::Path RemoteClientPath;
|
||||
if (!RemoteClient.empty())
|
||||
RemoteClientPath = sys::Program::FindProgramByName(RemoteClient);
|
||||
RemoteClientPath = sys::FindProgramByName(RemoteClient);
|
||||
|
||||
Message = "Found gcc: " + GCCPath.str() + "\n";
|
||||
return new GCC(GCCPath, RemoteClientPath, Args);
|
||||
|
@ -425,7 +425,7 @@ int main(int argc, char **argv) {
|
||||
cl::ParseCommandLineOptions(argc, argv, "llvm symbol table dumper\n");
|
||||
|
||||
// llvm-nm only reads binary files.
|
||||
if (error(sys::Program::ChangeStdinToBinary()))
|
||||
if (error(sys::ChangeStdinToBinary()))
|
||||
return 1;
|
||||
|
||||
ToolName = argv[0];
|
||||
|
@ -79,9 +79,9 @@ TEST(ProgramTest, CreateProcessTrailingSlash) {
|
||||
Path nul("/dev/null");
|
||||
#endif
|
||||
const Path *redirects[] = { &nul, &nul, 0 };
|
||||
int rc = Program::ExecuteAndWait(my_exe, argv, &envp[0], redirects,
|
||||
/*secondsToWait=*/10, /*memoryLimit=*/0,
|
||||
&error, &ExecutionFailed);
|
||||
int rc =
|
||||
ExecuteAndWait(my_exe, argv, &envp[0], redirects, /*secondsToWait=*/ 10,
|
||||
/*memoryLimit=*/ 0, &error, &ExecutionFailed);
|
||||
EXPECT_FALSE(ExecutionFailed) << error;
|
||||
EXPECT_EQ(0, rc);
|
||||
}
|
||||
|
@ -13,11 +13,10 @@
|
||||
using namespace llvm;
|
||||
|
||||
int main(int argc, const char **argv) {
|
||||
sys::Path Program = sys::Program::FindProgramByName(argv[1]);
|
||||
sys::Path Program = sys::FindProgramByName(argv[1]);
|
||||
|
||||
std::string ErrMsg;
|
||||
int Result = sys::Program::ExecuteAndWait(Program, argv + 1, 0, 0, 0, 0,
|
||||
&ErrMsg);
|
||||
int Result = sys::ExecuteAndWait(Program, argv + 1, 0, 0, 0, 0, &ErrMsg);
|
||||
if (Result < 0) {
|
||||
errs() << "Error: " << ErrMsg << "\n";
|
||||
return 1;
|
||||
|
Loading…
Reference in New Issue
Block a user