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