//===-- ConnectionFileDescriptorPosix.cpp ---------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#if defined(__APPLE__)
// Enable this special support for Apple builds where we can have unlimited
// select bounds. We tried switching to poll() and kqueue and we were panicing
// the kernel, so we have to stick with select for now.
#define _DARWIN_UNLIMITED_SELECT
#endif

#include "lldb/Host/posix/ConnectionFileDescriptorPosix.h"
#include "lldb/Host/Config.h"
#include "lldb/Host/Socket.h"
#include "lldb/Host/SocketAddress.h"
#include "lldb/Utility/SelectHelper.h"
#include "lldb/Utility/Timeout.h"

#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>

#if LLDB_ENABLE_POSIX
#include <termios.h>
#include <unistd.h>
#endif

#include <memory>
#include <sstream>

#include "llvm/Support/Errno.h"
#include "llvm/Support/ErrorHandling.h"
#if defined(__APPLE__)
#include "llvm/ADT/SmallVector.h"
#endif
#include "lldb/Host/Host.h"
#include "lldb/Host/Socket.h"
#include "lldb/Host/common/TCPSocket.h"
#include "lldb/Host/common/UDPSocket.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/Timer.h"

using namespace lldb;
using namespace lldb_private;

const char *ConnectionFileDescriptor::LISTEN_SCHEME = "listen";
const char *ConnectionFileDescriptor::ACCEPT_SCHEME = "accept";
const char *ConnectionFileDescriptor::UNIX_ACCEPT_SCHEME = "unix-accept";
const char *ConnectionFileDescriptor::CONNECT_SCHEME = "connect";
const char *ConnectionFileDescriptor::TCP_CONNECT_SCHEME = "tcp-connect";
const char *ConnectionFileDescriptor::UDP_SCHEME = "udp";
const char *ConnectionFileDescriptor::UNIX_CONNECT_SCHEME = "unix-connect";
const char *ConnectionFileDescriptor::UNIX_ABSTRACT_CONNECT_SCHEME =
    "unix-abstract-connect";
const char *ConnectionFileDescriptor::FD_SCHEME = "fd";
const char *ConnectionFileDescriptor::FILE_SCHEME = "file";

namespace {

llvm::Optional<llvm::StringRef> GetURLAddress(llvm::StringRef url,
                                              llvm::StringRef scheme) {
  if (!url.consume_front(scheme))
    return llvm::None;
  if (!url.consume_front("://"))
    return llvm::None;
  return url;
}
}

ConnectionFileDescriptor::ConnectionFileDescriptor(bool child_processes_inherit)
    : Connection(), m_pipe(), m_mutex(), m_shutting_down(false),
      m_waiting_for_accept(false),
      m_child_processes_inherit(child_processes_inherit) {
  Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION |
                                                  LIBLLDB_LOG_OBJECT));
  LLDB_LOGF(log, "%p ConnectionFileDescriptor::ConnectionFileDescriptor ()",
            static_cast<void *>(this));
}

ConnectionFileDescriptor::ConnectionFileDescriptor(int fd, bool owns_fd)
    : Connection(), m_pipe(), m_mutex(), m_shutting_down(false),
      m_waiting_for_accept(false), m_child_processes_inherit(false) {
  m_write_sp = std::make_shared<NativeFile>(fd, File::eOpenOptionWrite, owns_fd);
  m_read_sp = std::make_shared<NativeFile>(fd, File::eOpenOptionRead, false);

  Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION |
                                                  LIBLLDB_LOG_OBJECT));
  LLDB_LOGF(log,
            "%p ConnectionFileDescriptor::ConnectionFileDescriptor (fd = "
            "%i, owns_fd = %i)",
            static_cast<void *>(this), fd, owns_fd);
  OpenCommandPipe();
}

ConnectionFileDescriptor::ConnectionFileDescriptor(Socket *socket)
    : Connection(), m_pipe(), m_mutex(), m_shutting_down(false),
      m_waiting_for_accept(false), m_child_processes_inherit(false) {
  InitializeSocket(socket);
}

ConnectionFileDescriptor::~ConnectionFileDescriptor() {
  Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION |
                                                  LIBLLDB_LOG_OBJECT));
  LLDB_LOGF(log, "%p ConnectionFileDescriptor::~ConnectionFileDescriptor ()",
            static_cast<void *>(this));
  Disconnect(nullptr);
  CloseCommandPipe();
}

void ConnectionFileDescriptor::OpenCommandPipe() {
  CloseCommandPipe();

  Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION));
  // Make the command file descriptor here:
  Status result = m_pipe.CreateNew(m_child_processes_inherit);
  if (!result.Success()) {
    LLDB_LOGF(log,
              "%p ConnectionFileDescriptor::OpenCommandPipe () - could not "
              "make pipe: %s",
              static_cast<void *>(this), result.AsCString());
  } else {
    LLDB_LOGF(log,
              "%p ConnectionFileDescriptor::OpenCommandPipe() - success "
              "readfd=%d writefd=%d",
              static_cast<void *>(this), m_pipe.GetReadFileDescriptor(),
              m_pipe.GetWriteFileDescriptor());
  }
}

void ConnectionFileDescriptor::CloseCommandPipe() {
  Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION));
  LLDB_LOGF(log, "%p ConnectionFileDescriptor::CloseCommandPipe()",
            static_cast<void *>(this));

  m_pipe.Close();
}

bool ConnectionFileDescriptor::IsConnected() const {
  return (m_read_sp && m_read_sp->IsValid()) ||
         (m_write_sp && m_write_sp->IsValid());
}

ConnectionStatus ConnectionFileDescriptor::Connect(llvm::StringRef path,
                                                   Status *error_ptr) {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);
  Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION));
  LLDB_LOGF(log, "%p ConnectionFileDescriptor::Connect (url = '%s')",
            static_cast<void *>(this), path.str().c_str());

  OpenCommandPipe();

  if (!path.empty()) {
    llvm::Optional<llvm::StringRef> addr;
    if ((addr = GetURLAddress(path, LISTEN_SCHEME))) {
      // listen://HOST:PORT
      return SocketListenAndAccept(*addr, error_ptr);
    } else if ((addr = GetURLAddress(path, ACCEPT_SCHEME))) {
      // unix://SOCKNAME
      return NamedSocketAccept(*addr, error_ptr);
    } else if ((addr = GetURLAddress(path, UNIX_ACCEPT_SCHEME))) {
      // unix://SOCKNAME
      return NamedSocketAccept(*addr, error_ptr);
    } else if ((addr = GetURLAddress(path, CONNECT_SCHEME))) {
      return ConnectTCP(*addr, error_ptr);
    } else if ((addr = GetURLAddress(path, TCP_CONNECT_SCHEME))) {
      return ConnectTCP(*addr, error_ptr);
    } else if ((addr = GetURLAddress(path, UDP_SCHEME))) {
      return ConnectUDP(*addr, error_ptr);
    } else if ((addr = GetURLAddress(path, UNIX_CONNECT_SCHEME))) {
      // unix-connect://SOCKNAME
      return NamedSocketConnect(*addr, error_ptr);
    } else if ((addr = GetURLAddress(path, UNIX_ABSTRACT_CONNECT_SCHEME))) {
      // unix-abstract-connect://SOCKNAME
      return UnixAbstractSocketConnect(*addr, error_ptr);
    }
#if LLDB_ENABLE_POSIX
    else if ((addr = GetURLAddress(path, FD_SCHEME))) {
      // Just passing a native file descriptor within this current process that
      // is already opened (possibly from a service or other source).
      int fd = -1;

      if (!addr->getAsInteger(0, fd)) {
        // We have what looks to be a valid file descriptor, but we should make
        // sure it is. We currently are doing this by trying to get the flags
        // from the file descriptor and making sure it isn't a bad fd.
        errno = 0;
        int flags = ::fcntl(fd, F_GETFL, 0);
        if (flags == -1 || errno == EBADF) {
          if (error_ptr)
            error_ptr->SetErrorStringWithFormat("stale file descriptor: %s",
                                                path.str().c_str());
          m_read_sp.reset();
          m_write_sp.reset();
          return eConnectionStatusError;
        } else {
          // Don't take ownership of a file descriptor that gets passed to us
          // since someone else opened the file descriptor and handed it to us.
          // TODO: Since are using a URL to open connection we should
          // eventually parse options using the web standard where we have
          // "fd://123?opt1=value;opt2=value" and we can have an option be
          // "owns=1" or "owns=0" or something like this to allow us to specify
          // this. For now, we assume we must assume we don't own it.

          std::unique_ptr<TCPSocket> tcp_socket;
          tcp_socket = std::make_unique<TCPSocket>(fd, false, false);
          // Try and get a socket option from this file descriptor to see if
          // this is a socket and set m_is_socket accordingly.
          int resuse;
          bool is_socket =
              !!tcp_socket->GetOption(SOL_SOCKET, SO_REUSEADDR, resuse);
          if (is_socket) {
            m_read_sp = std::move(tcp_socket);
            m_write_sp = m_read_sp;
          } else {
            m_read_sp =
                std::make_shared<NativeFile>(fd, File::eOpenOptionRead, false);
            m_write_sp =
                std::make_shared<NativeFile>(fd, File::eOpenOptionWrite, false);
          }
          m_uri = std::string(*addr);
          return eConnectionStatusSuccess;
        }
      }

      if (error_ptr)
        error_ptr->SetErrorStringWithFormat("invalid file descriptor: \"%s\"",
                                            path.str().c_str());
      m_read_sp.reset();
      m_write_sp.reset();
      return eConnectionStatusError;
    } else if ((addr = GetURLAddress(path, FILE_SCHEME))) {
      std::string addr_str = addr->str();
      // file:///PATH
      int fd = llvm::sys::RetryAfterSignal(-1, ::open, addr_str.c_str(), O_RDWR);
      if (fd == -1) {
        if (error_ptr)
          error_ptr->SetErrorToErrno();
        return eConnectionStatusError;
      }

      if (::isatty(fd)) {
        // Set up serial terminal emulation
        struct termios options;
        ::tcgetattr(fd, &options);

        // Set port speed to maximum
        ::cfsetospeed(&options, B115200);
        ::cfsetispeed(&options, B115200);

        // Raw input, disable echo and signals
        options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);

        // Make sure only one character is needed to return from a read
        options.c_cc[VMIN] = 1;
        options.c_cc[VTIME] = 0;

        llvm::sys::RetryAfterSignal(-1, ::tcsetattr, fd, TCSANOW, &options);
      }

      int flags = ::fcntl(fd, F_GETFL, 0);
      if (flags >= 0) {
        if ((flags & O_NONBLOCK) == 0) {
          flags |= O_NONBLOCK;
          ::fcntl(fd, F_SETFL, flags);
        }
      }
      m_read_sp = std::make_shared<NativeFile>(fd, File::eOpenOptionRead, true);
      m_write_sp = std::make_shared<NativeFile>(fd, File::eOpenOptionWrite, false);
      return eConnectionStatusSuccess;
    }
#endif
    if (error_ptr)
      error_ptr->SetErrorStringWithFormat("unsupported connection URL: '%s'",
                                          path.str().c_str());
    return eConnectionStatusError;
  }
  if (error_ptr)
    error_ptr->SetErrorString("invalid connect arguments");
  return eConnectionStatusError;
}

bool ConnectionFileDescriptor::InterruptRead() {
  size_t bytes_written = 0;
  Status result = m_pipe.Write("i", 1, bytes_written);
  return result.Success();
}

ConnectionStatus ConnectionFileDescriptor::Disconnect(Status *error_ptr) {
  Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION));
  LLDB_LOGF(log, "%p ConnectionFileDescriptor::Disconnect ()",
            static_cast<void *>(this));

  ConnectionStatus status = eConnectionStatusSuccess;

  if (!IsConnected()) {
    LLDB_LOGF(
        log, "%p ConnectionFileDescriptor::Disconnect(): Nothing to disconnect",
        static_cast<void *>(this));
    return eConnectionStatusSuccess;
  }

  if (m_read_sp && m_read_sp->IsValid() &&
      m_read_sp->GetFdType() == IOObject::eFDTypeSocket)
    static_cast<Socket &>(*m_read_sp).PreDisconnect();

  // Try to get the ConnectionFileDescriptor's mutex.  If we fail, that is
  // quite likely because somebody is doing a blocking read on our file
  // descriptor.  If that's the case, then send the "q" char to the command
  // file channel so the read will wake up and the connection will then know to
  // shut down.
  std::unique_lock<std::recursive_mutex> locker(m_mutex, std::defer_lock);
  if (!locker.try_lock()) {
    if (m_pipe.CanWrite()) {
      size_t bytes_written = 0;
      Status result = m_pipe.Write("q", 1, bytes_written);
      LLDB_LOGF(log,
                "%p ConnectionFileDescriptor::Disconnect(): Couldn't get "
                "the lock, sent 'q' to %d, error = '%s'.",
                static_cast<void *>(this), m_pipe.GetWriteFileDescriptor(),
                result.AsCString());
    } else if (log) {
      LLDB_LOGF(log,
                "%p ConnectionFileDescriptor::Disconnect(): Couldn't get the "
                "lock, but no command pipe is available.",
                static_cast<void *>(this));
    }
    locker.lock();
  }

  // Prevents reads and writes during shutdown.
  m_shutting_down = true;

  Status error = m_read_sp->Close();
  Status error2 = m_write_sp->Close();
  if (error.Fail() || error2.Fail())
    status = eConnectionStatusError;
  if (error_ptr)
    *error_ptr = error.Fail() ? error : error2;

  // Close any pipes we were using for async interrupts
  m_pipe.Close();

  m_uri.clear();
  m_shutting_down = false;
  return status;
}

size_t ConnectionFileDescriptor::Read(void *dst, size_t dst_len,
                                      const Timeout<std::micro> &timeout,
                                      ConnectionStatus &status,
                                      Status *error_ptr) {
  Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION));

  std::unique_lock<std::recursive_mutex> locker(m_mutex, std::defer_lock);
  if (!locker.try_lock()) {
    LLDB_LOGF(log,
              "%p ConnectionFileDescriptor::Read () failed to get the "
              "connection lock.",
              static_cast<void *>(this));
    if (error_ptr)
      error_ptr->SetErrorString("failed to get the connection lock for read.");

    status = eConnectionStatusTimedOut;
    return 0;
  }

  if (m_shutting_down) {
    if (error_ptr)
      error_ptr->SetErrorString("shutting down");
    status = eConnectionStatusError;
    return 0;
  }

  status = BytesAvailable(timeout, error_ptr);
  if (status != eConnectionStatusSuccess)
    return 0;

  Status error;
  size_t bytes_read = dst_len;
  error = m_read_sp->Read(dst, bytes_read);

  if (log) {
    LLDB_LOGF(log,
              "%p ConnectionFileDescriptor::Read()  fd = %" PRIu64
              ", dst = %p, dst_len = %" PRIu64 ") => %" PRIu64 ", error = %s",
              static_cast<void *>(this),
              static_cast<uint64_t>(m_read_sp->GetWaitableHandle()),
              static_cast<void *>(dst), static_cast<uint64_t>(dst_len),
              static_cast<uint64_t>(bytes_read), error.AsCString());
  }

  if (bytes_read == 0) {
    error.Clear(); // End-of-file.  Do not automatically close; pass along for
                   // the end-of-file handlers.
    status = eConnectionStatusEndOfFile;
  }

  if (error_ptr)
    *error_ptr = error;

  if (error.Fail()) {
    uint32_t error_value = error.GetError();
    switch (error_value) {
    case EAGAIN: // The file was marked for non-blocking I/O, and no data were
                 // ready to be read.
      if (m_read_sp->GetFdType() == IOObject::eFDTypeSocket)
        status = eConnectionStatusTimedOut;
      else
        status = eConnectionStatusSuccess;
      return 0;

    case EFAULT:  // Buf points outside the allocated address space.
    case EINTR:   // A read from a slow device was interrupted before any data
                  // arrived by the delivery of a signal.
    case EINVAL:  // The pointer associated with fildes was negative.
    case EIO:     // An I/O error occurred while reading from the file system.
                  // The process group is orphaned.
                  // The file is a regular file, nbyte is greater than 0, the
                  // starting position is before the end-of-file, and the
                  // starting position is greater than or equal to the offset
                  // maximum established for the open file descriptor
                  // associated with fildes.
    case EISDIR:  // An attempt is made to read a directory.
    case ENOBUFS: // An attempt to allocate a memory buffer fails.
    case ENOMEM:  // Insufficient memory is available.
      status = eConnectionStatusError;
      break; // Break to close....

    case ENOENT:     // no such file or directory
    case EBADF:      // fildes is not a valid file or socket descriptor open for
                     // reading.
    case ENXIO:      // An action is requested of a device that does not exist..
                     // A requested action cannot be performed by the device.
    case ECONNRESET: // The connection is closed by the peer during a read
                     // attempt on a socket.
    case ENOTCONN:   // A read is attempted on an unconnected socket.
      status = eConnectionStatusLostConnection;
      break; // Break to close....

    case ETIMEDOUT: // A transmission timeout occurs during a read attempt on a
                    // socket.
      status = eConnectionStatusTimedOut;
      return 0;

    default:
      LLDB_LOG(log, "this = {0}, unexpected error: {1}", this,
               llvm::sys::StrError(error_value));
      status = eConnectionStatusError;
      break; // Break to close....
    }

    return 0;
  }
  return bytes_read;
}

size_t ConnectionFileDescriptor::Write(const void *src, size_t src_len,
                                       ConnectionStatus &status,
                                       Status *error_ptr) {
  Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION));
  LLDB_LOGF(log,
            "%p ConnectionFileDescriptor::Write (src = %p, src_len = %" PRIu64
            ")",
            static_cast<void *>(this), static_cast<const void *>(src),
            static_cast<uint64_t>(src_len));

  if (!IsConnected()) {
    if (error_ptr)
      error_ptr->SetErrorString("not connected");
    status = eConnectionStatusNoConnection;
    return 0;
  }

  if (m_shutting_down) {
    if (error_ptr)
      error_ptr->SetErrorString("shutting down");
    status = eConnectionStatusError;
    return 0;
  }

  Status error;

  size_t bytes_sent = src_len;
  error = m_write_sp->Write(src, bytes_sent);

  if (log) {
    LLDB_LOGF(log,
              "%p ConnectionFileDescriptor::Write(fd = %" PRIu64
              ", src = %p, src_len = %" PRIu64 ") => %" PRIu64 " (error = %s)",
              static_cast<void *>(this),
              static_cast<uint64_t>(m_write_sp->GetWaitableHandle()),
              static_cast<const void *>(src), static_cast<uint64_t>(src_len),
              static_cast<uint64_t>(bytes_sent), error.AsCString());
  }

  if (error_ptr)
    *error_ptr = error;

  if (error.Fail()) {
    switch (error.GetError()) {
    case EAGAIN:
    case EINTR:
      status = eConnectionStatusSuccess;
      return 0;

    case ECONNRESET: // The connection is closed by the peer during a read
                     // attempt on a socket.
    case ENOTCONN:   // A read is attempted on an unconnected socket.
      status = eConnectionStatusLostConnection;
      break; // Break to close....

    default:
      status = eConnectionStatusError;
      break; // Break to close....
    }

    return 0;
  }

  status = eConnectionStatusSuccess;
  return bytes_sent;
}

std::string ConnectionFileDescriptor::GetURI() { return m_uri; }

// This ConnectionFileDescriptor::BytesAvailable() uses select() via
// SelectHelper
//
// PROS:
//  - select is consistent across most unix platforms
//  - The Apple specific version allows for unlimited fds in the fd_sets by
//    setting the _DARWIN_UNLIMITED_SELECT define prior to including the
//    required header files.
// CONS:
//  - on non-Apple platforms, only supports file descriptors up to FD_SETSIZE.
//     This implementation  will assert if it runs into that hard limit to let
//     users know that another ConnectionFileDescriptor::BytesAvailable() should
//     be used or a new version of ConnectionFileDescriptor::BytesAvailable()
//     should be written for the system that is running into the limitations.

ConnectionStatus
ConnectionFileDescriptor::BytesAvailable(const Timeout<std::micro> &timeout,
                                         Status *error_ptr) {
  // Don't need to take the mutex here separately since we are only called from
  // Read.  If we ever get used more generally we will need to lock here as
  // well.

  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_CONNECTION));
  LLDB_LOG(log, "this = {0}, timeout = {1}", this, timeout);

  // Make a copy of the file descriptors to make sure we don't have another
  // thread change these values out from under us and cause problems in the
  // loop below where like in FS_SET()
  const IOObject::WaitableHandle handle = m_read_sp->GetWaitableHandle();
  const int pipe_fd = m_pipe.GetReadFileDescriptor();

  if (handle != IOObject::kInvalidHandleValue) {
    SelectHelper select_helper;
    if (timeout)
      select_helper.SetTimeout(*timeout);

    select_helper.FDSetRead(handle);
#if defined(_WIN32)
    // select() won't accept pipes on Windows.  The entire Windows codepath
    // needs to be converted over to using WaitForMultipleObjects and event
    // HANDLEs, but for now at least this will allow ::select() to not return
    // an error.
    const bool have_pipe_fd = false;
#else
    const bool have_pipe_fd = pipe_fd >= 0;
#endif
    if (have_pipe_fd)
      select_helper.FDSetRead(pipe_fd);

    while (handle == m_read_sp->GetWaitableHandle()) {

      Status error = select_helper.Select();

      if (error_ptr)
        *error_ptr = error;

      if (error.Fail()) {
        switch (error.GetError()) {
        case EBADF: // One of the descriptor sets specified an invalid
                    // descriptor.
          return eConnectionStatusLostConnection;

        case EINVAL: // The specified time limit is invalid. One of its
                     // components is negative or too large.
        default:     // Other unknown error
          return eConnectionStatusError;

        case ETIMEDOUT:
          return eConnectionStatusTimedOut;

        case EAGAIN: // The kernel was (perhaps temporarily) unable to
                     // allocate the requested number of file descriptors, or
                     // we have non-blocking IO
        case EINTR:  // A signal was delivered before the time limit
          // expired and before any of the selected events occurred.
          break; // Lets keep reading to until we timeout
        }
      } else {
        if (select_helper.FDIsSetRead(handle))
          return eConnectionStatusSuccess;

        if (select_helper.FDIsSetRead(pipe_fd)) {
          // There is an interrupt or exit command in the command pipe Read the
          // data from that pipe:
          char c;

          ssize_t bytes_read = llvm::sys::RetryAfterSignal(-1, ::read, pipe_fd, &c, 1);
          assert(bytes_read == 1);
          (void)bytes_read;
          switch (c) {
          case 'q':
            LLDB_LOGF(log,
                      "%p ConnectionFileDescriptor::BytesAvailable() "
                      "got data: %c from the command channel.",
                      static_cast<void *>(this), c);
            return eConnectionStatusEndOfFile;
          case 'i':
            // Interrupt the current read
            return eConnectionStatusInterrupted;
          }
        }
      }
    }
  }

  if (error_ptr)
    error_ptr->SetErrorString("not connected");
  return eConnectionStatusLostConnection;
}

ConnectionStatus
ConnectionFileDescriptor::NamedSocketAccept(llvm::StringRef socket_name,
                                            Status *error_ptr) {
  Socket *socket = nullptr;
  Status error =
      Socket::UnixDomainAccept(socket_name, m_child_processes_inherit, socket);
  if (error_ptr)
    *error_ptr = error;
  m_write_sp.reset(socket);
  m_read_sp = m_write_sp;
  if (error.Fail()) {
    return eConnectionStatusError;
  }
  m_uri.assign(std::string(socket_name));
  return eConnectionStatusSuccess;
}

ConnectionStatus
ConnectionFileDescriptor::NamedSocketConnect(llvm::StringRef socket_name,
                                             Status *error_ptr) {
  Socket *socket = nullptr;
  Status error =
      Socket::UnixDomainConnect(socket_name, m_child_processes_inherit, socket);
  if (error_ptr)
    *error_ptr = error;
  m_write_sp.reset(socket);
  m_read_sp = m_write_sp;
  if (error.Fail()) {
    return eConnectionStatusError;
  }
  m_uri.assign(std::string(socket_name));
  return eConnectionStatusSuccess;
}

lldb::ConnectionStatus
ConnectionFileDescriptor::UnixAbstractSocketConnect(llvm::StringRef socket_name,
                                                    Status *error_ptr) {
  Socket *socket = nullptr;
  Status error = Socket::UnixAbstractConnect(socket_name,
                                             m_child_processes_inherit, socket);
  if (error_ptr)
    *error_ptr = error;
  m_write_sp.reset(socket);
  m_read_sp = m_write_sp;
  if (error.Fail()) {
    return eConnectionStatusError;
  }
  m_uri.assign(std::string(socket_name));
  return eConnectionStatusSuccess;
}

ConnectionStatus
ConnectionFileDescriptor::SocketListenAndAccept(llvm::StringRef s,
                                                Status *error_ptr) {
  if (error_ptr)
    *error_ptr = Status();
  m_port_predicate.SetValue(0, eBroadcastNever);

  m_waiting_for_accept = true;
  llvm::Expected<std::unique_ptr<TCPSocket>> listening_socket =
      Socket::TcpListen(s, m_child_processes_inherit, &m_port_predicate);
  if (!listening_socket) {
    if (error_ptr)
      *error_ptr = listening_socket.takeError();
    else
      LLDB_LOG_ERROR(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION),
                     listening_socket.takeError(), "tcp listen failed: {0}");
    return eConnectionStatusError;
  }


  Socket *accepted_socket;
  Status error = listening_socket.get()->Accept(accepted_socket);
  if (error_ptr)
    *error_ptr = error;
  if (error.Fail())
    return eConnectionStatusError;

  InitializeSocket(accepted_socket);
  return eConnectionStatusSuccess;
}

ConnectionStatus ConnectionFileDescriptor::ConnectTCP(llvm::StringRef s,
                                                      Status *error_ptr) {
  if (error_ptr)
    *error_ptr = Status();

  llvm::Expected<std::unique_ptr<Socket>> socket =
      Socket::TcpConnect(s, m_child_processes_inherit);
  if (!socket) {
    if (error_ptr)
      *error_ptr = socket.takeError();
    else
      LLDB_LOG_ERROR(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION),
                     socket.takeError(), "tcp connect failed: {0}");
    return eConnectionStatusError;
  }
  m_write_sp = std::move(*socket);
  m_read_sp = m_write_sp;
  m_uri.assign(std::string(s));
  return eConnectionStatusSuccess;
}

ConnectionStatus ConnectionFileDescriptor::ConnectUDP(llvm::StringRef s,
                                                      Status *error_ptr) {
  if (error_ptr)
    *error_ptr = Status();
  llvm::Expected<std::unique_ptr<UDPSocket>> socket =
      Socket::UdpConnect(s, m_child_processes_inherit);
  if (!socket) {
    if (error_ptr)
      *error_ptr = socket.takeError();
    else
      LLDB_LOG_ERROR(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION),
                     socket.takeError(), "tcp connect failed: {0}");
    return eConnectionStatusError;
  }
  m_write_sp = std::move(*socket);
  m_read_sp = m_write_sp;
  m_uri.assign(std::string(s));
  return eConnectionStatusSuccess;
}

uint16_t
ConnectionFileDescriptor::GetListeningPort(const Timeout<std::micro> &timeout) {
  auto Result = m_port_predicate.WaitForValueNotEqualTo(0, timeout);
  return Result ? *Result : 0;
}

bool ConnectionFileDescriptor::GetChildProcessesInherit() const {
  return m_child_processes_inherit;
}

void ConnectionFileDescriptor::SetChildProcessesInherit(
    bool child_processes_inherit) {
  m_child_processes_inherit = child_processes_inherit;
}

void ConnectionFileDescriptor::InitializeSocket(Socket *socket) {
  m_write_sp.reset(socket);
  m_read_sp = m_write_sp;
  m_uri = socket->GetRemoteConnectionURI();
}
