blob: 403b10e19bb1776605ed93720d5eb1a4dc8cd1b9 [file] [log] [blame]
Greg Claytone4b9c1f2011-03-08 22:40:15 +00001//===-- Platform.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
10#include "lldb/Target/Platform.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
16#include "lldb/Core/Error.h"
Greg Claytonb72d0f02011-04-12 05:54:46 +000017#include "lldb/Core/Log.h"
Greg Claytone4b9c1f2011-03-08 22:40:15 +000018#include "lldb/Core/PluginManager.h"
19#include "lldb/Host/FileSpec.h"
Greg Claytonb1888f22011-03-19 01:12:21 +000020#include "lldb/Host/Host.h"
Greg Claytonb72d0f02011-04-12 05:54:46 +000021#include "lldb/Target/Process.h"
Greg Claytone4b9c1f2011-03-08 22:40:15 +000022#include "lldb/Target/Target.h"
23
24using namespace lldb;
25using namespace lldb_private;
26
27// Use a singleton function for g_local_platform_sp to avoid init
28// constructors since LLDB is often part of a shared library
29static PlatformSP&
30GetDefaultPlatformSP ()
31{
32 static PlatformSP g_default_platform_sp;
33 return g_default_platform_sp;
34}
35
Greg Claytone4b9c1f2011-03-08 22:40:15 +000036static Mutex &
37GetConnectedPlatformListMutex ()
38{
39 static Mutex g_remote_connected_platforms_mutex (Mutex::eMutexTypeRecursive);
40 return g_remote_connected_platforms_mutex;
41}
42static std::vector<PlatformSP> &
43GetConnectedPlatformList ()
44{
45 static std::vector<PlatformSP> g_remote_connected_platforms;
46 return g_remote_connected_platforms;
47}
48
Greg Clayton5e342f52011-04-13 22:47:15 +000049
50const char *
51Platform::GetHostPlatformName ()
52{
53 return "host";
54}
55
Greg Claytone4b9c1f2011-03-08 22:40:15 +000056//------------------------------------------------------------------
57/// Get the native host platform plug-in.
58///
59/// There should only be one of these for each host that LLDB runs
60/// upon that should be statically compiled in and registered using
61/// preprocessor macros or other similar build mechanisms.
62///
63/// This platform will be used as the default platform when launching
64/// or attaching to processes unless another platform is specified.
65//------------------------------------------------------------------
66PlatformSP
67Platform::GetDefaultPlatform ()
68{
69 return GetDefaultPlatformSP ();
70}
71
72void
73Platform::SetDefaultPlatform (const lldb::PlatformSP &platform_sp)
74{
75 // The native platform should use its static void Platform::Initialize()
76 // function to register itself as the native platform.
77 GetDefaultPlatformSP () = platform_sp;
78}
79
Greg Claytone4b9c1f2011-03-08 22:40:15 +000080Error
Greg Claytoncb8977d2011-03-23 00:09:55 +000081Platform::GetFile (const FileSpec &platform_file,
82 const UUID *uuid_ptr,
83 FileSpec &local_file)
Greg Claytone4b9c1f2011-03-08 22:40:15 +000084{
85 // Default to the local case
86 local_file = platform_file;
87 return Error();
88}
89
Greg Clayton24bc5d92011-03-30 18:16:51 +000090Error
Greg Clayton444fe992012-02-26 05:51:37 +000091Platform::GetSharedModule (const ModuleSpec &module_spec,
Greg Clayton24bc5d92011-03-30 18:16:51 +000092 ModuleSP &module_sp,
Greg Clayton9ce95382012-02-13 23:10:39 +000093 const FileSpecList *module_search_paths_ptr,
Greg Clayton24bc5d92011-03-30 18:16:51 +000094 ModuleSP *old_module_sp_ptr,
95 bool *did_create_ptr)
96{
97 // Don't do any path remapping for the default implementation
98 // of the platform GetSharedModule function, just call through
99 // to our static ModuleList function. Platform subclasses that
100 // implement remote debugging, might have a developer kits
101 // installed that have cached versions of the files for the
102 // remote target, or might implement a download and cache
103 // locally implementation.
104 const bool always_create = false;
Greg Clayton444fe992012-02-26 05:51:37 +0000105 return ModuleList::GetSharedModule (module_spec,
Greg Clayton24bc5d92011-03-30 18:16:51 +0000106 module_sp,
Greg Clayton9ce95382012-02-13 23:10:39 +0000107 module_search_paths_ptr,
Greg Clayton24bc5d92011-03-30 18:16:51 +0000108 old_module_sp_ptr,
109 did_create_ptr,
110 always_create);
111}
112
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000113
114PlatformSP
Greg Claytonb1888f22011-03-19 01:12:21 +0000115Platform::Create (const char *platform_name, Error &error)
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000116{
117 PlatformCreateInstance create_callback = NULL;
118 lldb::PlatformSP platform_sp;
Greg Claytonb1888f22011-03-19 01:12:21 +0000119 if (platform_name && platform_name[0])
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000120 {
121 create_callback = PluginManager::GetPlatformCreateCallbackForPluginName (platform_name);
122 if (create_callback)
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000123 platform_sp.reset(create_callback());
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000124 else
Greg Claytonb1888f22011-03-19 01:12:21 +0000125 error.SetErrorStringWithFormat ("unable to find a plug-in for the platform named \"%s\"", platform_name);
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000126 }
127 else
Greg Claytonb1888f22011-03-19 01:12:21 +0000128 error.SetErrorString ("invalid platform name");
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000129 return platform_sp;
130}
131
132uint32_t
133Platform::GetNumConnectedRemotePlatforms ()
134{
135 Mutex::Locker locker (GetConnectedPlatformListMutex ());
136 return GetConnectedPlatformList().size();
137}
138
139PlatformSP
140Platform::GetConnectedRemotePlatformAtIndex (uint32_t idx)
141{
142 PlatformSP platform_sp;
143 {
144 Mutex::Locker locker (GetConnectedPlatformListMutex ());
145 if (idx < GetConnectedPlatformList().size())
146 platform_sp = GetConnectedPlatformList ()[idx];
147 }
148 return platform_sp;
149}
150
151//------------------------------------------------------------------
152/// Default Constructor
153//------------------------------------------------------------------
Greg Claytonb1888f22011-03-19 01:12:21 +0000154Platform::Platform (bool is_host) :
155 m_is_host (is_host),
Greg Claytonb1888f22011-03-19 01:12:21 +0000156 m_os_version_set_while_connected (false),
157 m_system_arch_set_while_connected (false),
Greg Clayton604f0d32011-06-17 03:31:01 +0000158 m_sdk_sysroot (),
159 m_sdk_build (),
Greg Claytonb1888f22011-03-19 01:12:21 +0000160 m_remote_url (),
Greg Clayton58e26e02011-03-24 04:28:38 +0000161 m_name (),
Greg Claytonb1888f22011-03-19 01:12:21 +0000162 m_major_os_version (UINT32_MAX),
163 m_minor_os_version (UINT32_MAX),
Greg Clayton24bc5d92011-03-30 18:16:51 +0000164 m_update_os_version (UINT32_MAX),
165 m_system_arch(),
166 m_uid_map_mutex (Mutex::eMutexTypeNormal),
167 m_gid_map_mutex (Mutex::eMutexTypeNormal),
168 m_uid_map(),
169 m_gid_map(),
170 m_max_uid_name_len (0),
171 m_max_gid_name_len (0)
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000172{
Greg Claytonb72d0f02011-04-12 05:54:46 +0000173 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
174 if (log)
175 log->Printf ("%p Platform::Platform()", this);
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000176}
177
178//------------------------------------------------------------------
179/// Destructor.
180///
181/// The destructor is virtual since this class is designed to be
182/// inherited from by the plug-in instance.
183//------------------------------------------------------------------
184Platform::~Platform()
185{
Greg Claytonb72d0f02011-04-12 05:54:46 +0000186 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
187 if (log)
188 log->Printf ("%p Platform::~Platform()", this);
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000189}
190
Greg Clayton58e26e02011-03-24 04:28:38 +0000191void
192Platform::GetStatus (Stream &strm)
193{
194 uint32_t major = UINT32_MAX;
195 uint32_t minor = UINT32_MAX;
196 uint32_t update = UINT32_MAX;
197 std::string s;
Greg Clayton24bc5d92011-03-30 18:16:51 +0000198 strm.Printf (" Platform: %s\n", GetShortPluginName());
Greg Clayton58e26e02011-03-24 04:28:38 +0000199
200 ArchSpec arch (GetSystemArchitecture());
201 if (arch.IsValid())
202 {
203 if (!arch.GetTriple().str().empty())
Greg Clayton24bc5d92011-03-30 18:16:51 +0000204 strm.Printf(" Triple: %s\n", arch.GetTriple().str().c_str());
Greg Clayton58e26e02011-03-24 04:28:38 +0000205 }
206
207 if (GetOSVersion(major, minor, update))
208 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000209 strm.Printf("OS Version: %u", major);
Greg Clayton58e26e02011-03-24 04:28:38 +0000210 if (minor != UINT32_MAX)
211 strm.Printf(".%u", minor);
212 if (update != UINT32_MAX)
213 strm.Printf(".%u", update);
214
215 if (GetOSBuildString (s))
216 strm.Printf(" (%s)", s.c_str());
217
218 strm.EOL();
219 }
220
221 if (GetOSKernelDescription (s))
Greg Clayton24bc5d92011-03-30 18:16:51 +0000222 strm.Printf(" Kernel: %s\n", s.c_str());
Greg Clayton58e26e02011-03-24 04:28:38 +0000223
224 if (IsHost())
225 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000226 strm.Printf(" Hostname: %s\n", GetHostname());
Greg Clayton58e26e02011-03-24 04:28:38 +0000227 }
228 else
229 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000230 const bool is_connected = IsConnected();
231 if (is_connected)
232 strm.Printf(" Hostname: %s\n", GetHostname());
233 strm.Printf(" Connected: %s\n", is_connected ? "yes" : "no");
Greg Clayton58e26e02011-03-24 04:28:38 +0000234 }
235}
236
Greg Claytonb1888f22011-03-19 01:12:21 +0000237
238bool
239Platform::GetOSVersion (uint32_t &major,
240 uint32_t &minor,
241 uint32_t &update)
242{
243 bool success = m_major_os_version != UINT32_MAX;
244 if (IsHost())
245 {
246 if (!success)
247 {
248 // We have a local host platform
249 success = Host::GetOSVersion (m_major_os_version,
250 m_minor_os_version,
251 m_update_os_version);
252 m_os_version_set_while_connected = success;
253 }
254 }
255 else
256 {
257 // We have a remote platform. We can only fetch the remote
258 // OS version if we are connected, and we don't want to do it
259 // more than once.
260
261 const bool is_connected = IsConnected();
262
Greg Clayton58e26e02011-03-24 04:28:38 +0000263 bool fetch = false;
Greg Claytonb1888f22011-03-19 01:12:21 +0000264 if (success)
265 {
266 // We have valid OS version info, check to make sure it wasn't
267 // manually set prior to connecting. If it was manually set prior
268 // to connecting, then lets fetch the actual OS version info
269 // if we are now connected.
270 if (is_connected && !m_os_version_set_while_connected)
Greg Clayton58e26e02011-03-24 04:28:38 +0000271 fetch = true;
Greg Claytonb1888f22011-03-19 01:12:21 +0000272 }
273 else
274 {
275 // We don't have valid OS version info, fetch it if we are connected
Greg Clayton58e26e02011-03-24 04:28:38 +0000276 fetch = is_connected;
Greg Claytonb1888f22011-03-19 01:12:21 +0000277 }
278
Greg Clayton58e26e02011-03-24 04:28:38 +0000279 if (fetch)
Greg Claytonb1888f22011-03-19 01:12:21 +0000280 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000281 success = GetRemoteOSVersion ();
Greg Claytonb1888f22011-03-19 01:12:21 +0000282 m_os_version_set_while_connected = success;
283 }
284 }
285
286 if (success)
287 {
288 major = m_major_os_version;
289 minor = m_minor_os_version;
290 update = m_update_os_version;
291 }
292 return success;
293}
Greg Clayton58e26e02011-03-24 04:28:38 +0000294
295bool
296Platform::GetOSBuildString (std::string &s)
297{
298 if (IsHost())
299 return Host::GetOSBuildString (s);
300 else
301 return GetRemoteOSBuildString (s);
302}
303
304bool
305Platform::GetOSKernelDescription (std::string &s)
306{
307 if (IsHost())
308 return Host::GetOSKernelDescription (s);
309 else
310 return GetRemoteOSKernelDescription (s);
311}
312
313const char *
Greg Claytonb72d0f02011-04-12 05:54:46 +0000314Platform::GetName ()
315{
316 const char *name = GetHostname();
317 if (name == NULL || name[0] == '\0')
318 name = GetShortPluginName();
319 return name;
320}
321
322const char *
Greg Clayton58e26e02011-03-24 04:28:38 +0000323Platform::GetHostname ()
324{
Greg Clayton5e342f52011-04-13 22:47:15 +0000325 if (IsHost())
326 return "localhost";
Greg Clayton24bc5d92011-03-30 18:16:51 +0000327
328 if (m_name.empty())
329 return NULL;
330 return m_name.c_str();
331}
332
333const char *
334Platform::GetUserName (uint32_t uid)
335{
336 const char *user_name = GetCachedUserName(uid);
337 if (user_name)
338 return user_name;
339 if (IsHost())
340 {
341 std::string name;
342 if (Host::GetUserName(uid, name))
343 return SetCachedUserName (uid, name.c_str(), name.size());
344 }
Greg Clayton58e26e02011-03-24 04:28:38 +0000345 return NULL;
346}
347
Greg Clayton24bc5d92011-03-30 18:16:51 +0000348const char *
349Platform::GetGroupName (uint32_t gid)
350{
351 const char *group_name = GetCachedGroupName(gid);
352 if (group_name)
353 return group_name;
354 if (IsHost())
355 {
356 std::string name;
357 if (Host::GetGroupName(gid, name))
358 return SetCachedGroupName (gid, name.c_str(), name.size());
359 }
360 return NULL;
361}
Greg Clayton58e26e02011-03-24 04:28:38 +0000362
Greg Claytonb1888f22011-03-19 01:12:21 +0000363bool
364Platform::SetOSVersion (uint32_t major,
365 uint32_t minor,
366 uint32_t update)
367{
368 if (IsHost())
369 {
370 // We don't need anyone setting the OS version for the host platform,
371 // we should be able to figure it out by calling Host::GetOSVersion(...).
372 return false;
373 }
374 else
375 {
376 // We have a remote platform, allow setting the target OS version if
377 // we aren't connected, since if we are connected, we should be able to
378 // request the remote OS version from the connected platform.
379 if (IsConnected())
380 return false;
381 else
382 {
383 // We aren't connected and we might want to set the OS version
384 // ahead of time before we connect so we can peruse files and
385 // use a local SDK or PDK cache of support files to disassemble
386 // or do other things.
387 m_major_os_version = major;
388 m_minor_os_version = minor;
389 m_update_os_version = update;
390 return true;
391 }
392 }
393 return false;
394}
395
396
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000397Error
398Platform::ResolveExecutable (const FileSpec &exe_file,
399 const ArchSpec &exe_arch,
Greg Clayton9ce95382012-02-13 23:10:39 +0000400 lldb::ModuleSP &exe_module_sp,
401 const FileSpecList *module_search_paths_ptr)
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000402{
403 Error error;
404 if (exe_file.Exists())
405 {
Greg Clayton444fe992012-02-26 05:51:37 +0000406 ModuleSpec module_spec (exe_file, exe_arch);
407 if (module_spec.GetArchitecture().IsValid())
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000408 {
Greg Clayton444fe992012-02-26 05:51:37 +0000409 error = ModuleList::GetSharedModule (module_spec,
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000410 exe_module_sp,
Greg Clayton9ce95382012-02-13 23:10:39 +0000411 module_search_paths_ptr,
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000412 NULL,
413 NULL);
414 }
415 else
416 {
417 // No valid architecture was specified, ask the platform for
418 // the architectures that we should be using (in the correct order)
419 // and see if we can find a match that way
Greg Clayton444fe992012-02-26 05:51:37 +0000420 for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, module_spec.GetArchitecture()); ++idx)
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000421 {
Greg Clayton444fe992012-02-26 05:51:37 +0000422 error = ModuleList::GetSharedModule (module_spec,
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000423 exe_module_sp,
Greg Clayton9ce95382012-02-13 23:10:39 +0000424 module_search_paths_ptr,
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000425 NULL,
426 NULL);
427 // Did we find an executable using one of the
428 if (error.Success() && exe_module_sp)
429 break;
430 }
431 }
432 }
433 else
434 {
435 error.SetErrorStringWithFormat ("'%s%s%s' does not exist",
436 exe_file.GetDirectory().AsCString(""),
437 exe_file.GetDirectory() ? "/" : "",
438 exe_file.GetFilename().AsCString(""));
439 }
440 return error;
441}
442
Greg Claytonf2bf8702011-08-11 16:25:18 +0000443bool
444Platform::ResolveRemotePath (const FileSpec &platform_path,
445 FileSpec &resolved_platform_path)
446{
447 resolved_platform_path = platform_path;
448 return resolved_platform_path.ResolvePath();
449}
450
Greg Claytonb1888f22011-03-19 01:12:21 +0000451
452const ArchSpec &
453Platform::GetSystemArchitecture()
454{
455 if (IsHost())
456 {
457 if (!m_system_arch.IsValid())
458 {
459 // We have a local host platform
460 m_system_arch = Host::GetArchitecture();
461 m_system_arch_set_while_connected = m_system_arch.IsValid();
462 }
463 }
464 else
465 {
466 // We have a remote platform. We can only fetch the remote
467 // system architecture if we are connected, and we don't want to do it
468 // more than once.
469
470 const bool is_connected = IsConnected();
471
472 bool fetch = false;
473 if (m_system_arch.IsValid())
474 {
475 // We have valid OS version info, check to make sure it wasn't
476 // manually set prior to connecting. If it was manually set prior
477 // to connecting, then lets fetch the actual OS version info
478 // if we are now connected.
479 if (is_connected && !m_system_arch_set_while_connected)
480 fetch = true;
481 }
482 else
483 {
484 // We don't have valid OS version info, fetch it if we are connected
485 fetch = is_connected;
486 }
487
488 if (fetch)
489 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000490 m_system_arch = GetRemoteSystemArchitecture ();
Greg Claytonb1888f22011-03-19 01:12:21 +0000491 m_system_arch_set_while_connected = m_system_arch.IsValid();
492 }
493 }
494 return m_system_arch;
495}
496
497
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000498Error
Greg Claytoncb8977d2011-03-23 00:09:55 +0000499Platform::ConnectRemote (Args& args)
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000500{
501 Error error;
Greg Claytoncb8977d2011-03-23 00:09:55 +0000502 if (IsHost())
503 error.SetErrorStringWithFormat ("The currently selected platform (%s) is the host platform and is always connected.", GetShortPluginName());
504 else
505 error.SetErrorStringWithFormat ("Platform::ConnectRemote() is not supported by %s", GetShortPluginName());
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000506 return error;
507}
508
509Error
Greg Claytoncb8977d2011-03-23 00:09:55 +0000510Platform::DisconnectRemote ()
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000511{
512 Error error;
Greg Claytoncb8977d2011-03-23 00:09:55 +0000513 if (IsHost())
514 error.SetErrorStringWithFormat ("The currently selected platform (%s) is the host platform and is always connected.", GetShortPluginName());
515 else
516 error.SetErrorStringWithFormat ("Platform::DisconnectRemote() is not supported by %s", GetShortPluginName());
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000517 return error;
518}
Greg Clayton24bc5d92011-03-30 18:16:51 +0000519
520bool
Greg Claytonb72d0f02011-04-12 05:54:46 +0000521Platform::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
Greg Clayton24bc5d92011-03-30 18:16:51 +0000522{
523 // Take care of the host case so that each subclass can just
Greg Claytonb72d0f02011-04-12 05:54:46 +0000524 // call this function to get the host functionality.
Greg Clayton24bc5d92011-03-30 18:16:51 +0000525 if (IsHost())
526 return Host::GetProcessInfo (pid, process_info);
527 return false;
528}
529
530uint32_t
Greg Claytonb72d0f02011-04-12 05:54:46 +0000531Platform::FindProcesses (const ProcessInstanceInfoMatch &match_info,
532 ProcessInstanceInfoList &process_infos)
Greg Clayton24bc5d92011-03-30 18:16:51 +0000533{
Greg Claytonb72d0f02011-04-12 05:54:46 +0000534 // Take care of the host case so that each subclass can just
535 // call this function to get the host functionality.
Greg Clayton24bc5d92011-03-30 18:16:51 +0000536 uint32_t match_count = 0;
537 if (IsHost())
538 match_count = Host::FindProcesses (match_info, process_infos);
539 return match_count;
540}
Greg Claytonb72d0f02011-04-12 05:54:46 +0000541
542
543Error
544Platform::LaunchProcess (ProcessLaunchInfo &launch_info)
545{
546 Error error;
547 // Take care of the host case so that each subclass can just
548 // call this function to get the host functionality.
549 if (IsHost())
550 error = Host::LaunchProcess (launch_info);
551 else
552 error.SetErrorString ("base lldb_private::Platform class can't launch remote processes");
553 return error;
554}
555
556lldb::ProcessSP
557Platform::DebugProcess (ProcessLaunchInfo &launch_info,
558 Debugger &debugger,
559 Target *target, // Can be NULL, if NULL create a new target, else use existing one
560 Listener &listener,
561 Error &error)
562{
563 ProcessSP process_sp;
564 // Make sure we stop at the entry point
565 launch_info.GetFlags ().Set (eLaunchFlagDebug);
566 error = LaunchProcess (launch_info);
567 if (error.Success())
568 {
Greg Clayton527154d2011-11-15 03:53:30 +0000569 if (launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
Greg Claytonb72d0f02011-04-12 05:54:46 +0000570 {
Greg Clayton527154d2011-11-15 03:53:30 +0000571 ProcessAttachInfo attach_info (launch_info);
572 process_sp = Attach (attach_info, debugger, target, listener, error);
Greg Claytonffa43a62011-11-17 04:46:02 +0000573 if (process_sp)
574 {
575 // Since we attached to the process, it will think it needs to detach
576 // if the process object just goes away without an explicit call to
577 // Process::Kill() or Process::Detach(), so let it know to kill the
578 // process if this happens.
579 process_sp->SetShouldDetach (false);
Greg Clayton464c6162011-11-17 22:14:31 +0000580
581 // If we didn't have any file actions, the pseudo terminal might
582 // have been used where the slave side was given as the file to
583 // open for stdin/out/err after we have already opened the master
584 // so we can read/write stdin/out/err.
585 int pty_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor();
586 if (pty_fd != lldb_utility::PseudoTerminal::invalid_fd)
587 {
588 process_sp->SetSTDIOFileDescriptor(pty_fd);
589 }
Greg Claytonffa43a62011-11-17 04:46:02 +0000590 }
Greg Claytonb72d0f02011-04-12 05:54:46 +0000591 }
592 }
593 return process_sp;
594}