forked from OSchip/llvm-project
Implement -w flag to process launch (allow launching inferior process in different working directory) on Linux/FreeBSD
- fixes test case TestProcessLaunch llvm-svn: 171854
This commit is contained in:
parent
7daa1a2201
commit
6217d2ae37
|
@ -627,14 +627,16 @@ ProcessMonitor::LaunchArgs::LaunchArgs(ProcessMonitor *monitor,
|
|||
char const **envp,
|
||||
const char *stdin_path,
|
||||
const char *stdout_path,
|
||||
const char *stderr_path)
|
||||
const char *stderr_path,
|
||||
const char *working_dir)
|
||||
: OperationArgs(monitor),
|
||||
m_module(module),
|
||||
m_argv(argv),
|
||||
m_envp(envp),
|
||||
m_stdin_path(stdin_path),
|
||||
m_stdout_path(stdout_path),
|
||||
m_stderr_path(stderr_path) { }
|
||||
m_stderr_path(stderr_path),
|
||||
m_working_dir(working_dir) { }
|
||||
|
||||
ProcessMonitor::LaunchArgs::~LaunchArgs()
|
||||
{ }
|
||||
|
@ -665,6 +667,7 @@ ProcessMonitor::ProcessMonitor(ProcessPOSIX *process,
|
|||
const char *stdin_path,
|
||||
const char *stdout_path,
|
||||
const char *stderr_path,
|
||||
const char *working_dir,
|
||||
lldb_private::Error &error)
|
||||
: m_process(static_cast<ProcessFreeBSD *>(process)),
|
||||
m_operation_thread(LLDB_INVALID_HOST_THREAD),
|
||||
|
@ -678,7 +681,7 @@ ProcessMonitor::ProcessMonitor(ProcessPOSIX *process,
|
|||
std::auto_ptr<LaunchArgs> args;
|
||||
|
||||
args.reset(new LaunchArgs(this, module, argv, envp,
|
||||
stdin_path, stdout_path, stderr_path));
|
||||
stdin_path, stdout_path, stderr_path, working_dir));
|
||||
|
||||
|
||||
// Server/client descriptors.
|
||||
|
@ -839,6 +842,7 @@ ProcessMonitor::Launch(LaunchArgs *args)
|
|||
const char *stdin_path = args->m_stdin_path;
|
||||
const char *stdout_path = args->m_stdout_path;
|
||||
const char *stderr_path = args->m_stderr_path;
|
||||
const char *working_dir = args->m_working_dir;
|
||||
lldb::pid_t pid;
|
||||
|
||||
lldb::ThreadSP inferior;
|
||||
|
@ -853,6 +857,7 @@ ProcessMonitor::Launch(LaunchArgs *args)
|
|||
eDupStdinFailed,
|
||||
eDupStdoutFailed,
|
||||
eDupStderrFailed,
|
||||
eChdirFailed,
|
||||
eExecFailed
|
||||
};
|
||||
|
||||
|
@ -887,6 +892,11 @@ ProcessMonitor::Launch(LaunchArgs *args)
|
|||
if (!DupDescriptor(stderr_path, STDERR_FILENO, O_WRONLY | O_CREAT))
|
||||
exit(eDupStderrFailed);
|
||||
|
||||
// Change working directory
|
||||
if (working_dir != NULL && working_dir[0])
|
||||
if (0 != ::chdir(working_dir))
|
||||
exit(eChdirFailed);
|
||||
|
||||
// Execute. We should never return.
|
||||
execve(argv[0],
|
||||
const_cast<char *const *>(argv),
|
||||
|
@ -920,6 +930,9 @@ ProcessMonitor::Launch(LaunchArgs *args)
|
|||
case eDupStderrFailed:
|
||||
args->m_error.SetErrorString("Child open stderr failed.");
|
||||
break;
|
||||
case eChdirFailed:
|
||||
args->m_error.SetErrorString("Child failed to set working directory.");
|
||||
break;
|
||||
case eExecFailed:
|
||||
args->m_error.SetErrorString("Child exec failed.");
|
||||
break;
|
||||
|
|
|
@ -54,6 +54,7 @@ public:
|
|||
const char *stdin_path,
|
||||
const char *stdout_path,
|
||||
const char *stderr_path,
|
||||
const char *working_dir,
|
||||
lldb_private::Error &error);
|
||||
|
||||
ProcessMonitor(ProcessPOSIX *process,
|
||||
|
@ -210,7 +211,8 @@ private:
|
|||
char const **envp,
|
||||
const char *stdin_path,
|
||||
const char *stdout_path,
|
||||
const char *stderr_path);
|
||||
const char *stderr_path,
|
||||
const char *working_dir);
|
||||
|
||||
~LaunchArgs();
|
||||
|
||||
|
@ -220,6 +222,7 @@ private:
|
|||
const char *m_stdin_path; // Redirect stdin or NULL.
|
||||
const char *m_stdout_path; // Redirect stdout or NULL.
|
||||
const char *m_stderr_path; // Redirect stderr or NULL.
|
||||
const char *m_working_dir; // Working directory or NULL.
|
||||
};
|
||||
|
||||
void
|
||||
|
|
|
@ -780,14 +780,16 @@ ProcessMonitor::LaunchArgs::LaunchArgs(ProcessMonitor *monitor,
|
|||
char const **envp,
|
||||
const char *stdin_path,
|
||||
const char *stdout_path,
|
||||
const char *stderr_path)
|
||||
const char *stderr_path,
|
||||
const char *working_dir)
|
||||
: OperationArgs(monitor),
|
||||
m_module(module),
|
||||
m_argv(argv),
|
||||
m_envp(envp),
|
||||
m_stdin_path(stdin_path),
|
||||
m_stdout_path(stdout_path),
|
||||
m_stderr_path(stderr_path) { }
|
||||
m_stderr_path(stderr_path),
|
||||
m_working_dir(working_dir) { }
|
||||
|
||||
ProcessMonitor::LaunchArgs::~LaunchArgs()
|
||||
{ }
|
||||
|
@ -818,6 +820,7 @@ ProcessMonitor::ProcessMonitor(ProcessPOSIX *process,
|
|||
const char *stdin_path,
|
||||
const char *stdout_path,
|
||||
const char *stderr_path,
|
||||
const char *working_dir,
|
||||
lldb_private::Error &error)
|
||||
: m_process(static_cast<ProcessLinux *>(process)),
|
||||
m_operation_thread(LLDB_INVALID_HOST_THREAD),
|
||||
|
@ -830,7 +833,7 @@ ProcessMonitor::ProcessMonitor(ProcessPOSIX *process,
|
|||
std::auto_ptr<LaunchArgs> args;
|
||||
|
||||
args.reset(new LaunchArgs(this, module, argv, envp,
|
||||
stdin_path, stdout_path, stderr_path));
|
||||
stdin_path, stdout_path, stderr_path, working_dir));
|
||||
|
||||
// Server/client descriptors.
|
||||
if (!EnableIPC())
|
||||
|
@ -976,6 +979,7 @@ ProcessMonitor::Launch(LaunchArgs *args)
|
|||
const char *stdin_path = args->m_stdin_path;
|
||||
const char *stdout_path = args->m_stdout_path;
|
||||
const char *stderr_path = args->m_stderr_path;
|
||||
const char *working_dir = args->m_working_dir;
|
||||
|
||||
lldb_utility::PseudoTerminal terminal;
|
||||
const size_t err_len = 1024;
|
||||
|
@ -1010,6 +1014,7 @@ ProcessMonitor::Launch(LaunchArgs *args)
|
|||
eDupStdinFailed,
|
||||
eDupStdoutFailed,
|
||||
eDupStderrFailed,
|
||||
eChdirFailed,
|
||||
eExecFailed
|
||||
};
|
||||
|
||||
|
@ -1042,6 +1047,11 @@ ProcessMonitor::Launch(LaunchArgs *args)
|
|||
if (!DupDescriptor(stderr_path, STDERR_FILENO, O_WRONLY | O_CREAT))
|
||||
exit(eDupStderrFailed);
|
||||
|
||||
// Change working directory
|
||||
if (working_dir != NULL && working_dir[0])
|
||||
if (0 != ::chdir(working_dir))
|
||||
exit(eChdirFailed);
|
||||
|
||||
// Execute. We should never return.
|
||||
execve(argv[0],
|
||||
const_cast<char *const *>(argv),
|
||||
|
@ -1075,6 +1085,9 @@ ProcessMonitor::Launch(LaunchArgs *args)
|
|||
case eDupStderrFailed:
|
||||
args->m_error.SetErrorString("Child open stderr failed.");
|
||||
break;
|
||||
case eChdirFailed:
|
||||
args->m_error.SetErrorString("Child failed to set working directory.");
|
||||
break;
|
||||
case eExecFailed:
|
||||
args->m_error.SetErrorString("Child exec failed.");
|
||||
break;
|
||||
|
|
|
@ -56,6 +56,7 @@ public:
|
|||
const char *stdin_path,
|
||||
const char *stdout_path,
|
||||
const char *stderr_path,
|
||||
const char *working_dir,
|
||||
lldb_private::Error &error);
|
||||
|
||||
ProcessMonitor(ProcessPOSIX *process,
|
||||
|
@ -200,7 +201,8 @@ private:
|
|||
char const **envp,
|
||||
const char *stdin_path,
|
||||
const char *stdout_path,
|
||||
const char *stderr_path);
|
||||
const char *stderr_path,
|
||||
const char *working_dir);
|
||||
|
||||
~LaunchArgs();
|
||||
|
||||
|
@ -210,6 +212,7 @@ private:
|
|||
const char *m_stdin_path; // Redirect stdin or NULL.
|
||||
const char *m_stdout_path; // Redirect stdout or NULL.
|
||||
const char *m_stderr_path; // Redirect stderr or NULL.
|
||||
const char *m_working_dir; // Working directory or NULL.
|
||||
};
|
||||
|
||||
void
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "lldb/Core/Module.h"
|
||||
#include "lldb/Core/PluginManager.h"
|
||||
#include "lldb/Core/State.h"
|
||||
#include "lldb/Host/FileSpec.h"
|
||||
#include "lldb/Host/Host.h"
|
||||
#include "lldb/Symbol/ObjectFile.h"
|
||||
#include "lldb/Target/DynamicLoader.h"
|
||||
|
@ -162,6 +163,16 @@ ProcessPOSIX::DoLaunch (Module *module,
|
|||
Error error;
|
||||
assert(m_monitor == NULL);
|
||||
|
||||
const char* working_dir = launch_info.GetWorkingDirectory();
|
||||
if (working_dir) {
|
||||
FileSpec WorkingDir(working_dir, true);
|
||||
if (!WorkingDir || WorkingDir.GetFileType() != FileSpec::eFileTypeDirectory)
|
||||
{
|
||||
error.SetErrorStringWithFormat("No such file or directory: %s", working_dir);
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
SetPrivateState(eStateLaunching);
|
||||
|
||||
const lldb_private::ProcessLaunchInfo::FileAction *file_action;
|
||||
|
@ -170,7 +181,7 @@ ProcessPOSIX::DoLaunch (Module *module,
|
|||
const char *stdin_path = NULL;
|
||||
const char *stdout_path = NULL;
|
||||
const char *stderr_path = NULL;
|
||||
|
||||
|
||||
file_action = launch_info.GetFileActionForFD (STDIN_FILENO);
|
||||
stdin_path = GetFilePath(file_action, stdin_path);
|
||||
|
||||
|
@ -187,6 +198,7 @@ ProcessPOSIX::DoLaunch (Module *module,
|
|||
stdin_path,
|
||||
stdout_path,
|
||||
stderr_path,
|
||||
working_dir,
|
||||
error);
|
||||
|
||||
m_module = module;
|
||||
|
|
|
@ -152,7 +152,7 @@ class ProcessLaunchTestCase(TestBase):
|
|||
err_file_path)
|
||||
|
||||
self.expect(launch_command, error=True,
|
||||
startstr = "error: No such file or directory: %sz" % my_working_dir_path)
|
||||
patterns = ["error:.* No such file or directory: %sz" % my_working_dir_path])
|
||||
|
||||
# Really launch the process
|
||||
launch_command = "process launch -w %s -o %s -e %s" % (my_working_dir_path,
|
||||
|
|
Loading…
Reference in New Issue