//===-- 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/FileSystem.h"
#include "lldb/Host/Socket.h"
#include "lldb/Host/SocketAddress.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/SelectHelper.h"
#include "lldb/Utility/Timeout.h"

#include <cerrno>
#include <cstdlib>
#include <cstring>
#include <fcntl.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;

ConnectionFileDescriptor::ConnectionFileDescriptor(bool child_processes_inherit)
    : Connection(), m_pipe(), m_mutex(), m_shutting_down(false),

      m_child_processes_inherit(child_processes_inherit) {
  Log *log(GetLog(LLDBLog::Connection | LLDBLog::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_child_processes_inherit(false) {
  m_io_sp =
      std::make_shared<NativeFile>(fd, File::eOpenOptionReadWrite, owns_fd);

  Log *log(GetLog(LLDBLog::Connection | LLDBLog::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_child_processes_inherit(false) {
  InitializeSocket(socket);
}

ConnectionFileDescriptor::~ConnectionFileDescriptor() {
  Log *log(GetLog(LLDBLog::Connection | LLDBLog::Object));
  LLDB_LOGF(log, "%p ConnectionFileDescriptor::~ConnectionFileDescriptor ()",
            static_cast<void *>(this));
  Disconnect(nullptr);
  CloseCommandPipe();
}

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

  Log *log = GetLog(LLDBLog::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 = GetLog(LLDBLog::Connection);
  LLDB_LOGF(log, "%p ConnectionFileDescriptor::CloseCommandPipe()",
            static_cast<void *>(this));

  m_pipe.Close();
}

bool ConnectionFileDescriptor::IsConnected() const {
  return m_io_sp && m_io_sp->IsValid();
}

ConnectionStatus ConnectionFileDescriptor::Connect(llvm::StringRef path,
                                                   Status *error_ptr) {
  return Connect(
      path, [](llvm::StringRef) {}, error_ptr);
}

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

  OpenCommandPipe();

  if (path.empty()) {
    if (error_ptr)
      *error_ptr = Status::FromErrorString("invalid connect arguments");
    return eConnectionStatusError;
  }

  llvm::StringRef scheme;
  std::tie(scheme, path) = path.split("://");

  if (!path.empty()) {
    auto method =
        llvm::StringSwitch<ConnectionStatus (ConnectionFileDescriptor::*)(
            llvm::StringRef, socket_id_callback_type, Status *)>(scheme)
            .Case("listen", &ConnectionFileDescriptor::AcceptTCP)
            .Cases("accept", "unix-accept",
                   &ConnectionFileDescriptor::AcceptNamedSocket)
            .Case("unix-abstract-accept",
                  &ConnectionFileDescriptor::AcceptAbstractSocket)
            .Cases("connect", "tcp-connect",
                   &ConnectionFileDescriptor::ConnectTCP)
            .Case("udp", &ConnectionFileDescriptor::ConnectUDP)
            .Case("unix-connect", &ConnectionFileDescriptor::ConnectNamedSocket)
            .Case("unix-abstract-connect",
                  &ConnectionFileDescriptor::ConnectAbstractSocket)
#if LLDB_ENABLE_POSIX
            .Case("fd", &ConnectionFileDescriptor::ConnectFD)
            .Case("file", &ConnectionFileDescriptor::ConnectFile)
            .Case("serial", &ConnectionFileDescriptor::ConnectSerialPort)
#endif
            .Default(nullptr);

    if (method) {
      if (error_ptr)
        *error_ptr = Status();
      return (this->*method)(path, socket_id_callback, error_ptr);
    }
  }

  if (error_ptr)
    *error_ptr = Status::FromErrorStringWithFormat(
        "unsupported connection URL: '%s'", path.str().c_str());
  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 = GetLog(LLDBLog::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;
  }

  // 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_io_sp->Close();
  if (error.Fail())
    status = eConnectionStatusError;
  if (error_ptr)
    *error_ptr = std::move(error);

  // 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 = GetLog(LLDBLog::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 = Status::FromErrorString(
          "failed to get the connection lock for read.");

    status = eConnectionStatusTimedOut;
    return 0;
  }

  if (m_shutting_down) {
    if (error_ptr)
      *error_ptr = Status::FromErrorString("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_io_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_io_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.Clone();

  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_io_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 = GetLog(LLDBLog::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 = Status::FromErrorString("not connected");
    status = eConnectionStatusNoConnection;
    return 0;
  }

  if (m_shutting_down) {
    if (error_ptr)
      *error_ptr = Status::FromErrorString("shutting down");
    status = eConnectionStatusError;
    return 0;
  }

  Status error;

  size_t bytes_sent = src_len;
  error = m_io_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_io_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.Clone();

  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 = GetLog(LLDBLog::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_io_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_io_sp->GetWaitableHandle()) {

      Status error = select_helper.Select();

      if (error_ptr)
        *error_ptr = error.Clone();

      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);
          UNUSED_IF_ASSERT_DISABLED(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 = Status::FromErrorString("not connected");
  return eConnectionStatusLostConnection;
}

lldb::ConnectionStatus ConnectionFileDescriptor::AcceptSocket(
    Socket::SocketProtocol socket_protocol, llvm::StringRef socket_name,
    llvm::function_ref<void(Socket &)> post_listen_callback,
    Status *error_ptr) {
  Status error;
  std::unique_ptr<Socket> listening_socket =
      Socket::Create(socket_protocol, m_child_processes_inherit, error);
  Socket *accepted_socket;

  if (!error.Fail())
    error = listening_socket->Listen(socket_name, 5);

  if (!error.Fail()) {
    post_listen_callback(*listening_socket);
    error = listening_socket->Accept(accepted_socket);
  }

  if (!error.Fail()) {
    m_io_sp.reset(accepted_socket);
    m_uri.assign(socket_name.str());
    return eConnectionStatusSuccess;
  }

  if (error_ptr)
    *error_ptr = error.Clone();
  return eConnectionStatusError;
}

lldb::ConnectionStatus
ConnectionFileDescriptor::ConnectSocket(Socket::SocketProtocol socket_protocol,
                                        llvm::StringRef socket_name,
                                        Status *error_ptr) {
  Status error;
  std::unique_ptr<Socket> socket =
      Socket::Create(socket_protocol, m_child_processes_inherit, error);

  if (!error.Fail())
    error = socket->Connect(socket_name);

  if (!error.Fail()) {
    m_io_sp = std::move(socket);
    m_uri.assign(socket_name.str());
    return eConnectionStatusSuccess;
  }

  if (error_ptr)
    *error_ptr = error.Clone();
  return eConnectionStatusError;
}

ConnectionStatus ConnectionFileDescriptor::AcceptNamedSocket(
    llvm::StringRef socket_name, socket_id_callback_type socket_id_callback,
    Status *error_ptr) {
  return AcceptSocket(
      Socket::ProtocolUnixDomain, socket_name,
      [socket_id_callback, socket_name](Socket &listening_socket) {
        socket_id_callback(socket_name);
      },
      error_ptr);
}

ConnectionStatus ConnectionFileDescriptor::ConnectNamedSocket(
    llvm::StringRef socket_name, socket_id_callback_type socket_id_callback,
    Status *error_ptr) {
  return ConnectSocket(Socket::ProtocolUnixDomain, socket_name, error_ptr);
}

ConnectionStatus ConnectionFileDescriptor::AcceptAbstractSocket(
    llvm::StringRef socket_name, socket_id_callback_type socket_id_callback,
    Status *error_ptr) {
  return AcceptSocket(
      Socket::ProtocolUnixAbstract, socket_name,
      [socket_id_callback, socket_name](Socket &listening_socket) {
        socket_id_callback(socket_name);
      },
      error_ptr);
}

lldb::ConnectionStatus ConnectionFileDescriptor::ConnectAbstractSocket(
    llvm::StringRef socket_name, socket_id_callback_type socket_id_callback,
    Status *error_ptr) {
  return ConnectSocket(Socket::ProtocolUnixAbstract, socket_name, error_ptr);
}

ConnectionStatus
ConnectionFileDescriptor::AcceptTCP(llvm::StringRef socket_name,
                                    socket_id_callback_type socket_id_callback,
                                    Status *error_ptr) {
  ConnectionStatus ret = AcceptSocket(
      Socket::ProtocolTcp, socket_name,
      [socket_id_callback](Socket &listening_socket) {
        uint16_t port =
            static_cast<TCPSocket &>(listening_socket).GetLocalPortNumber();
        socket_id_callback(std::to_string(port));
      },
      error_ptr);
  if (ret == eConnectionStatusSuccess)
    m_uri.assign(
        static_cast<TCPSocket *>(m_io_sp.get())->GetRemoteConnectionURI());
  return ret;
}

ConnectionStatus
ConnectionFileDescriptor::ConnectTCP(llvm::StringRef socket_name,
                                     socket_id_callback_type socket_id_callback,
                                     Status *error_ptr) {
  return ConnectSocket(Socket::ProtocolTcp, socket_name, error_ptr);
}

ConnectionStatus
ConnectionFileDescriptor::ConnectUDP(llvm::StringRef s,
                                     socket_id_callback_type socket_id_callback,
                                     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 = Status::FromError(socket.takeError());
    else
      LLDB_LOG_ERROR(GetLog(LLDBLog::Connection), socket.takeError(),
                     "tcp connect failed: {0}");
    return eConnectionStatusError;
  }
  m_io_sp = std::move(*socket);
  m_uri.assign(std::string(s));
  return eConnectionStatusSuccess;
}

ConnectionStatus
ConnectionFileDescriptor::ConnectFD(llvm::StringRef s,
                                    socket_id_callback_type socket_id_callback,
                                    Status *error_ptr) {
#if LLDB_ENABLE_POSIX
  // 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 (!s.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 = Status::FromErrorStringWithFormat(
            "stale file descriptor: %s", s.str().c_str());
      m_io_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_io_sp = std::move(tcp_socket);
      else
        m_io_sp =
            std::make_shared<NativeFile>(fd, File::eOpenOptionReadWrite, false);
      m_uri = s.str();
      return eConnectionStatusSuccess;
    }
  }

  if (error_ptr)
    *error_ptr = Status::FromErrorStringWithFormat(
        "invalid file descriptor: \"%s\"", s.str().c_str());
  m_io_sp.reset();
  return eConnectionStatusError;
#endif // LLDB_ENABLE_POSIX
  llvm_unreachable("this function should be only called w/ LLDB_ENABLE_POSIX");
}

ConnectionStatus ConnectionFileDescriptor::ConnectFile(
    llvm::StringRef s, socket_id_callback_type socket_id_callback,
    Status *error_ptr) {
#if LLDB_ENABLE_POSIX
  std::string addr_str = s.str();
  // file:///PATH
  int fd = FileSystem::Instance().Open(addr_str.c_str(), O_RDWR);
  if (fd == -1) {
    if (error_ptr)
      *error_ptr = Status::FromErrno();
    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);
  }

  m_io_sp = std::make_shared<NativeFile>(fd, File::eOpenOptionReadWrite, true);
  return eConnectionStatusSuccess;
#endif // LLDB_ENABLE_POSIX
  llvm_unreachable("this function should be only called w/ LLDB_ENABLE_POSIX");
}

ConnectionStatus ConnectionFileDescriptor::ConnectSerialPort(
    llvm::StringRef s, socket_id_callback_type socket_id_callback,
    Status *error_ptr) {
#if LLDB_ENABLE_POSIX
  llvm::StringRef path, qs;
  // serial:///PATH?k1=v1&k2=v2...
  std::tie(path, qs) = s.split('?');

  llvm::Expected<SerialPort::Options> serial_options =
      SerialPort::OptionsFromURL(qs);
  if (!serial_options) {
    if (error_ptr)
      *error_ptr = Status::FromError(serial_options.takeError());
    else
      llvm::consumeError(serial_options.takeError());
    return eConnectionStatusError;
  }

  int fd = FileSystem::Instance().Open(path.str().c_str(), O_RDWR);
  if (fd == -1) {
    if (error_ptr)
      *error_ptr = Status::FromErrno();
    return eConnectionStatusError;
  }

  llvm::Expected<std::unique_ptr<SerialPort>> serial_sp = SerialPort::Create(
      fd, File::eOpenOptionReadWrite, serial_options.get(), true);
  if (!serial_sp) {
    if (error_ptr)
      *error_ptr = Status::FromError(serial_sp.takeError());
    else
      llvm::consumeError(serial_sp.takeError());
    return eConnectionStatusError;
  }
  m_io_sp = std::move(serial_sp.get());

  return eConnectionStatusSuccess;
#endif // LLDB_ENABLE_POSIX
  llvm_unreachable("this function should be only called w/ LLDB_ENABLE_POSIX");
}

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_io_sp.reset(socket);
  m_uri = socket->GetRemoteConnectionURI();
}
