11#include "lldb/Host/Config.h"
20#include "llvm/Support/ConvertUTF.h"
21#include "llvm/Support/FileSystem.h"
33 :
ProcessInfo(), m_working_dir(), m_plugin_name(), m_flags(0),
34 m_file_actions(), m_pty(new
PseudoTerminal), m_monitor_callback(nullptr) {
41 uint32_t launch_flags)
42 :
ProcessInfo(), m_working_dir(), m_plugin_name(), m_flags(launch_flags),
44 if (stdin_file_spec) {
46 const bool read =
true;
47 const bool write =
false;
48 if (file_action.
Open(STDIN_FILENO, stdin_file_spec, read, write))
51 if (stdout_file_spec) {
53 const bool read =
false;
54 const bool write =
true;
55 if (file_action.
Open(STDOUT_FILENO, stdout_file_spec, read, write))
58 if (stderr_file_spec) {
60 const bool read =
false;
61 const bool write =
true;
62 if (file_action.
Open(STDERR_FILENO, stderr_file_spec, read, write))
65 if (working_directory)
71 if (file_action.
Close(fd)) {
88 bool read,
bool write) {
90 if (file_action.
Open(fd, file_spec, read, write)) {
114 for (
size_t idx = 0, count =
m_file_actions.size(); idx < count; ++idx) {
150 m_flags.
Set(lldb::eLaunchFlagLaunchInSeparateProcessGroup);
152 m_flags.
Clear(lldb::eLaunchFlagLaunchInSeparateProcessGroup);
157 m_flags.
Set(lldb::eLaunchFlagShellExpandArguments);
177 LLDB_LOG(log,
"pid = {0}, signal = {1}, status = {2}", pid, signal, status);
182 llvm::Expected<HostThread> maybe_thread =
186 "failed to launch host thread: {0}");
205 bool any_free = stdin_free || stdout_free || stderr_free;
207 return llvm::Error::success();
209 LLDB_LOG(log,
"Generating a pty to use for stdin/out/err");
216 open_flags |= O_CLOEXEC;
218 if (llvm::Error Err =
m_pty->OpenFirstAvailablePrimary(open_flags))
221 const FileSpec secondary_file_spec(
m_pty->GetSecondaryName());
231 return llvm::Error::success();
235 Status &
error,
bool will_debug,
bool first_arg_is_full_shell_command,
236 uint32_t num_resumes) {
239 if (
GetFlags().Test(eLaunchFlagLaunchInShell)) {
244 if (argv ==
nullptr || argv[0] ==
nullptr)
246 Args shell_arguments;
249 if (triple.getOS() == llvm::Triple::Win32 &&
250 !triple.isWindowsCygwinEnvironment())
259 const char *argv0 = argv[0];
267 std::string new_path(
"PATH=\"");
268 const size_t empty_path_len = new_path.size();
271 new_path += working_dir.
GetPath();
273 llvm::SmallString<64> cwd;
274 if (! llvm::sys::fs::current_path(cwd))
277 std::string curr_path;
278 if (HostInfo::GetEnvironmentVar(
"PATH", curr_path)) {
279 if (new_path.size() > empty_path_len)
281 new_path += curr_path;
287 if (triple.getOS() != llvm::Triple::Win32 ||
288 triple.isWindowsCygwinEnvironment())
295 llvm::Triple::Apple &&
299 shell_command.
Printf(
" /usr/bin/arch -arch %s",
314 if (first_arg_is_full_shell_command) {
317 if (argv[0] && !argv[1])
318 shell_command.
Printf(
"%s", argv[0]);
322 for (
size_t i = 0; argv[i] !=
nullptr; ++i) {
324 if (safe_arg.empty())
336 error.SetErrorString(
"invalid shell path");
339 error.SetErrorString(
"not launching in shell");
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
#define LLDB_LOG_ERROR(log, error,...)
static bool separate(size_t count)
llvm::Triple & GetTriple()
Architecture triple accessor.
A command line argument class.
void AppendArgument(llvm::StringRef arg_str, char quote_char='\0')
Appends a new argument to the end of the list argument list.
static std::string GetShellSafeArgument(const FileSpec &shell, llvm::StringRef unsafe_arg)
const char ** GetConstArgumentVector() const
Gets the argument vector.
bool Duplicate(int fd, int dup_fd)
bool Open(int fd, const FileSpec &file_spec, bool read, bool write)
bool IsRelative() const
Returns true if the filespec represents a relative path.
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
void Clear()
Clears the object state.
static const char * DEV_NULL
bool ResolveExecutableLocation(FileSpec &file_spec)
Call into the Host to see if it can help find the file.
static FileSystem & Instance()
ValueType Clear(ValueType mask=~static_cast< ValueType >(0))
Clear one or more flags.
ValueType Set(ValueType mask)
Set one or more flags by logical OR'ing mask with the current flags.
static llvm::Expected< HostThread > StartMonitoringChildProcess(const MonitorChildProcessCallback &callback, lldb::pid_t pid)
Start monitoring a child process.
bool ProcessIDIsValid() const
lldb::pid_t GetProcessID() const
lldb::ListenerSP m_hijack_listener_sp
lldb::ListenerSP m_listener_sp
ArchSpec & GetArchitecture()
llvm::StringRef GetProcessPluginName() const
const FileSpec & GetShell() const
bool MonitorProcess() const
std::vector< FileAction > m_file_actions
llvm::Error SetUpPtyRedirection()
bool AppendOpenFileAction(int fd, const FileSpec &file_spec, bool read, bool write)
bool AppendSuppressFileAction(int fd, bool read, bool write)
bool AppendCloseFileAction(int fd)
static void NoOpMonitorCallback(lldb::pid_t pid, int signal, int status)
A Monitor callback which does not take any action on process events.
const FileAction * GetFileActionAtIndex(size_t idx) const
std::string m_plugin_name
std::shared_ptr< PseudoTerminal > m_pty
void SetShell(const FileSpec &shell)
const FileAction * GetFileActionForFD(int fd) const
void SetProcessPluginName(llvm::StringRef plugin)
bool ConvertArgumentsForLaunchingInShell(Status &error, bool will_debug, bool first_arg_is_full_shell_command, uint32_t num_resumes)
bool AppendDuplicateFileAction(int fd, int dup_fd)
void AppendFileAction(const FileAction &info)
void SetLaunchInSeparateProcessGroup(bool separate)
void SetShellExpandArguments(bool expand)
void SetDetachOnError(bool enable)
void SetResumeCount(uint32_t c)
void SetWorkingDirectory(const FileSpec &working_dir)
Host::MonitorChildProcessCallback m_monitor_callback
const FileSpec & GetWorkingDirectory() const
A pseudo terminal helper class.
llvm::StringRef GetString() const
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.