blob: 1c07db9c64451d9f342d3b768c16a93d3dd9f282 [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
91Platform::GetSharedModule (const FileSpec &platform_file,
92 const ArchSpec &arch,
93 const UUID *uuid_ptr,
94 const ConstString *object_name_ptr,
95 off_t object_offset,
96 ModuleSP &module_sp,
Greg Clayton9ce95382012-02-13 23:10:39 +000097 const FileSpecList *module_search_paths_ptr,
Greg Clayton24bc5d92011-03-30 18:16:51 +000098 ModuleSP *old_module_sp_ptr,
99 bool *did_create_ptr)
100{
101 // Don't do any path remapping for the default implementation
102 // of the platform GetSharedModule function, just call through
103 // to our static ModuleList function. Platform subclasses that
104 // implement remote debugging, might have a developer kits
105 // installed that have cached versions of the files for the
106 // remote target, or might implement a download and cache
107 // locally implementation.
108 const bool always_create = false;
109 return ModuleList::GetSharedModule (platform_file,
110 arch,
111 uuid_ptr,
112 object_name_ptr,
113 object_offset,
114 module_sp,
Greg Clayton9ce95382012-02-13 23:10:39 +0000115 module_search_paths_ptr,
Greg Clayton24bc5d92011-03-30 18:16:51 +0000116 old_module_sp_ptr,
117 did_create_ptr,
118 always_create);
119}
120
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000121
122PlatformSP
Greg Claytonb1888f22011-03-19 01:12:21 +0000123Platform::Create (const char *platform_name, Error &error)
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000124{
125 PlatformCreateInstance create_callback = NULL;
126 lldb::PlatformSP platform_sp;
Greg Claytonb1888f22011-03-19 01:12:21 +0000127 if (platform_name && platform_name[0])
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000128 {
129 create_callback = PluginManager::GetPlatformCreateCallbackForPluginName (platform_name);
130 if (create_callback)
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000131 platform_sp.reset(create_callback());
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000132 else
Greg Claytonb1888f22011-03-19 01:12:21 +0000133 error.SetErrorStringWithFormat ("unable to find a plug-in for the platform named \"%s\"", platform_name);
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000134 }
135 else
Greg Claytonb1888f22011-03-19 01:12:21 +0000136 error.SetErrorString ("invalid platform name");
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000137 return platform_sp;
138}
139
140uint32_t
141Platform::GetNumConnectedRemotePlatforms ()
142{
143 Mutex::Locker locker (GetConnectedPlatformListMutex ());
144 return GetConnectedPlatformList().size();
145}
146
147PlatformSP
148Platform::GetConnectedRemotePlatformAtIndex (uint32_t idx)
149{
150 PlatformSP platform_sp;
151 {
152 Mutex::Locker locker (GetConnectedPlatformListMutex ());
153 if (idx < GetConnectedPlatformList().size())
154 platform_sp = GetConnectedPlatformList ()[idx];
155 }
156 return platform_sp;
157}
158
159//------------------------------------------------------------------
160/// Default Constructor
161//------------------------------------------------------------------
Greg Claytonb1888f22011-03-19 01:12:21 +0000162Platform::Platform (bool is_host) :
163 m_is_host (is_host),
Greg Claytonb1888f22011-03-19 01:12:21 +0000164 m_os_version_set_while_connected (false),
165 m_system_arch_set_while_connected (false),
Greg Clayton604f0d32011-06-17 03:31:01 +0000166 m_sdk_sysroot (),
167 m_sdk_build (),
Greg Claytonb1888f22011-03-19 01:12:21 +0000168 m_remote_url (),
Greg Clayton58e26e02011-03-24 04:28:38 +0000169 m_name (),
Greg Claytonb1888f22011-03-19 01:12:21 +0000170 m_major_os_version (UINT32_MAX),
171 m_minor_os_version (UINT32_MAX),
Greg Clayton24bc5d92011-03-30 18:16:51 +0000172 m_update_os_version (UINT32_MAX),
173 m_system_arch(),
174 m_uid_map_mutex (Mutex::eMutexTypeNormal),
175 m_gid_map_mutex (Mutex::eMutexTypeNormal),
176 m_uid_map(),
177 m_gid_map(),
178 m_max_uid_name_len (0),
179 m_max_gid_name_len (0)
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000180{
Greg Claytonb72d0f02011-04-12 05:54:46 +0000181 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
182 if (log)
183 log->Printf ("%p Platform::Platform()", this);
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000184}
185
186//------------------------------------------------------------------
187/// Destructor.
188///
189/// The destructor is virtual since this class is designed to be
190/// inherited from by the plug-in instance.
191//------------------------------------------------------------------
192Platform::~Platform()
193{
Greg Claytonb72d0f02011-04-12 05:54:46 +0000194 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
195 if (log)
196 log->Printf ("%p Platform::~Platform()", this);
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000197}
198
Greg Clayton58e26e02011-03-24 04:28:38 +0000199void
200Platform::GetStatus (Stream &strm)
201{
202 uint32_t major = UINT32_MAX;
203 uint32_t minor = UINT32_MAX;
204 uint32_t update = UINT32_MAX;
205 std::string s;
Greg Clayton24bc5d92011-03-30 18:16:51 +0000206 strm.Printf (" Platform: %s\n", GetShortPluginName());
Greg Clayton58e26e02011-03-24 04:28:38 +0000207
208 ArchSpec arch (GetSystemArchitecture());
209 if (arch.IsValid())
210 {
211 if (!arch.GetTriple().str().empty())
Greg Clayton24bc5d92011-03-30 18:16:51 +0000212 strm.Printf(" Triple: %s\n", arch.GetTriple().str().c_str());
Greg Clayton58e26e02011-03-24 04:28:38 +0000213 }
214
215 if (GetOSVersion(major, minor, update))
216 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000217 strm.Printf("OS Version: %u", major);
Greg Clayton58e26e02011-03-24 04:28:38 +0000218 if (minor != UINT32_MAX)
219 strm.Printf(".%u", minor);
220 if (update != UINT32_MAX)
221 strm.Printf(".%u", update);
222
223 if (GetOSBuildString (s))
224 strm.Printf(" (%s)", s.c_str());
225
226 strm.EOL();
227 }
228
229 if (GetOSKernelDescription (s))
Greg Clayton24bc5d92011-03-30 18:16:51 +0000230 strm.Printf(" Kernel: %s\n", s.c_str());
Greg Clayton58e26e02011-03-24 04:28:38 +0000231
232 if (IsHost())
233 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000234 strm.Printf(" Hostname: %s\n", GetHostname());
Greg Clayton58e26e02011-03-24 04:28:38 +0000235 }
236 else
237 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000238 const bool is_connected = IsConnected();
239 if (is_connected)
240 strm.Printf(" Hostname: %s\n", GetHostname());
241 strm.Printf(" Connected: %s\n", is_connected ? "yes" : "no");
Greg Clayton58e26e02011-03-24 04:28:38 +0000242 }
243}
244
Greg Claytonb1888f22011-03-19 01:12:21 +0000245
246bool
247Platform::GetOSVersion (uint32_t &major,
248 uint32_t &minor,
249 uint32_t &update)
250{
251 bool success = m_major_os_version != UINT32_MAX;
252 if (IsHost())
253 {
254 if (!success)
255 {
256 // We have a local host platform
257 success = Host::GetOSVersion (m_major_os_version,
258 m_minor_os_version,
259 m_update_os_version);
260 m_os_version_set_while_connected = success;
261 }
262 }
263 else
264 {
265 // We have a remote platform. We can only fetch the remote
266 // OS version if we are connected, and we don't want to do it
267 // more than once.
268
269 const bool is_connected = IsConnected();
270
Greg Clayton58e26e02011-03-24 04:28:38 +0000271 bool fetch = false;
Greg Claytonb1888f22011-03-19 01:12:21 +0000272 if (success)
273 {
274 // We have valid OS version info, check to make sure it wasn't
275 // manually set prior to connecting. If it was manually set prior
276 // to connecting, then lets fetch the actual OS version info
277 // if we are now connected.
278 if (is_connected && !m_os_version_set_while_connected)
Greg Clayton58e26e02011-03-24 04:28:38 +0000279 fetch = true;
Greg Claytonb1888f22011-03-19 01:12:21 +0000280 }
281 else
282 {
283 // We don't have valid OS version info, fetch it if we are connected
Greg Clayton58e26e02011-03-24 04:28:38 +0000284 fetch = is_connected;
Greg Claytonb1888f22011-03-19 01:12:21 +0000285 }
286
Greg Clayton58e26e02011-03-24 04:28:38 +0000287 if (fetch)
Greg Claytonb1888f22011-03-19 01:12:21 +0000288 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000289 success = GetRemoteOSVersion ();
Greg Claytonb1888f22011-03-19 01:12:21 +0000290 m_os_version_set_while_connected = success;
291 }
292 }
293
294 if (success)
295 {
296 major = m_major_os_version;
297 minor = m_minor_os_version;
298 update = m_update_os_version;
299 }
300 return success;
301}
Greg Clayton58e26e02011-03-24 04:28:38 +0000302
303bool
304Platform::GetOSBuildString (std::string &s)
305{
306 if (IsHost())
307 return Host::GetOSBuildString (s);
308 else
309 return GetRemoteOSBuildString (s);
310}
311
312bool
313Platform::GetOSKernelDescription (std::string &s)
314{
315 if (IsHost())
316 return Host::GetOSKernelDescription (s);
317 else
318 return GetRemoteOSKernelDescription (s);
319}
320
321const char *
Greg Claytonb72d0f02011-04-12 05:54:46 +0000322Platform::GetName ()
323{
324 const char *name = GetHostname();
325 if (name == NULL || name[0] == '\0')
326 name = GetShortPluginName();
327 return name;
328}
329
330const char *
Greg Clayton58e26e02011-03-24 04:28:38 +0000331Platform::GetHostname ()
332{
Greg Clayton5e342f52011-04-13 22:47:15 +0000333 if (IsHost())
334 return "localhost";
Greg Clayton24bc5d92011-03-30 18:16:51 +0000335
336 if (m_name.empty())
337 return NULL;
338 return m_name.c_str();
339}
340
341const char *
342Platform::GetUserName (uint32_t uid)
343{
344 const char *user_name = GetCachedUserName(uid);
345 if (user_name)
346 return user_name;
347 if (IsHost())
348 {
349 std::string name;
350 if (Host::GetUserName(uid, name))
351 return SetCachedUserName (uid, name.c_str(), name.size());
352 }
Greg Clayton58e26e02011-03-24 04:28:38 +0000353 return NULL;
354}
355
Greg Clayton24bc5d92011-03-30 18:16:51 +0000356const char *
357Platform::GetGroupName (uint32_t gid)
358{
359 const char *group_name = GetCachedGroupName(gid);
360 if (group_name)
361 return group_name;
362 if (IsHost())
363 {
364 std::string name;
365 if (Host::GetGroupName(gid, name))
366 return SetCachedGroupName (gid, name.c_str(), name.size());
367 }
368 return NULL;
369}
Greg Clayton58e26e02011-03-24 04:28:38 +0000370
Greg Claytonb1888f22011-03-19 01:12:21 +0000371bool
372Platform::SetOSVersion (uint32_t major,
373 uint32_t minor,
374 uint32_t update)
375{
376 if (IsHost())
377 {
378 // We don't need anyone setting the OS version for the host platform,
379 // we should be able to figure it out by calling Host::GetOSVersion(...).
380 return false;
381 }
382 else
383 {
384 // We have a remote platform, allow setting the target OS version if
385 // we aren't connected, since if we are connected, we should be able to
386 // request the remote OS version from the connected platform.
387 if (IsConnected())
388 return false;
389 else
390 {
391 // We aren't connected and we might want to set the OS version
392 // ahead of time before we connect so we can peruse files and
393 // use a local SDK or PDK cache of support files to disassemble
394 // or do other things.
395 m_major_os_version = major;
396 m_minor_os_version = minor;
397 m_update_os_version = update;
398 return true;
399 }
400 }
401 return false;
402}
403
404
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000405Error
406Platform::ResolveExecutable (const FileSpec &exe_file,
407 const ArchSpec &exe_arch,
Greg Clayton9ce95382012-02-13 23:10:39 +0000408 lldb::ModuleSP &exe_module_sp,
409 const FileSpecList *module_search_paths_ptr)
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000410{
411 Error error;
412 if (exe_file.Exists())
413 {
414 if (exe_arch.IsValid())
415 {
416 error = ModuleList::GetSharedModule (exe_file,
417 exe_arch,
418 NULL,
419 NULL,
420 0,
421 exe_module_sp,
Greg Clayton9ce95382012-02-13 23:10:39 +0000422 module_search_paths_ptr,
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000423 NULL,
424 NULL);
425 }
426 else
427 {
428 // No valid architecture was specified, ask the platform for
429 // the architectures that we should be using (in the correct order)
430 // and see if we can find a match that way
431 ArchSpec platform_arch;
432 for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, platform_arch); ++idx)
433 {
434 error = ModuleList::GetSharedModule (exe_file,
435 platform_arch,
436 NULL,
437 NULL,
438 0,
439 exe_module_sp,
Greg Clayton9ce95382012-02-13 23:10:39 +0000440 module_search_paths_ptr,
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000441 NULL,
442 NULL);
443 // Did we find an executable using one of the
444 if (error.Success() && exe_module_sp)
445 break;
446 }
447 }
448 }
449 else
450 {
451 error.SetErrorStringWithFormat ("'%s%s%s' does not exist",
452 exe_file.GetDirectory().AsCString(""),
453 exe_file.GetDirectory() ? "/" : "",
454 exe_file.GetFilename().AsCString(""));
455 }
456 return error;
457}
458
Greg Claytonf2bf8702011-08-11 16:25:18 +0000459bool
460Platform::ResolveRemotePath (const FileSpec &platform_path,
461 FileSpec &resolved_platform_path)
462{
463 resolved_platform_path = platform_path;
464 return resolved_platform_path.ResolvePath();
465}
466
Greg Claytonb1888f22011-03-19 01:12:21 +0000467
468const ArchSpec &
469Platform::GetSystemArchitecture()
470{
471 if (IsHost())
472 {
473 if (!m_system_arch.IsValid())
474 {
475 // We have a local host platform
476 m_system_arch = Host::GetArchitecture();
477 m_system_arch_set_while_connected = m_system_arch.IsValid();
478 }
479 }
480 else
481 {
482 // We have a remote platform. We can only fetch the remote
483 // system architecture if we are connected, and we don't want to do it
484 // more than once.
485
486 const bool is_connected = IsConnected();
487
488 bool fetch = false;
489 if (m_system_arch.IsValid())
490 {
491 // We have valid OS version info, check to make sure it wasn't
492 // manually set prior to connecting. If it was manually set prior
493 // to connecting, then lets fetch the actual OS version info
494 // if we are now connected.
495 if (is_connected && !m_system_arch_set_while_connected)
496 fetch = true;
497 }
498 else
499 {
500 // We don't have valid OS version info, fetch it if we are connected
501 fetch = is_connected;
502 }
503
504 if (fetch)
505 {
Greg Clayton58e26e02011-03-24 04:28:38 +0000506 m_system_arch = GetRemoteSystemArchitecture ();
Greg Claytonb1888f22011-03-19 01:12:21 +0000507 m_system_arch_set_while_connected = m_system_arch.IsValid();
508 }
509 }
510 return m_system_arch;
511}
512
513
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000514Error
Greg Claytoncb8977d2011-03-23 00:09:55 +0000515Platform::ConnectRemote (Args& args)
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000516{
517 Error error;
Greg Claytoncb8977d2011-03-23 00:09:55 +0000518 if (IsHost())
519 error.SetErrorStringWithFormat ("The currently selected platform (%s) is the host platform and is always connected.", GetShortPluginName());
520 else
521 error.SetErrorStringWithFormat ("Platform::ConnectRemote() is not supported by %s", GetShortPluginName());
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000522 return error;
523}
524
525Error
Greg Claytoncb8977d2011-03-23 00:09:55 +0000526Platform::DisconnectRemote ()
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000527{
528 Error error;
Greg Claytoncb8977d2011-03-23 00:09:55 +0000529 if (IsHost())
530 error.SetErrorStringWithFormat ("The currently selected platform (%s) is the host platform and is always connected.", GetShortPluginName());
531 else
532 error.SetErrorStringWithFormat ("Platform::DisconnectRemote() is not supported by %s", GetShortPluginName());
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000533 return error;
534}
Greg Clayton24bc5d92011-03-30 18:16:51 +0000535
536bool
Greg Claytonb72d0f02011-04-12 05:54:46 +0000537Platform::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
Greg Clayton24bc5d92011-03-30 18:16:51 +0000538{
539 // Take care of the host case so that each subclass can just
Greg Claytonb72d0f02011-04-12 05:54:46 +0000540 // call this function to get the host functionality.
Greg Clayton24bc5d92011-03-30 18:16:51 +0000541 if (IsHost())
542 return Host::GetProcessInfo (pid, process_info);
543 return false;
544}
545
546uint32_t
Greg Claytonb72d0f02011-04-12 05:54:46 +0000547Platform::FindProcesses (const ProcessInstanceInfoMatch &match_info,
548 ProcessInstanceInfoList &process_infos)
Greg Clayton24bc5d92011-03-30 18:16:51 +0000549{
Greg Claytonb72d0f02011-04-12 05:54:46 +0000550 // Take care of the host case so that each subclass can just
551 // call this function to get the host functionality.
Greg Clayton24bc5d92011-03-30 18:16:51 +0000552 uint32_t match_count = 0;
553 if (IsHost())
554 match_count = Host::FindProcesses (match_info, process_infos);
555 return match_count;
556}
Greg Claytonb72d0f02011-04-12 05:54:46 +0000557
558
559Error
560Platform::LaunchProcess (ProcessLaunchInfo &launch_info)
561{
562 Error error;
563 // Take care of the host case so that each subclass can just
564 // call this function to get the host functionality.
565 if (IsHost())
566 error = Host::LaunchProcess (launch_info);
567 else
568 error.SetErrorString ("base lldb_private::Platform class can't launch remote processes");
569 return error;
570}
571
572lldb::ProcessSP
573Platform::DebugProcess (ProcessLaunchInfo &launch_info,
574 Debugger &debugger,
575 Target *target, // Can be NULL, if NULL create a new target, else use existing one
576 Listener &listener,
577 Error &error)
578{
579 ProcessSP process_sp;
580 // Make sure we stop at the entry point
581 launch_info.GetFlags ().Set (eLaunchFlagDebug);
582 error = LaunchProcess (launch_info);
583 if (error.Success())
584 {
Greg Clayton527154d2011-11-15 03:53:30 +0000585 if (launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
Greg Claytonb72d0f02011-04-12 05:54:46 +0000586 {
Greg Clayton527154d2011-11-15 03:53:30 +0000587 ProcessAttachInfo attach_info (launch_info);
588 process_sp = Attach (attach_info, debugger, target, listener, error);
Greg Claytonffa43a62011-11-17 04:46:02 +0000589 if (process_sp)
590 {
591 // Since we attached to the process, it will think it needs to detach
592 // if the process object just goes away without an explicit call to
593 // Process::Kill() or Process::Detach(), so let it know to kill the
594 // process if this happens.
595 process_sp->SetShouldDetach (false);
Greg Clayton464c6162011-11-17 22:14:31 +0000596
597 // If we didn't have any file actions, the pseudo terminal might
598 // have been used where the slave side was given as the file to
599 // open for stdin/out/err after we have already opened the master
600 // so we can read/write stdin/out/err.
601 int pty_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor();
602 if (pty_fd != lldb_utility::PseudoTerminal::invalid_fd)
603 {
604 process_sp->SetSTDIOFileDescriptor(pty_fd);
605 }
Greg Claytonffa43a62011-11-17 04:46:02 +0000606 }
Greg Claytonb72d0f02011-04-12 05:54:46 +0000607 }
608 }
609 return process_sp;
610}