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