1 //===-- ConnectionFileDescriptorPosix.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 #if defined(__APPLE__)
11 // Enable this special support for Apple builds where we can have unlimited
12 // select bounds. We tried switching to poll() and kqueue and we were panicing
13 // the kernel, so we have to stick with select for now.
14 #define _DARWIN_UNLIMITED_SELECT
15 #endif
16 
17 #include "lldb/Host/posix/ConnectionFileDescriptorPosix.h"
18 #include "lldb/Host/Config.h"
19 #include "lldb/Host/IOObject.h"
20 #include "lldb/Host/SocketAddress.h"
21 #include "lldb/Host/Socket.h"
22 #include "lldb/Host/StringConvert.h"
23 
24 // C Includes
25 #include <errno.h>
26 #include <fcntl.h>
27 #include <string.h>
28 #include <stdlib.h>
29 #include <sys/types.h>
30 
31 #ifndef LLDB_DISABLE_POSIX
32 #include <termios.h>
33 #endif
34 
35 // C++ Includes
36 #include <sstream>
37 
38 // Other libraries and framework includes
39 #include "llvm/Support/ErrorHandling.h"
40 #if defined(__APPLE__)
41 #include "llvm/ADT/SmallVector.h"
42 #endif
43 // Project includes
44 #include "lldb/Core/Communication.h"
45 #include "lldb/Core/Log.h"
46 #include "lldb/Core/StreamString.h"
47 #include "lldb/Core/Timer.h"
48 #include "lldb/Host/Host.h"
49 #include "lldb/Host/Socket.h"
50 #include "lldb/Host/common/TCPSocket.h"
51 #include "lldb/Interpreter/Args.h"
52 
53 using namespace lldb;
54 using namespace lldb_private;
55 
56 ConnectionFileDescriptor::ConnectionFileDescriptor(bool child_processes_inherit)
57     : Connection()
58     , m_pipe()
59     , m_mutex(Mutex::eMutexTypeRecursive)
60     , m_shutting_down(false)
61     , m_waiting_for_accept(false)
62     , m_child_processes_inherit(child_processes_inherit)
63 {
64     Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION | LIBLLDB_LOG_OBJECT));
65     if (log)
66         log->Printf("%p ConnectionFileDescriptor::ConnectionFileDescriptor ()", static_cast<void *>(this));
67 }
68 
69 ConnectionFileDescriptor::ConnectionFileDescriptor(int fd, bool owns_fd)
70     : Connection()
71     , m_pipe()
72     , m_mutex(Mutex::eMutexTypeRecursive)
73     , m_shutting_down(false)
74     , m_waiting_for_accept(false)
75     , m_child_processes_inherit(false)
76 {
77     m_write_sp.reset(new File(fd, owns_fd));
78     m_read_sp.reset(new File(fd, false));
79 
80     Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION | LIBLLDB_LOG_OBJECT));
81     if (log)
82         log->Printf("%p ConnectionFileDescriptor::ConnectionFileDescriptor (fd = %i, owns_fd = %i)", static_cast<void *>(this), fd,
83                     owns_fd);
84     OpenCommandPipe();
85 }
86 
87 ConnectionFileDescriptor::ConnectionFileDescriptor(Socket* socket)
88     : Connection()
89     , m_pipe()
90     , m_mutex(Mutex::eMutexTypeRecursive)
91     , m_shutting_down(false)
92     , m_waiting_for_accept(false)
93     , m_child_processes_inherit(false)
94 {
95     InitializeSocket(socket);
96 }
97 
98 ConnectionFileDescriptor::~ConnectionFileDescriptor()
99 {
100     Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION | LIBLLDB_LOG_OBJECT));
101     if (log)
102         log->Printf("%p ConnectionFileDescriptor::~ConnectionFileDescriptor ()", static_cast<void *>(this));
103     Disconnect(NULL);
104     CloseCommandPipe();
105 }
106 
107 void
108 ConnectionFileDescriptor::OpenCommandPipe()
109 {
110     CloseCommandPipe();
111 
112     Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION));
113     // Make the command file descriptor here:
114     Error result = m_pipe.CreateNew(m_child_processes_inherit);
115     if (!result.Success())
116     {
117         if (log)
118             log->Printf("%p ConnectionFileDescriptor::OpenCommandPipe () - could not make pipe: %s", static_cast<void *>(this),
119                         result.AsCString());
120     }
121     else
122     {
123         if (log)
124             log->Printf("%p ConnectionFileDescriptor::OpenCommandPipe() - success readfd=%d writefd=%d", static_cast<void *>(this),
125                         m_pipe.GetReadFileDescriptor(), m_pipe.GetWriteFileDescriptor());
126     }
127 }
128 
129 void
130 ConnectionFileDescriptor::CloseCommandPipe()
131 {
132     Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION));
133     if (log)
134         log->Printf("%p ConnectionFileDescriptor::CloseCommandPipe()", static_cast<void *>(this));
135 
136     m_pipe.Close();
137 }
138 
139 bool
140 ConnectionFileDescriptor::IsConnected() const
141 {
142     return (m_read_sp && m_read_sp->IsValid()) || (m_write_sp && m_write_sp->IsValid());
143 }
144 
145 ConnectionStatus
146 ConnectionFileDescriptor::Connect(const char *s, Error *error_ptr)
147 {
148     Mutex::Locker locker(m_mutex);
149     Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION));
150     if (log)
151         log->Printf("%p ConnectionFileDescriptor::Connect (url = '%s')", static_cast<void *>(this), s);
152 
153     OpenCommandPipe();
154 
155     if (s && s[0])
156     {
157         if (strstr(s, "listen://") == s)
158         {
159             // listen://HOST:PORT
160             return SocketListenAndAccept(s + strlen("listen://"), error_ptr);
161         }
162         else if (strstr(s, "accept://") == s)
163         {
164             // unix://SOCKNAME
165             return NamedSocketAccept(s + strlen("accept://"), error_ptr);
166         }
167         else if (strstr(s, "unix-accept://") == s)
168         {
169             // unix://SOCKNAME
170             return NamedSocketAccept(s + strlen("unix-accept://"), error_ptr);
171         }
172         else if (strstr(s, "connect://") == s)
173         {
174             return ConnectTCP(s + strlen("connect://"), error_ptr);
175         }
176         else if (strstr(s, "tcp-connect://") == s)
177         {
178             return ConnectTCP(s + strlen("tcp-connect://"), error_ptr);
179         }
180         else if (strstr(s, "udp://") == s)
181         {
182             return ConnectUDP(s + strlen("udp://"), error_ptr);
183         }
184         else if (strstr(s, "unix-connect://") == s)
185         {
186             // unix-connect://SOCKNAME
187             return NamedSocketConnect(s + strlen("unix-connect://"), error_ptr);
188         }
189         else if (strstr(s, "unix-abstract-connect://") == s)
190         {
191             // unix-abstract-connect://SOCKNAME
192             return UnixAbstractSocketConnect(s + strlen("unix-abstract-connect://"), error_ptr);
193         }
194 #ifndef LLDB_DISABLE_POSIX
195         else if (strstr(s, "fd://") == s)
196         {
197             // Just passing a native file descriptor within this current process
198             // that is already opened (possibly from a service or other source).
199             s += strlen("fd://");
200             bool success = false;
201             int fd = StringConvert::ToSInt32(s, -1, 0, &success);
202 
203             if (success)
204             {
205                 // We have what looks to be a valid file descriptor, but we
206                 // should make sure it is. We currently are doing this by trying to
207                 // get the flags from the file descriptor and making sure it
208                 // isn't a bad fd.
209                 errno = 0;
210                 int flags = ::fcntl(fd, F_GETFL, 0);
211                 if (flags == -1 || errno == EBADF)
212                 {
213                     if (error_ptr)
214                         error_ptr->SetErrorStringWithFormat("stale file descriptor: %s", s);
215                     m_read_sp.reset();
216                     m_write_sp.reset();
217                     return eConnectionStatusError;
218                 }
219                 else
220                 {
221                     // Don't take ownership of a file descriptor that gets passed
222                     // to us since someone else opened the file descriptor and
223                     // handed it to us.
224                     // TODO: Since are using a URL to open connection we should
225                     // eventually parse options using the web standard where we
226                     // have "fd://123?opt1=value;opt2=value" and we can have an
227                     // option be "owns=1" or "owns=0" or something like this to
228                     // allow us to specify this. For now, we assume we must
229                     // assume we don't own it.
230 
231                     std::unique_ptr<TCPSocket> tcp_socket;
232                     tcp_socket.reset(new TCPSocket(fd, false));
233                     // Try and get a socket option from this file descriptor to
234                     // see if this is a socket and set m_is_socket accordingly.
235                     int resuse;
236                     bool is_socket = !!tcp_socket->GetOption(SOL_SOCKET, SO_REUSEADDR, resuse);
237                     if (is_socket)
238                     {
239                         m_read_sp = std::move(tcp_socket);
240                         m_write_sp = m_read_sp;
241                     }
242                     else
243                     {
244                         m_read_sp.reset(new File(fd, false));
245                         m_write_sp.reset(new File(fd, false));
246                     }
247                     m_uri.assign(s);
248                     return eConnectionStatusSuccess;
249                 }
250             }
251 
252             if (error_ptr)
253                 error_ptr->SetErrorStringWithFormat("invalid file descriptor: \"fd://%s\"", s);
254             m_read_sp.reset();
255             m_write_sp.reset();
256             return eConnectionStatusError;
257         }
258         else if (strstr(s, "file://") == s)
259         {
260             // file:///PATH
261             const char *path = s + strlen("file://");
262             int fd = -1;
263             do
264             {
265                 fd = ::open(path, O_RDWR);
266             } while (fd == -1 && errno == EINTR);
267 
268             if (fd == -1)
269             {
270                 if (error_ptr)
271                     error_ptr->SetErrorToErrno();
272                 return eConnectionStatusError;
273             }
274 
275             if (::isatty(fd))
276             {
277                 // Set up serial terminal emulation
278                 struct termios options;
279                 ::tcgetattr(fd, &options);
280 
281                 // Set port speed to maximum
282                 ::cfsetospeed(&options, B115200);
283                 ::cfsetispeed(&options, B115200);
284 
285                 // Raw input, disable echo and signals
286                 options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
287 
288                 // Make sure only one character is needed to return from a read
289                 options.c_cc[VMIN] = 1;
290                 options.c_cc[VTIME] = 0;
291 
292                 ::tcsetattr(fd, TCSANOW, &options);
293             }
294 
295             int flags = ::fcntl(fd, F_GETFL, 0);
296             if (flags >= 0)
297             {
298                 if ((flags & O_NONBLOCK) == 0)
299                 {
300                     flags |= O_NONBLOCK;
301                     ::fcntl(fd, F_SETFL, flags);
302                 }
303             }
304             m_read_sp.reset(new File(fd, true));
305             m_write_sp.reset(new File(fd, false));
306             return eConnectionStatusSuccess;
307         }
308 #endif
309         if (error_ptr)
310             error_ptr->SetErrorStringWithFormat("unsupported connection URL: '%s'", s);
311         return eConnectionStatusError;
312     }
313     if (error_ptr)
314         error_ptr->SetErrorString("invalid connect arguments");
315     return eConnectionStatusError;
316 }
317 
318 bool
319 ConnectionFileDescriptor::InterruptRead()
320 {
321     size_t bytes_written = 0;
322     Error result = m_pipe.Write("i", 1, bytes_written);
323     return result.Success();
324 }
325 
326 ConnectionStatus
327 ConnectionFileDescriptor::Disconnect(Error *error_ptr)
328 {
329     Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION));
330     if (log)
331         log->Printf("%p ConnectionFileDescriptor::Disconnect ()", static_cast<void *>(this));
332 
333     ConnectionStatus status = eConnectionStatusSuccess;
334 
335     if (!IsConnected())
336     {
337         if (log)
338             log->Printf("%p ConnectionFileDescriptor::Disconnect(): Nothing to disconnect", static_cast<void *>(this));
339         return eConnectionStatusSuccess;
340     }
341 
342     if (m_read_sp && m_read_sp->IsValid() && m_read_sp->GetFdType() == IOObject::eFDTypeSocket)
343         static_cast<Socket &>(*m_read_sp).PreDisconnect();
344 
345     // Try to get the ConnectionFileDescriptor's mutex.  If we fail, that is quite likely
346     // because somebody is doing a blocking read on our file descriptor.  If that's the case,
347     // then send the "q" char to the command file channel so the read will wake up and the connection
348     // will then know to shut down.
349 
350     m_shutting_down = true;
351 
352     Mutex::Locker locker;
353     bool got_lock = locker.TryLock(m_mutex);
354 
355     if (!got_lock)
356     {
357         if (m_pipe.CanWrite())
358         {
359             size_t bytes_written = 0;
360             Error result = m_pipe.Write("q", 1, bytes_written);
361             if (log)
362                 log->Printf("%p ConnectionFileDescriptor::Disconnect(): Couldn't get the lock, sent 'q' to %d, error = '%s'.",
363                             static_cast<void *>(this), m_pipe.GetWriteFileDescriptor(), result.AsCString());
364         }
365         else if (log)
366         {
367             log->Printf("%p ConnectionFileDescriptor::Disconnect(): Couldn't get the lock, but no command pipe is available.",
368                         static_cast<void *>(this));
369         }
370         locker.Lock(m_mutex);
371     }
372 
373     Error error = m_read_sp->Close();
374     Error error2 = m_write_sp->Close();
375     if (error.Fail() || error2.Fail())
376         status = eConnectionStatusError;
377     if (error_ptr)
378         *error_ptr = error.Fail() ? error : error2;
379 
380     // Close any pipes we were using for async interrupts
381     m_pipe.Close();
382 
383     m_uri.clear();
384     m_shutting_down = false;
385     return status;
386 }
387 
388 size_t
389 ConnectionFileDescriptor::Read(void *dst, size_t dst_len, uint32_t timeout_usec, ConnectionStatus &status, Error *error_ptr)
390 {
391     Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION));
392 
393     Mutex::Locker locker;
394     bool got_lock = locker.TryLock(m_mutex);
395     if (!got_lock)
396     {
397         if (log)
398             log->Printf("%p ConnectionFileDescriptor::Read () failed to get the connection lock.", static_cast<void *>(this));
399         if (error_ptr)
400             error_ptr->SetErrorString("failed to get the connection lock for read.");
401 
402         status = eConnectionStatusTimedOut;
403         return 0;
404     }
405 
406     if (m_shutting_down)
407     {
408         status = eConnectionStatusError;
409         return 0;
410     }
411 
412     status = BytesAvailable(timeout_usec, error_ptr);
413     if (status != eConnectionStatusSuccess)
414         return 0;
415 
416     Error error;
417     size_t bytes_read = dst_len;
418     error = m_read_sp->Read(dst, bytes_read);
419 
420     if (log)
421     {
422         log->Printf("%p ConnectionFileDescriptor::Read()  fd = %" PRIu64 ", dst = %p, dst_len = %" PRIu64 ") => %" PRIu64 ", error = %s",
423                     static_cast<void *>(this), static_cast<uint64_t>(m_read_sp->GetWaitableHandle()), static_cast<void *>(dst),
424                     static_cast<uint64_t>(dst_len), static_cast<uint64_t>(bytes_read), error.AsCString());
425     }
426 
427     if (bytes_read == 0)
428     {
429         error.Clear(); // End-of-file.  Do not automatically close; pass along for the end-of-file handlers.
430         status = eConnectionStatusEndOfFile;
431     }
432 
433     if (error_ptr)
434         *error_ptr = error;
435 
436     if (error.Fail())
437     {
438         uint32_t error_value = error.GetError();
439         switch (error_value)
440         {
441             case EAGAIN: // The file was marked for non-blocking I/O, and no data were ready to be read.
442                 if (m_read_sp->GetFdType() == IOObject::eFDTypeSocket)
443                     status = eConnectionStatusTimedOut;
444                 else
445                     status = eConnectionStatusSuccess;
446                 return 0;
447 
448             case EFAULT:  // Buf points outside the allocated address space.
449             case EINTR:   // A read from a slow device was interrupted before any data arrived by the delivery of a signal.
450             case EINVAL:  // The pointer associated with fildes was negative.
451             case EIO:     // An I/O error occurred while reading from the file system.
452                           // The process group is orphaned.
453                           // The file is a regular file, nbyte is greater than 0,
454                           // the starting position is before the end-of-file, and
455                           // the starting position is greater than or equal to the
456                           // offset maximum established for the open file
457                           // descriptor associated with fildes.
458             case EISDIR:  // An attempt is made to read a directory.
459             case ENOBUFS: // An attempt to allocate a memory buffer fails.
460             case ENOMEM:  // Insufficient memory is available.
461                 status = eConnectionStatusError;
462                 break; // Break to close....
463 
464             case ENOENT:     // no such file or directory
465             case EBADF:      // fildes is not a valid file or socket descriptor open for reading.
466             case ENXIO:      // An action is requested of a device that does not exist..
467                              // A requested action cannot be performed by the device.
468             case ECONNRESET: // The connection is closed by the peer during a read attempt on a socket.
469             case ENOTCONN:   // A read is attempted on an unconnected socket.
470                 status = eConnectionStatusLostConnection;
471                 break; // Break to close....
472 
473             case ETIMEDOUT: // A transmission timeout occurs during a read attempt on a socket.
474                 status = eConnectionStatusTimedOut;
475                 return 0;
476 
477             default:
478                 if (log)
479                     log->Printf("%p ConnectionFileDescriptor::Read (), unexpected error: %s", static_cast<void *>(this),
480                                 strerror(error_value));
481                 status = eConnectionStatusError;
482                 break; // Break to close....
483         }
484 
485         return 0;
486     }
487     return bytes_read;
488 }
489 
490 size_t
491 ConnectionFileDescriptor::Write(const void *src, size_t src_len, ConnectionStatus &status, Error *error_ptr)
492 {
493     Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION));
494     if (log)
495         log->Printf("%p ConnectionFileDescriptor::Write (src = %p, src_len = %" PRIu64 ")", static_cast<void *>(this),
496                     static_cast<const void *>(src), static_cast<uint64_t>(src_len));
497 
498     if (!IsConnected())
499     {
500         if (error_ptr)
501             error_ptr->SetErrorString("not connected");
502         status = eConnectionStatusNoConnection;
503         return 0;
504     }
505 
506     Error error;
507 
508     size_t bytes_sent = src_len;
509     error = m_write_sp->Write(src, bytes_sent);
510 
511     if (log)
512     {
513         log->Printf("%p ConnectionFileDescriptor::Write(fd = %" PRIu64 ", src = %p, src_len = %" PRIu64 ") => %" PRIu64 " (error = %s)",
514                     static_cast<void *>(this), static_cast<uint64_t>(m_write_sp->GetWaitableHandle()), static_cast<const void *>(src),
515                     static_cast<uint64_t>(src_len), static_cast<uint64_t>(bytes_sent), error.AsCString());
516     }
517 
518     if (error_ptr)
519         *error_ptr = error;
520 
521     if (error.Fail())
522     {
523         switch (error.GetError())
524         {
525             case EAGAIN:
526             case EINTR:
527                 status = eConnectionStatusSuccess;
528                 return 0;
529 
530             case ECONNRESET: // The connection is closed by the peer during a read attempt on a socket.
531             case ENOTCONN:   // A read is attempted on an unconnected socket.
532                 status = eConnectionStatusLostConnection;
533                 break; // Break to close....
534 
535             default:
536                 status = eConnectionStatusError;
537                 break; // Break to close....
538         }
539 
540         return 0;
541     }
542 
543     status = eConnectionStatusSuccess;
544     return bytes_sent;
545 }
546 
547 std::string
548 ConnectionFileDescriptor::GetURI()
549 {
550     return m_uri;
551 }
552 
553 // This ConnectionFileDescriptor::BytesAvailable() uses select().
554 //
555 // PROS:
556 //  - select is consistent across most unix platforms
557 //  - The Apple specific version allows for unlimited fds in the fd_sets by
558 //    setting the _DARWIN_UNLIMITED_SELECT define prior to including the
559 //    required header files.
560 // CONS:
561 //  - on non-Apple platforms, only supports file descriptors up to FD_SETSIZE.
562 //     This implementation  will assert if it runs into that hard limit to let
563 //     users know that another ConnectionFileDescriptor::BytesAvailable() should
564 //     be used or a new version of ConnectionFileDescriptor::BytesAvailable()
565 //     should be written for the system that is running into the limitations.
566 
567 #if defined(__APPLE__)
568 #define FD_SET_DATA(fds) fds.data()
569 #else
570 #define FD_SET_DATA(fds) &fds
571 #endif
572 
573 ConnectionStatus
574 ConnectionFileDescriptor::BytesAvailable(uint32_t timeout_usec, Error *error_ptr)
575 {
576     // Don't need to take the mutex here separately since we are only called from Read.  If we
577     // ever get used more generally we will need to lock here as well.
578 
579     Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_CONNECTION));
580     if (log)
581         log->Printf("%p ConnectionFileDescriptor::BytesAvailable (timeout_usec = %u)", static_cast<void *>(this), timeout_usec);
582 
583     struct timeval *tv_ptr;
584     struct timeval tv;
585     if (timeout_usec == UINT32_MAX)
586     {
587         // Inifinite wait...
588         tv_ptr = nullptr;
589     }
590     else
591     {
592         TimeValue time_value;
593         time_value.OffsetWithMicroSeconds(timeout_usec);
594         tv.tv_sec = time_value.seconds();
595         tv.tv_usec = time_value.microseconds();
596         tv_ptr = &tv;
597     }
598 
599     // Make a copy of the file descriptors to make sure we don't
600     // have another thread change these values out from under us
601     // and cause problems in the loop below where like in FS_SET()
602     const IOObject::WaitableHandle handle = m_read_sp->GetWaitableHandle();
603     const int pipe_fd = m_pipe.GetReadFileDescriptor();
604 
605     if (handle != IOObject::kInvalidHandleValue)
606     {
607 #if defined(_MSC_VER)
608         // select() won't accept pipes on Windows.  The entire Windows codepath needs to be
609         // converted over to using WaitForMultipleObjects and event HANDLEs, but for now at least
610         // this will allow ::select() to not return an error.
611         const bool have_pipe_fd = false;
612 #else
613         const bool have_pipe_fd = pipe_fd >= 0;
614 #if !defined(__APPLE__)
615         assert(handle < FD_SETSIZE);
616         if (have_pipe_fd)
617             assert(pipe_fd < FD_SETSIZE);
618 #endif
619 #endif
620         while (handle == m_read_sp->GetWaitableHandle())
621         {
622             const int nfds = std::max<int>(handle, pipe_fd) + 1;
623 #if defined(__APPLE__)
624             llvm::SmallVector<fd_set, 1> read_fds;
625             read_fds.resize((nfds / FD_SETSIZE) + 1);
626             for (size_t i = 0; i < read_fds.size(); ++i)
627                 FD_ZERO(&read_fds[i]);
628 // FD_SET doesn't bounds check, it just happily walks off the end
629 // but we have taken care of making the extra storage with our
630 // SmallVector of fd_set objects
631 #else
632             fd_set read_fds;
633             FD_ZERO(&read_fds);
634 #endif
635             FD_SET(handle, FD_SET_DATA(read_fds));
636             if (have_pipe_fd)
637                 FD_SET(pipe_fd, FD_SET_DATA(read_fds));
638 
639             Error error;
640 
641             if (log)
642             {
643                 if (have_pipe_fd)
644                     log->Printf(
645                         "%p ConnectionFileDescriptor::BytesAvailable()  ::select (nfds=%i, fds={%i, %i}, NULL, NULL, timeout=%p)...",
646                         static_cast<void *>(this), nfds, handle, pipe_fd, static_cast<void *>(tv_ptr));
647                 else
648                     log->Printf("%p ConnectionFileDescriptor::BytesAvailable()  ::select (nfds=%i, fds={%i}, NULL, NULL, timeout=%p)...",
649                                 static_cast<void *>(this), nfds, handle, static_cast<void *>(tv_ptr));
650             }
651 
652             const int num_set_fds = ::select(nfds, FD_SET_DATA(read_fds), NULL, NULL, tv_ptr);
653             if (num_set_fds < 0)
654                 error.SetErrorToErrno();
655             else
656                 error.Clear();
657 
658             if (log)
659             {
660                 if (have_pipe_fd)
661                     log->Printf("%p ConnectionFileDescriptor::BytesAvailable()  ::select (nfds=%i, fds={%i, %i}, NULL, NULL, timeout=%p) "
662                                 "=> %d, error = %s",
663                                 static_cast<void *>(this), nfds, handle, pipe_fd, static_cast<void *>(tv_ptr), num_set_fds,
664                                 error.AsCString());
665                 else
666                     log->Printf("%p ConnectionFileDescriptor::BytesAvailable()  ::select (nfds=%i, fds={%i}, NULL, NULL, timeout=%p) => "
667                                 "%d, error = %s",
668                                 static_cast<void *>(this), nfds, handle, static_cast<void *>(tv_ptr), num_set_fds, error.AsCString());
669             }
670 
671             if (error_ptr)
672                 *error_ptr = error;
673 
674             if (error.Fail())
675             {
676                 switch (error.GetError())
677                 {
678                     case EBADF: // One of the descriptor sets specified an invalid descriptor.
679                         return eConnectionStatusLostConnection;
680 
681                     case EINVAL: // The specified time limit is invalid. One of its components is negative or too large.
682                     default:     // Other unknown error
683                         return eConnectionStatusError;
684 
685                     case EAGAIN: // The kernel was (perhaps temporarily) unable to
686                                  // allocate the requested number of file descriptors,
687                                  // or we have non-blocking IO
688                     case EINTR:  // A signal was delivered before the time limit
689                         // expired and before any of the selected events
690                         // occurred.
691                         break; // Lets keep reading to until we timeout
692                 }
693             }
694             else if (num_set_fds == 0)
695             {
696                 return eConnectionStatusTimedOut;
697             }
698             else if (num_set_fds > 0)
699             {
700                 if (FD_ISSET(handle, FD_SET_DATA(read_fds)))
701                     return eConnectionStatusSuccess;
702                 if (have_pipe_fd && FD_ISSET(pipe_fd, FD_SET_DATA(read_fds)))
703                 {
704                     // There is an interrupt or exit command in the command pipe
705                     // Read the data from that pipe:
706                     char buffer[1];
707 
708                     ssize_t bytes_read;
709 
710                     do
711                     {
712                         bytes_read = ::read(pipe_fd, buffer, sizeof(buffer));
713                     } while (bytes_read < 0 && errno == EINTR);
714 
715                     switch (buffer[0])
716                     {
717                         case 'q':
718                             if (log)
719                                 log->Printf("%p ConnectionFileDescriptor::BytesAvailable() "
720                                             "got data: %c from the command channel.",
721                                             static_cast<void *>(this), buffer[0]);
722                             return eConnectionStatusEndOfFile;
723                         case 'i':
724                             // Interrupt the current read
725                             return eConnectionStatusInterrupted;
726                     }
727                 }
728             }
729         }
730     }
731 
732     if (error_ptr)
733         error_ptr->SetErrorString("not connected");
734     return eConnectionStatusLostConnection;
735 }
736 
737 ConnectionStatus
738 ConnectionFileDescriptor::NamedSocketAccept(const char *socket_name, Error *error_ptr)
739 {
740     Socket *socket = nullptr;
741     Error error = Socket::UnixDomainAccept(socket_name, m_child_processes_inherit, socket);
742     if (error_ptr)
743         *error_ptr = error;
744     m_write_sp.reset(socket);
745     m_read_sp = m_write_sp;
746     if (error.Fail())
747     {
748         return eConnectionStatusError;
749     }
750     m_uri.assign(socket_name);
751     return eConnectionStatusSuccess;
752 }
753 
754 ConnectionStatus
755 ConnectionFileDescriptor::NamedSocketConnect(const char *socket_name, Error *error_ptr)
756 {
757     Socket *socket = nullptr;
758     Error error = Socket::UnixDomainConnect(socket_name, m_child_processes_inherit, socket);
759     if (error_ptr)
760         *error_ptr = error;
761     m_write_sp.reset(socket);
762     m_read_sp = m_write_sp;
763     if (error.Fail())
764     {
765         return eConnectionStatusError;
766     }
767     m_uri.assign(socket_name);
768     return eConnectionStatusSuccess;
769 }
770 
771 lldb::ConnectionStatus
772 ConnectionFileDescriptor::UnixAbstractSocketConnect(const char *socket_name, Error *error_ptr)
773 {
774     Socket *socket = nullptr;
775     Error error = Socket::UnixAbstractConnect(socket_name, m_child_processes_inherit, socket);
776     if (error_ptr)
777         *error_ptr = error;
778     m_write_sp.reset(socket);
779     m_read_sp = m_write_sp;
780     if (error.Fail())
781     {
782         return eConnectionStatusError;
783     }
784     m_uri.assign(socket_name);
785     return eConnectionStatusSuccess;
786 }
787 
788 ConnectionStatus
789 ConnectionFileDescriptor::SocketListenAndAccept(const char *s, Error *error_ptr)
790 {
791     m_port_predicate.SetValue(0, eBroadcastNever);
792 
793     Socket *socket = nullptr;
794     m_waiting_for_accept = true;
795     Error error = Socket::TcpListen(s, m_child_processes_inherit, socket, &m_port_predicate);
796     if (error_ptr)
797         *error_ptr = error;
798     if (error.Fail())
799         return eConnectionStatusError;
800 
801     std::unique_ptr<Socket> listening_socket_up;
802 
803     listening_socket_up.reset(socket);
804     socket = nullptr;
805     error = listening_socket_up->Accept(s, m_child_processes_inherit, socket);
806     listening_socket_up.reset();
807     if (error_ptr)
808         *error_ptr = error;
809     if (error.Fail())
810         return eConnectionStatusError;
811 
812     InitializeSocket(socket);
813     return eConnectionStatusSuccess;
814 }
815 
816 ConnectionStatus
817 ConnectionFileDescriptor::ConnectTCP(const char *s, Error *error_ptr)
818 {
819     Socket *socket = nullptr;
820     Error error = Socket::TcpConnect(s, m_child_processes_inherit, socket);
821     if (error_ptr)
822         *error_ptr = error;
823     m_write_sp.reset(socket);
824     m_read_sp = m_write_sp;
825     if (error.Fail())
826     {
827         return eConnectionStatusError;
828     }
829     m_uri.assign(s);
830     return eConnectionStatusSuccess;
831 }
832 
833 ConnectionStatus
834 ConnectionFileDescriptor::ConnectUDP(const char *s, Error *error_ptr)
835 {
836     Socket *send_socket = nullptr;
837     Socket *recv_socket = nullptr;
838     Error error = Socket::UdpConnect(s, m_child_processes_inherit, send_socket, recv_socket);
839     if (error_ptr)
840         *error_ptr = error;
841     m_write_sp.reset(send_socket);
842     m_read_sp.reset(recv_socket);
843     if (error.Fail())
844     {
845         return eConnectionStatusError;
846     }
847     m_uri.assign(s);
848     return eConnectionStatusSuccess;
849 }
850 
851 uint16_t
852 ConnectionFileDescriptor::GetListeningPort(uint32_t timeout_sec)
853 {
854     uint16_t bound_port = 0;
855     if (timeout_sec == UINT32_MAX)
856         m_port_predicate.WaitForValueNotEqualTo(0, bound_port);
857     else
858     {
859         TimeValue timeout = TimeValue::Now();
860         timeout.OffsetWithSeconds(timeout_sec);
861         m_port_predicate.WaitForValueNotEqualTo(0, bound_port, &timeout);
862     }
863     return bound_port;
864 }
865 
866 bool
867 ConnectionFileDescriptor::GetChildProcessesInherit() const
868 {
869     return m_child_processes_inherit;
870 }
871 
872 void
873 ConnectionFileDescriptor::SetChildProcessesInherit(bool child_processes_inherit)
874 {
875     m_child_processes_inherit = child_processes_inherit;
876 }
877 
878 void
879 ConnectionFileDescriptor::InitializeSocket(Socket* socket)
880 {
881     assert(socket->GetSocketProtocol() == Socket::ProtocolTcp);
882     TCPSocket* tcp_socket = static_cast<TCPSocket*>(socket);
883 
884     m_write_sp.reset(socket);
885     m_read_sp = m_write_sp;
886     StreamString strm;
887     strm.Printf("connect://%s:%u",tcp_socket->GetRemoteIPAddress().c_str(), tcp_socket->GetRemotePortNumber());
888     m_uri.swap(strm.GetString());
889 }
890