blob: 60fe26bb60dadfbd12605b094dacebf0b297188b [file] [log] [blame]
Todd Fiala6d6b55d2014-06-30 00:30:53 +00001//===-- ProcessLaunchInfo.cpp -----------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Eugene Zelenko9394d7722016-02-18 00:10:17 +000010// C Includes
11// C++ Includes
12#include <climits>
Todd Fiala2850b1b2014-06-30 23:51:35 +000013
Eugene Zelenko9394d7722016-02-18 00:10:17 +000014// Other libraries and framework includes
15// Project includes
Greg Clayton8012cad2014-11-17 19:39:20 +000016#include "lldb/Core/Debugger.h"
Zachary Turner190fadc2016-03-22 17:58:09 +000017#include "lldb/Host/Config.h"
Zachary Turner4eff2d32015-10-14 21:37:36 +000018#include "lldb/Host/FileSystem.h"
Zachary Turner190fadc2016-03-22 17:58:09 +000019#include "lldb/Host/HostInfo.h"
Zachary Turner696b5282014-08-14 16:01:25 +000020#include "lldb/Target/FileAction.h"
Zachary Turner190fadc2016-03-22 17:58:09 +000021#include "lldb/Target/ProcessLaunchInfo.h"
Todd Fiala6d6b55d2014-06-30 00:30:53 +000022#include "lldb/Target/Target.h"
Zachary Turner6f9e6902017-03-03 20:56:28 +000023#include "lldb/Utility/Log.h"
Zachary Turner2f3df612017-04-06 21:28:29 +000024#include "lldb/Utility/StreamString.h"
Todd Fiala6d6b55d2014-06-30 00:30:53 +000025
Zachary Turner190fadc2016-03-22 17:58:09 +000026#include "llvm/Support/ConvertUTF.h"
Pavel Labath1d5855b2017-01-23 15:56:45 +000027#include "llvm/Support/FileSystem.h"
Zachary Turner190fadc2016-03-22 17:58:09 +000028
29#if !defined(_WIN32)
30#include <limits.h>
31#endif
32
Todd Fiala6d6b55d2014-06-30 00:30:53 +000033using namespace lldb;
34using namespace lldb_private;
35
36//----------------------------------------------------------------------------
Todd Fiala6d6b55d2014-06-30 00:30:53 +000037// ProcessLaunchInfo member functions
38//----------------------------------------------------------------------------
39
Kate Stoneb9c1b512016-09-06 20:57:50 +000040ProcessLaunchInfo::ProcessLaunchInfo()
41 : ProcessInfo(), m_working_dir(), m_plugin_name(), m_flags(0),
Pavel Labath07d6f882017-12-11 10:09:14 +000042 m_file_actions(), m_pty(new PseudoTerminal), m_resume_count(0),
43 m_monitor_callback(nullptr), m_monitor_callback_baton(nullptr),
44 m_monitor_signals(false), m_listener_sp(), m_hijack_listener_sp() {}
Todd Fiala6d6b55d2014-06-30 00:30:53 +000045
Chaoren Lind3173f32015-05-29 19:52:29 +000046ProcessLaunchInfo::ProcessLaunchInfo(const FileSpec &stdin_file_spec,
47 const FileSpec &stdout_file_spec,
48 const FileSpec &stderr_file_spec,
49 const FileSpec &working_directory,
Kate Stoneb9c1b512016-09-06 20:57:50 +000050 uint32_t launch_flags)
51 : ProcessInfo(), m_working_dir(), m_plugin_name(), m_flags(launch_flags),
Pavel Labath07d6f882017-12-11 10:09:14 +000052 m_file_actions(), m_pty(new PseudoTerminal), m_resume_count(0),
53 m_monitor_callback(nullptr), m_monitor_callback_baton(nullptr),
54 m_monitor_signals(false), m_listener_sp(), m_hijack_listener_sp() {
Kate Stoneb9c1b512016-09-06 20:57:50 +000055 if (stdin_file_spec) {
Todd Fiala6d6b55d2014-06-30 00:30:53 +000056 FileAction file_action;
Kate Stoneb9c1b512016-09-06 20:57:50 +000057 const bool read = true;
58 const bool write = false;
59 if (file_action.Open(STDIN_FILENO, stdin_file_spec, read, write))
60 AppendFileAction(file_action);
61 }
62 if (stdout_file_spec) {
Todd Fiala6d6b55d2014-06-30 00:30:53 +000063 FileAction file_action;
Kate Stoneb9c1b512016-09-06 20:57:50 +000064 const bool read = false;
65 const bool write = true;
66 if (file_action.Open(STDOUT_FILENO, stdout_file_spec, read, write))
67 AppendFileAction(file_action);
68 }
69 if (stderr_file_spec) {
Todd Fiala6d6b55d2014-06-30 00:30:53 +000070 FileAction file_action;
Kate Stoneb9c1b512016-09-06 20:57:50 +000071 const bool read = false;
72 const bool write = true;
73 if (file_action.Open(STDERR_FILENO, stderr_file_spec, read, write))
74 AppendFileAction(file_action);
75 }
76 if (working_directory)
77 SetWorkingDirectory(working_directory);
Todd Fiala6d6b55d2014-06-30 00:30:53 +000078}
79
Kate Stoneb9c1b512016-09-06 20:57:50 +000080bool ProcessLaunchInfo::AppendCloseFileAction(int fd) {
81 FileAction file_action;
82 if (file_action.Close(fd)) {
83 AppendFileAction(file_action);
84 return true;
85 }
86 return false;
Todd Fiala6d6b55d2014-06-30 00:30:53 +000087}
88
Kate Stoneb9c1b512016-09-06 20:57:50 +000089bool ProcessLaunchInfo::AppendDuplicateFileAction(int fd, int dup_fd) {
90 FileAction file_action;
91 if (file_action.Duplicate(fd, dup_fd)) {
92 AppendFileAction(file_action);
93 return true;
94 }
95 return false;
Todd Fiala6d6b55d2014-06-30 00:30:53 +000096}
97
Kate Stoneb9c1b512016-09-06 20:57:50 +000098bool ProcessLaunchInfo::AppendOpenFileAction(int fd, const FileSpec &file_spec,
99 bool read, bool write) {
100 FileAction file_action;
101 if (file_action.Open(fd, file_spec, read, write)) {
102 AppendFileAction(file_action);
103 return true;
104 }
105 return false;
Todd Fiala6d6b55d2014-06-30 00:30:53 +0000106}
107
Kate Stoneb9c1b512016-09-06 20:57:50 +0000108bool ProcessLaunchInfo::AppendSuppressFileAction(int fd, bool read,
109 bool write) {
110 FileAction file_action;
111 if (file_action.Open(fd, FileSpec{FileSystem::DEV_NULL, false}, read,
112 write)) {
113 AppendFileAction(file_action);
114 return true;
115 }
116 return false;
Todd Fiala6d6b55d2014-06-30 00:30:53 +0000117}
118
Kate Stoneb9c1b512016-09-06 20:57:50 +0000119const FileAction *ProcessLaunchInfo::GetFileActionAtIndex(size_t idx) const {
120 if (idx < m_file_actions.size())
121 return &m_file_actions[idx];
122 return nullptr;
Todd Fiala6d6b55d2014-06-30 00:30:53 +0000123}
124
Kate Stoneb9c1b512016-09-06 20:57:50 +0000125const FileAction *ProcessLaunchInfo::GetFileActionForFD(int fd) const {
126 for (size_t idx = 0, count = m_file_actions.size(); idx < count; ++idx) {
127 if (m_file_actions[idx].GetFD() == fd)
128 return &m_file_actions[idx];
129 }
130 return nullptr;
Todd Fiala6d6b55d2014-06-30 00:30:53 +0000131}
132
Kate Stoneb9c1b512016-09-06 20:57:50 +0000133const FileSpec &ProcessLaunchInfo::GetWorkingDirectory() const {
134 return m_working_dir;
Todd Fiala6d6b55d2014-06-30 00:30:53 +0000135}
136
Kate Stoneb9c1b512016-09-06 20:57:50 +0000137void ProcessLaunchInfo::SetWorkingDirectory(const FileSpec &working_dir) {
138 m_working_dir = working_dir;
Todd Fiala6d6b55d2014-06-30 00:30:53 +0000139}
140
Kate Stoneb9c1b512016-09-06 20:57:50 +0000141const char *ProcessLaunchInfo::GetProcessPluginName() const {
142 return (m_plugin_name.empty() ? nullptr : m_plugin_name.c_str());
Todd Fiala6d6b55d2014-06-30 00:30:53 +0000143}
144
Zachary Turnerfe114832016-11-12 16:56:47 +0000145void ProcessLaunchInfo::SetProcessPluginName(llvm::StringRef plugin) {
146 m_plugin_name = plugin;
Todd Fiala6d6b55d2014-06-30 00:30:53 +0000147}
148
Kate Stoneb9c1b512016-09-06 20:57:50 +0000149const FileSpec &ProcessLaunchInfo::GetShell() const { return m_shell; }
150
151void ProcessLaunchInfo::SetShell(const FileSpec &shell) {
152 m_shell = shell;
153 if (m_shell) {
154 m_shell.ResolveExecutableLocation();
155 m_flags.Set(lldb::eLaunchFlagLaunchInShell);
156 } else
157 m_flags.Clear(lldb::eLaunchFlagLaunchInShell);
Todd Fiala6d6b55d2014-06-30 00:30:53 +0000158}
159
Kate Stoneb9c1b512016-09-06 20:57:50 +0000160void ProcessLaunchInfo::SetLaunchInSeparateProcessGroup(bool separate) {
161 if (separate)
162 m_flags.Set(lldb::eLaunchFlagLaunchInSeparateProcessGroup);
163 else
164 m_flags.Clear(lldb::eLaunchFlagLaunchInSeparateProcessGroup);
165}
166
167void ProcessLaunchInfo::SetShellExpandArguments(bool expand) {
168 if (expand)
169 m_flags.Set(lldb::eLaunchFlagShellExpandArguments);
170 else
171 m_flags.Clear(lldb::eLaunchFlagShellExpandArguments);
172}
173
174void ProcessLaunchInfo::Clear() {
175 ProcessInfo::Clear();
176 m_working_dir.Clear();
177 m_plugin_name.clear();
178 m_shell.Clear();
179 m_flags.Clear();
180 m_file_actions.clear();
181 m_resume_count = 0;
182 m_listener_sp.reset();
183 m_hijack_listener_sp.reset();
184}
185
186void ProcessLaunchInfo::SetMonitorProcessCallback(
187 const Host::MonitorChildProcessCallback &callback, bool monitor_signals) {
188 m_monitor_callback = callback;
189 m_monitor_signals = monitor_signals;
190}
191
192bool ProcessLaunchInfo::MonitorProcess() const {
193 if (m_monitor_callback && ProcessIDIsValid()) {
194 Host::StartMonitoringChildProcess(m_monitor_callback, GetProcessID(),
195 m_monitor_signals);
196 return true;
197 }
198 return false;
199}
200
201void ProcessLaunchInfo::SetDetachOnError(bool enable) {
202 if (enable)
203 m_flags.Set(lldb::eLaunchFlagDetachOnError);
204 else
205 m_flags.Clear(lldb::eLaunchFlagDetachOnError);
206}
207
208void ProcessLaunchInfo::FinalizeFileActions(Target *target,
209 bool default_to_use_pty) {
210 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
211
212 // If nothing for stdin or stdout or stderr was specified, then check the
Adrian Prantl05097242018-04-30 16:49:04 +0000213 // process for any default settings that were set with "settings set"
Kate Stoneb9c1b512016-09-06 20:57:50 +0000214 if (GetFileActionForFD(STDIN_FILENO) == nullptr ||
215 GetFileActionForFD(STDOUT_FILENO) == nullptr ||
216 GetFileActionForFD(STDERR_FILENO) == nullptr) {
217 if (log)
218 log->Printf("ProcessLaunchInfo::%s at least one of stdin/stdout/stderr "
219 "was not set, evaluating default handling",
220 __FUNCTION__);
221
222 if (m_flags.Test(eLaunchFlagLaunchInTTY)) {
Adrian Prantl05097242018-04-30 16:49:04 +0000223 // Do nothing, if we are launching in a remote terminal no file actions
224 // should be done at all.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000225 return;
Todd Fiala6d6b55d2014-06-30 00:30:53 +0000226 }
Todd Fiala6d6b55d2014-06-30 00:30:53 +0000227
Kate Stoneb9c1b512016-09-06 20:57:50 +0000228 if (m_flags.Test(eLaunchFlagDisableSTDIO)) {
229 if (log)
230 log->Printf("ProcessLaunchInfo::%s eLaunchFlagDisableSTDIO set, adding "
231 "suppression action for stdin, stdout and stderr",
232 __FUNCTION__);
233 AppendSuppressFileAction(STDIN_FILENO, true, false);
234 AppendSuppressFileAction(STDOUT_FILENO, false, true);
235 AppendSuppressFileAction(STDERR_FILENO, false, true);
236 } else {
Adrian Prantl05097242018-04-30 16:49:04 +0000237 // Check for any values that might have gotten set with any of: (lldb)
238 // settings set target.input-path (lldb) settings set target.output-path
Kate Stoneb9c1b512016-09-06 20:57:50 +0000239 // (lldb) settings set target.error-path
240 FileSpec in_file_spec;
241 FileSpec out_file_spec;
242 FileSpec err_file_spec;
243 if (target) {
Adrian Prantl05097242018-04-30 16:49:04 +0000244 // Only override with the target settings if we don't already have an
245 // action for in, out or error
Kate Stoneb9c1b512016-09-06 20:57:50 +0000246 if (GetFileActionForFD(STDIN_FILENO) == nullptr)
247 in_file_spec = target->GetStandardInputPath();
248 if (GetFileActionForFD(STDOUT_FILENO) == nullptr)
249 out_file_spec = target->GetStandardOutputPath();
250 if (GetFileActionForFD(STDERR_FILENO) == nullptr)
251 err_file_spec = target->GetStandardErrorPath();
252 }
Todd Fiala6d6b55d2014-06-30 00:30:53 +0000253
Kate Stoneb9c1b512016-09-06 20:57:50 +0000254 if (log)
255 log->Printf("ProcessLaunchInfo::%s target stdin='%s', target "
256 "stdout='%s', stderr='%s'",
257 __FUNCTION__,
258 in_file_spec ? in_file_spec.GetCString() : "<null>",
259 out_file_spec ? out_file_spec.GetCString() : "<null>",
260 err_file_spec ? err_file_spec.GetCString() : "<null>");
Todd Fiala75f47c32014-10-11 21:42:09 +0000261
Kate Stoneb9c1b512016-09-06 20:57:50 +0000262 if (in_file_spec) {
263 AppendOpenFileAction(STDIN_FILENO, in_file_spec, true, false);
Todd Fiala75f47c32014-10-11 21:42:09 +0000264 if (log)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000265 log->Printf(
266 "ProcessLaunchInfo::%s appended stdin open file action for %s",
267 __FUNCTION__, in_file_spec.GetCString());
268 }
Todd Fiala75f47c32014-10-11 21:42:09 +0000269
Kate Stoneb9c1b512016-09-06 20:57:50 +0000270 if (out_file_spec) {
271 AppendOpenFileAction(STDOUT_FILENO, out_file_spec, false, true);
272 if (log)
273 log->Printf(
274 "ProcessLaunchInfo::%s appended stdout open file action for %s",
275 __FUNCTION__, out_file_spec.GetCString());
276 }
Greg Claytonbf91f712015-07-10 18:04:46 +0000277
Kate Stoneb9c1b512016-09-06 20:57:50 +0000278 if (err_file_spec) {
279 AppendOpenFileAction(STDERR_FILENO, err_file_spec, false, true);
280 if (log)
281 log->Printf(
282 "ProcessLaunchInfo::%s appended stderr open file action for %s",
283 __FUNCTION__, err_file_spec.GetCString());
284 }
Todd Fiala6d6b55d2014-06-30 00:30:53 +0000285
Kate Stoneb9c1b512016-09-06 20:57:50 +0000286 if (default_to_use_pty &&
287 (!in_file_spec || !out_file_spec || !err_file_spec)) {
288 if (log)
289 log->Printf("ProcessLaunchInfo::%s default_to_use_pty is set, and at "
290 "least one stdin/stderr/stdout is unset, so generating a "
291 "pty to use for it",
292 __FUNCTION__);
Todd Fiala75f47c32014-10-11 21:42:09 +0000293
Kate Stoneb9c1b512016-09-06 20:57:50 +0000294 int open_flags = O_RDWR | O_NOCTTY;
Hafiz Abid Qadeerf6ee79c2016-12-15 15:00:41 +0000295#if !defined(_WIN32)
Adrian Prantl05097242018-04-30 16:49:04 +0000296 // We really shouldn't be specifying platform specific flags that are
297 // intended for a system call in generic code. But this will have to
298 // do for now.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000299 open_flags |= O_CLOEXEC;
Zachary Turner362a8132015-02-04 19:11:48 +0000300#endif
Kate Stoneb9c1b512016-09-06 20:57:50 +0000301 if (m_pty->OpenFirstAvailableMaster(open_flags, nullptr, 0)) {
302 const FileSpec slave_file_spec{m_pty->GetSlaveName(nullptr, 0),
303 false};
Todd Fiala6d6b55d2014-06-30 00:30:53 +0000304
Kate Stoneb9c1b512016-09-06 20:57:50 +0000305 // Only use the slave tty if we don't have anything specified for
306 // input and don't have an action for stdin
307 if (!in_file_spec && GetFileActionForFD(STDIN_FILENO) == nullptr) {
308 AppendOpenFileAction(STDIN_FILENO, slave_file_spec, true, false);
309 }
Todd Fiala6d6b55d2014-06-30 00:30:53 +0000310
Kate Stoneb9c1b512016-09-06 20:57:50 +0000311 // Only use the slave tty if we don't have anything specified for
312 // output and don't have an action for stdout
313 if (!out_file_spec && GetFileActionForFD(STDOUT_FILENO) == nullptr) {
314 AppendOpenFileAction(STDOUT_FILENO, slave_file_spec, false, true);
315 }
Todd Fiala6d6b55d2014-06-30 00:30:53 +0000316
Kate Stoneb9c1b512016-09-06 20:57:50 +0000317 // Only use the slave tty if we don't have anything specified for
318 // error and don't have an action for stderr
319 if (!err_file_spec && GetFileActionForFD(STDERR_FILENO) == nullptr) {
320 AppendOpenFileAction(STDERR_FILENO, slave_file_spec, false, true);
321 }
Todd Fiala6d6b55d2014-06-30 00:30:53 +0000322 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000323 }
Todd Fiala6d6b55d2014-06-30 00:30:53 +0000324 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000325 }
Todd Fiala6d6b55d2014-06-30 00:30:53 +0000326}
327
Kate Stoneb9c1b512016-09-06 20:57:50 +0000328bool ProcessLaunchInfo::ConvertArgumentsForLaunchingInShell(
Zachary Turner97206d52017-05-12 04:51:55 +0000329 Status &error, bool localhost, bool will_debug,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000330 bool first_arg_is_full_shell_command, int32_t num_resumes) {
331 error.Clear();
Todd Fiala6d6b55d2014-06-30 00:30:53 +0000332
Kate Stoneb9c1b512016-09-06 20:57:50 +0000333 if (GetFlags().Test(eLaunchFlagLaunchInShell)) {
334 if (m_shell) {
335 std::string shell_executable = m_shell.GetPath();
Todd Fiala6d6b55d2014-06-30 00:30:53 +0000336
Kate Stoneb9c1b512016-09-06 20:57:50 +0000337 const char **argv = GetArguments().GetConstArgumentVector();
338 if (argv == nullptr || argv[0] == nullptr)
339 return false;
340 Args shell_arguments;
341 std::string safe_arg;
Zachary Turnerecbb0bb2016-09-19 17:54:06 +0000342 shell_arguments.AppendArgument(shell_executable);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000343 const llvm::Triple &triple = GetArchitecture().GetTriple();
344 if (triple.getOS() == llvm::Triple::Win32 &&
345 !triple.isWindowsCygwinEnvironment())
Zachary Turnerecbb0bb2016-09-19 17:54:06 +0000346 shell_arguments.AppendArgument(llvm::StringRef("/C"));
Kate Stoneb9c1b512016-09-06 20:57:50 +0000347 else
Zachary Turnerecbb0bb2016-09-19 17:54:06 +0000348 shell_arguments.AppendArgument(llvm::StringRef("-c"));
Zachary Turner270e99a2014-12-08 21:36:42 +0000349
Kate Stoneb9c1b512016-09-06 20:57:50 +0000350 StreamString shell_command;
351 if (will_debug) {
Adrian Prantl05097242018-04-30 16:49:04 +0000352 // Add a modified PATH environment variable in case argv[0] is a
353 // relative path.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000354 const char *argv0 = argv[0];
355 FileSpec arg_spec(argv0, false);
356 if (arg_spec.IsRelative()) {
Adrian Prantl05097242018-04-30 16:49:04 +0000357 // We have a relative path to our executable which may not work if we
358 // just try to run "a.out" (without it being converted to "./a.out")
Kate Stoneb9c1b512016-09-06 20:57:50 +0000359 FileSpec working_dir = GetWorkingDirectory();
360 // Be sure to put quotes around PATH's value in case any paths have
361 // spaces...
362 std::string new_path("PATH=\"");
363 const size_t empty_path_len = new_path.size();
Todd Fiala6d6b55d2014-06-30 00:30:53 +0000364
Kate Stoneb9c1b512016-09-06 20:57:50 +0000365 if (working_dir) {
366 new_path += working_dir.GetPath();
367 } else {
Pavel Labath1d5855b2017-01-23 15:56:45 +0000368 llvm::SmallString<64> cwd;
369 if (! llvm::sys::fs::current_path(cwd))
Kate Stoneb9c1b512016-09-06 20:57:50 +0000370 new_path += cwd;
371 }
372 std::string curr_path;
373 if (HostInfo::GetEnvironmentVar("PATH", curr_path)) {
374 if (new_path.size() > empty_path_len)
375 new_path += ':';
376 new_path += curr_path;
377 }
378 new_path += "\" ";
Malcolm Parsons771ef6d2016-11-02 20:34:10 +0000379 shell_command.PutCString(new_path);
Todd Fiala6d6b55d2014-06-30 00:30:53 +0000380 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000381
382 if (triple.getOS() != llvm::Triple::Win32 ||
383 triple.isWindowsCygwinEnvironment())
384 shell_command.PutCString("exec");
385
386 // Only Apple supports /usr/bin/arch being able to specify the
387 // architecture
388 if (GetArchitecture().IsValid() && // Valid architecture
389 GetArchitecture().GetTriple().getVendor() ==
390 llvm::Triple::Apple && // Apple only
391 GetArchitecture().GetCore() !=
392 ArchSpec::eCore_x86_64_x86_64h) // Don't do this for x86_64h
393 {
394 shell_command.Printf(" /usr/bin/arch -arch %s",
395 GetArchitecture().GetArchitectureName());
396 // Set the resume count to 2:
397 // 1 - stop in shell
398 // 2 - stop in /usr/bin/arch
399 // 3 - then we will stop in our program
400 SetResumeCount(num_resumes + 1);
401 } else {
402 // Set the resume count to 1:
403 // 1 - stop in shell
404 // 2 - then we will stop in our program
405 SetResumeCount(num_resumes);
406 }
407 }
408
409 if (first_arg_is_full_shell_command) {
Adrian Prantl05097242018-04-30 16:49:04 +0000410 // There should only be one argument that is the shell command itself
411 // to be used as is
Kate Stoneb9c1b512016-09-06 20:57:50 +0000412 if (argv[0] && !argv[1])
413 shell_command.Printf("%s", argv[0]);
Todd Fiala6d6b55d2014-06-30 00:30:53 +0000414 else
Kate Stoneb9c1b512016-09-06 20:57:50 +0000415 return false;
416 } else {
417 for (size_t i = 0; argv[i] != nullptr; ++i) {
418 const char *arg =
419 Args::GetShellSafeArgument(m_shell, argv[i], safe_arg);
420 shell_command.Printf(" %s", arg);
Todd Fiala6d6b55d2014-06-30 00:30:53 +0000421 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000422 }
Zachary Turnerecbb0bb2016-09-19 17:54:06 +0000423 shell_arguments.AppendArgument(shell_command.GetString());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000424 m_executable = m_shell;
425 m_arguments = shell_arguments;
426 return true;
427 } else {
428 error.SetErrorString("invalid shell path");
Todd Fiala6d6b55d2014-06-30 00:30:53 +0000429 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000430 } else {
431 error.SetErrorString("not launching in shell");
432 }
433 return false;
Todd Fiala6d6b55d2014-06-30 00:30:53 +0000434}
Greg Clayton8012cad2014-11-17 19:39:20 +0000435
Kate Stoneb9c1b512016-09-06 20:57:50 +0000436ListenerSP ProcessLaunchInfo::GetListenerForProcess(Debugger &debugger) {
437 if (m_listener_sp)
438 return m_listener_sp;
439 else
440 return debugger.GetListener();
Greg Clayton8012cad2014-11-17 19:39:20 +0000441}