//===-- debugserver.cpp -----------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include <arpa/inet.h>
#include <asl.h>
#include <crt_externs.h> // for _NSGetEnviron()
#include <errno.h>
#include <getopt.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <string>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <sys/types.h>
#include <sys/types.h>
#include <sys/un.h>
#include <vector>

#if defined(__APPLE__)
#include <sched.h>
extern "C" int proc_set_wakemon_params(pid_t, int,
                                       int); // <libproc_internal.h> SPI
#endif

#include "CFString.h"
#include "DNB.h"
#include "DNBLog.h"
#include "DNBTimer.h"
#include "OsLogger.h"
#include "PseudoTerminal.h"
#include "RNBContext.h"
#include "RNBRemote.h"
#include "RNBServices.h"
#include "RNBSocket.h"
#include "SysSignal.h"

// Global PID in case we get a signal and need to stop the process...
nub_process_t g_pid = INVALID_NUB_PROCESS;

//----------------------------------------------------------------------
// Run loop modes which determine which run loop function will be called
//----------------------------------------------------------------------
typedef enum {
  eRNBRunLoopModeInvalid = 0,
  eRNBRunLoopModeGetStartModeFromRemoteProtocol,
  eRNBRunLoopModeInferiorAttaching,
  eRNBRunLoopModeInferiorLaunching,
  eRNBRunLoopModeInferiorExecuting,
  eRNBRunLoopModePlatformMode,
  eRNBRunLoopModeExit
} RNBRunLoopMode;

//----------------------------------------------------------------------
// Global Variables
//----------------------------------------------------------------------
RNBRemoteSP g_remoteSP;
static int g_lockdown_opt = 0;
static int g_applist_opt = 0;
static nub_launch_flavor_t g_launch_flavor = eLaunchFlavorDefault;
int g_disable_aslr = 0;

int g_isatty = 0;
bool g_detach_on_error = true;

#define RNBLogSTDOUT(fmt, ...)                                                 \
  do {                                                                         \
    if (g_isatty) {                                                            \
      fprintf(stdout, fmt, ##__VA_ARGS__);                                     \
    } else {                                                                   \
      _DNBLog(0, fmt, ##__VA_ARGS__);                                          \
    }                                                                          \
  } while (0)
#define RNBLogSTDERR(fmt, ...)                                                 \
  do {                                                                         \
    if (g_isatty) {                                                            \
      fprintf(stderr, fmt, ##__VA_ARGS__);                                     \
    } else {                                                                   \
      _DNBLog(0, fmt, ##__VA_ARGS__);                                          \
    }                                                                          \
  } while (0)

//----------------------------------------------------------------------
// Get our program path and arguments from the remote connection.
// We will need to start up the remote connection without a PID, get the
// arguments, wait for the new process to finish launching and hit its
// entry point,  and then return the run loop mode that should come next.
//----------------------------------------------------------------------
RNBRunLoopMode RNBRunLoopGetStartModeFromRemote(RNBRemote *remote) {
  std::string packet;

  if (remote) {
    RNBContext &ctx = remote->Context();
    uint32_t event_mask = RNBContext::event_read_packet_available |
                          RNBContext::event_read_thread_exiting;

    // Spin waiting to get the A packet.
    while (1) {
      DNBLogThreadedIf(LOG_RNB_MAX,
                       "%s ctx.Events().WaitForSetEvents( 0x%08x ) ...",
                       __FUNCTION__, event_mask);
      nub_event_t set_events = ctx.Events().WaitForSetEvents(event_mask);
      DNBLogThreadedIf(LOG_RNB_MAX,
                       "%s ctx.Events().WaitForSetEvents( 0x%08x ) => 0x%08x",
                       __FUNCTION__, event_mask, set_events);

      if (set_events & RNBContext::event_read_thread_exiting) {
        RNBLogSTDERR("error: packet read thread exited.\n");
        return eRNBRunLoopModeExit;
      }

      if (set_events & RNBContext::event_read_packet_available) {
        rnb_err_t err = rnb_err;
        RNBRemote::PacketEnum type;

        err = remote->HandleReceivedPacket(&type);

        // check if we tried to attach to a process
        if (type == RNBRemote::vattach || type == RNBRemote::vattachwait ||
            type == RNBRemote::vattachorwait) {
          if (err == rnb_success) {
            RNBLogSTDOUT("Attach succeeded, ready to debug.\n");
            return eRNBRunLoopModeInferiorExecuting;
          } else {
            RNBLogSTDERR("error: attach failed.\n");
            return eRNBRunLoopModeExit;
          }
        }

        if (err == rnb_success) {
          // If we got our arguments we are ready to launch using the arguments
          // and any environment variables we received.
          if (type == RNBRemote::set_argv) {
            return eRNBRunLoopModeInferiorLaunching;
          }
        } else if (err == rnb_not_connected) {
          RNBLogSTDERR("error: connection lost.\n");
          return eRNBRunLoopModeExit;
        } else {
          // a catch all for any other gdb remote packets that failed
          DNBLogThreadedIf(LOG_RNB_MINIMAL, "%s Error getting packet.",
                           __FUNCTION__);
          continue;
        }

        DNBLogThreadedIf(LOG_RNB_MINIMAL, "#### %s", __FUNCTION__);
      } else {
        DNBLogThreadedIf(LOG_RNB_MINIMAL,
                         "%s Connection closed before getting \"A\" packet.",
                         __FUNCTION__);
        return eRNBRunLoopModeExit;
      }
    }
  }
  return eRNBRunLoopModeExit;
}

//----------------------------------------------------------------------
// This run loop mode will wait for the process to launch and hit its
// entry point. It will currently ignore all events except for the
// process state changed event, where it watches for the process stopped
// or crash process state.
//----------------------------------------------------------------------
RNBRunLoopMode RNBRunLoopLaunchInferior(RNBRemote *remote,
                                        const char *stdin_path,
                                        const char *stdout_path,
                                        const char *stderr_path,
                                        bool no_stdio) {
  RNBContext &ctx = remote->Context();

  // The Process stuff takes a c array, the RNBContext has a vector...
  // So make up a c array.

  DNBLogThreadedIf(LOG_RNB_MINIMAL, "%s Launching '%s'...", __FUNCTION__,
                   ctx.ArgumentAtIndex(0));

  size_t inferior_argc = ctx.ArgumentCount();
  // Initialize inferior_argv with inferior_argc + 1 NULLs
  std::vector<const char *> inferior_argv(inferior_argc + 1, NULL);

  size_t i;
  for (i = 0; i < inferior_argc; i++)
    inferior_argv[i] = ctx.ArgumentAtIndex(i);

  // Pass the environment array the same way:

  size_t inferior_envc = ctx.EnvironmentCount();
  // Initialize inferior_argv with inferior_argc + 1 NULLs
  std::vector<const char *> inferior_envp(inferior_envc + 1, NULL);

  for (i = 0; i < inferior_envc; i++)
    inferior_envp[i] = ctx.EnvironmentAtIndex(i);

  // Our launch type hasn't been set to anything concrete, so we need to
  // figure our how we are going to launch automatically.

  nub_launch_flavor_t launch_flavor = g_launch_flavor;
  if (launch_flavor == eLaunchFlavorDefault) {
    // Our default launch method is posix spawn
    launch_flavor = eLaunchFlavorPosixSpawn;

#if defined WITH_FBS
    // Check if we have an app bundle, if so launch using BackBoard Services.
    if (strstr(inferior_argv[0], ".app")) {
      launch_flavor = eLaunchFlavorFBS;
    }
#elif defined WITH_BKS
    // Check if we have an app bundle, if so launch using BackBoard Services.
    if (strstr(inferior_argv[0], ".app")) {
      launch_flavor = eLaunchFlavorBKS;
    }
#elif defined WITH_SPRINGBOARD
    // Check if we have an app bundle, if so launch using SpringBoard.
    if (strstr(inferior_argv[0], ".app")) {
      launch_flavor = eLaunchFlavorSpringBoard;
    }
#endif
  }

  ctx.SetLaunchFlavor(launch_flavor);
  char resolved_path[PATH_MAX];

  // If we fail to resolve the path to our executable, then just use what we
  // were given and hope for the best
  if (!DNBResolveExecutablePath(inferior_argv[0], resolved_path,
                                sizeof(resolved_path)))
    ::strlcpy(resolved_path, inferior_argv[0], sizeof(resolved_path));

  char launch_err_str[PATH_MAX];
  launch_err_str[0] = '\0';
  const char *cwd =
      (ctx.GetWorkingDirPath() != NULL ? ctx.GetWorkingDirPath()
                                       : ctx.GetWorkingDirectory());
  const char *process_event = ctx.GetProcessEvent();
  nub_process_t pid = DNBProcessLaunch(
      resolved_path, &inferior_argv[0], &inferior_envp[0], cwd, stdin_path,
      stdout_path, stderr_path, no_stdio, launch_flavor, g_disable_aslr,
      process_event, launch_err_str, sizeof(launch_err_str));

  g_pid = pid;

  if (pid == INVALID_NUB_PROCESS && strlen(launch_err_str) > 0) {
    DNBLogThreaded("%s DNBProcessLaunch() returned error: '%s'", __FUNCTION__,
                   launch_err_str);
    ctx.LaunchStatus().SetError(-1, DNBError::Generic);
    ctx.LaunchStatus().SetErrorString(launch_err_str);
  } else if (pid == INVALID_NUB_PROCESS) {
    DNBLogThreaded(
        "%s DNBProcessLaunch() failed to launch process, unknown failure",
        __FUNCTION__);
    ctx.LaunchStatus().SetError(-1, DNBError::Generic);
    ctx.LaunchStatus().SetErrorString("<unknown failure>");
  } else {
    ctx.LaunchStatus().Clear();
  }

  if (remote->Comm().IsConnected()) {
    // It we are connected already, the next thing gdb will do is ask
    // whether the launch succeeded, and if not, whether there is an
    // error code.  So we need to fetch one packet from gdb before we wait
    // on the stop from the target.

    uint32_t event_mask = RNBContext::event_read_packet_available;
    nub_event_t set_events = ctx.Events().WaitForSetEvents(event_mask);

    if (set_events & RNBContext::event_read_packet_available) {
      rnb_err_t err = rnb_err;
      RNBRemote::PacketEnum type;

      err = remote->HandleReceivedPacket(&type);

      if (err != rnb_success) {
        DNBLogThreadedIf(LOG_RNB_MINIMAL, "%s Error getting packet.",
                         __FUNCTION__);
        return eRNBRunLoopModeExit;
      }
      if (type != RNBRemote::query_launch_success) {
        DNBLogThreadedIf(LOG_RNB_MINIMAL,
                         "%s Didn't get the expected qLaunchSuccess packet.",
                         __FUNCTION__);
      }
    }
  }

  while (pid != INVALID_NUB_PROCESS) {
    // Wait for process to start up and hit entry point
    DNBLogThreadedIf(LOG_RNB_EVENTS, "%s DNBProcessWaitForEvent (%4.4x, "
                                     "eEventProcessRunningStateChanged | "
                                     "eEventProcessStoppedStateChanged, true, "
                                     "INFINITE)...",
                     __FUNCTION__, pid);
    nub_event_t set_events =
        DNBProcessWaitForEvents(pid, eEventProcessRunningStateChanged |
                                         eEventProcessStoppedStateChanged,
                                true, NULL);
    DNBLogThreadedIf(LOG_RNB_EVENTS, "%s DNBProcessWaitForEvent (%4.4x, "
                                     "eEventProcessRunningStateChanged | "
                                     "eEventProcessStoppedStateChanged, true, "
                                     "INFINITE) => 0x%8.8x",
                     __FUNCTION__, pid, set_events);

    if (set_events == 0) {
      pid = INVALID_NUB_PROCESS;
      g_pid = pid;
    } else {
      if (set_events & (eEventProcessRunningStateChanged |
                        eEventProcessStoppedStateChanged)) {
        nub_state_t pid_state = DNBProcessGetState(pid);
        DNBLogThreadedIf(
            LOG_RNB_EVENTS,
            "%s process %4.4x state changed (eEventProcessStateChanged): %s",
            __FUNCTION__, pid, DNBStateAsString(pid_state));

        switch (pid_state) {
        case eStateInvalid:
        case eStateUnloaded:
        case eStateAttaching:
        case eStateLaunching:
        case eStateSuspended:
          break; // Ignore

        case eStateRunning:
        case eStateStepping:
          // Still waiting to stop at entry point...
          break;

        case eStateStopped:
        case eStateCrashed:
          ctx.SetProcessID(pid);
          return eRNBRunLoopModeInferiorExecuting;

        case eStateDetached:
        case eStateExited:
          pid = INVALID_NUB_PROCESS;
          g_pid = pid;
          return eRNBRunLoopModeExit;
        }
      }

      DNBProcessResetEvents(pid, set_events);
    }
  }

  return eRNBRunLoopModeExit;
}

//----------------------------------------------------------------------
// This run loop mode will wait for the process to launch and hit its
// entry point. It will currently ignore all events except for the
// process state changed event, where it watches for the process stopped
// or crash process state.
//----------------------------------------------------------------------
RNBRunLoopMode RNBRunLoopLaunchAttaching(RNBRemote *remote,
                                         nub_process_t attach_pid,
                                         nub_process_t &pid) {
  RNBContext &ctx = remote->Context();

  DNBLogThreadedIf(LOG_RNB_MINIMAL, "%s Attaching to pid %i...", __FUNCTION__,
                   attach_pid);
  char err_str[1024];
  pid = DNBProcessAttach(attach_pid, NULL, err_str, sizeof(err_str));
  g_pid = pid;

  if (pid == INVALID_NUB_PROCESS) {
    ctx.LaunchStatus().SetError(-1, DNBError::Generic);
    if (err_str[0])
      ctx.LaunchStatus().SetErrorString(err_str);
    return eRNBRunLoopModeExit;
  } else {
    ctx.SetProcessID(pid);
    return eRNBRunLoopModeInferiorExecuting;
  }
}

//----------------------------------------------------------------------
// Watch for signals:
// SIGINT: so we can halt our inferior. (disabled for now)
// SIGPIPE: in case our child process dies
//----------------------------------------------------------------------
int g_sigint_received = 0;
int g_sigpipe_received = 0;
void signal_handler(int signo) {
  DNBLogThreadedIf(LOG_RNB_MINIMAL, "%s (%s)", __FUNCTION__,
                   SysSignal::Name(signo));

  switch (signo) {
  case SIGINT:
    g_sigint_received++;
    if (g_pid != INVALID_NUB_PROCESS) {
      // Only send a SIGINT once...
      if (g_sigint_received == 1) {
        switch (DNBProcessGetState(g_pid)) {
        case eStateRunning:
        case eStateStepping:
          DNBProcessSignal(g_pid, SIGSTOP);
          return;
        default:
          break;
        }
      }
    }
    exit(SIGINT);
    break;

  case SIGPIPE:
    g_sigpipe_received = 1;
    break;
  }
}

// Return the new run loop mode based off of the current process state
RNBRunLoopMode HandleProcessStateChange(RNBRemote *remote, bool initialize) {
  RNBContext &ctx = remote->Context();
  nub_process_t pid = ctx.ProcessID();

  if (pid == INVALID_NUB_PROCESS) {
    DNBLogThreadedIf(LOG_RNB_MINIMAL, "#### %s error: pid invalid, exiting...",
                     __FUNCTION__);
    return eRNBRunLoopModeExit;
  }
  nub_state_t pid_state = DNBProcessGetState(pid);

  DNBLogThreadedIf(LOG_RNB_MINIMAL,
                   "%s (&remote, initialize=%i)  pid_state = %s", __FUNCTION__,
                   (int)initialize, DNBStateAsString(pid_state));

  switch (pid_state) {
  case eStateInvalid:
  case eStateUnloaded:
    // Something bad happened
    return eRNBRunLoopModeExit;
    break;

  case eStateAttaching:
  case eStateLaunching:
    return eRNBRunLoopModeInferiorExecuting;

  case eStateSuspended:
  case eStateCrashed:
  case eStateStopped:
    // If we stop due to a signal, so clear the fact that we got a SIGINT
    // so we can stop ourselves again (but only while our inferior
    // process is running..)
    g_sigint_received = 0;
    if (initialize == false) {
      // Compare the last stop count to our current notion of a stop count
      // to make sure we don't notify more than once for a given stop.
      nub_size_t prev_pid_stop_count = ctx.GetProcessStopCount();
      bool pid_stop_count_changed =
          ctx.SetProcessStopCount(DNBProcessGetStopCount(pid));
      if (pid_stop_count_changed) {
        remote->FlushSTDIO();

        if (ctx.GetProcessStopCount() == 1) {
          DNBLogThreadedIf(
              LOG_RNB_MINIMAL, "%s (&remote, initialize=%i)  pid_state = %s "
                               "pid_stop_count %llu (old %llu)) Notify??? no, "
                               "first stop...",
              __FUNCTION__, (int)initialize, DNBStateAsString(pid_state),
              (uint64_t)ctx.GetProcessStopCount(),
              (uint64_t)prev_pid_stop_count);
        } else {

          DNBLogThreadedIf(LOG_RNB_MINIMAL, "%s (&remote, initialize=%i)  "
                                            "pid_state = %s pid_stop_count "
                                            "%llu (old %llu)) Notify??? YES!!!",
                           __FUNCTION__, (int)initialize,
                           DNBStateAsString(pid_state),
                           (uint64_t)ctx.GetProcessStopCount(),
                           (uint64_t)prev_pid_stop_count);
          remote->NotifyThatProcessStopped();
        }
      } else {
        DNBLogThreadedIf(
            LOG_RNB_MINIMAL, "%s (&remote, initialize=%i)  pid_state = %s "
                             "pid_stop_count %llu (old %llu)) Notify??? "
                             "skipping...",
            __FUNCTION__, (int)initialize, DNBStateAsString(pid_state),
            (uint64_t)ctx.GetProcessStopCount(), (uint64_t)prev_pid_stop_count);
      }
    }
    return eRNBRunLoopModeInferiorExecuting;

  case eStateStepping:
  case eStateRunning:
    return eRNBRunLoopModeInferiorExecuting;

  case eStateExited:
    remote->HandlePacket_last_signal(NULL);
  case eStateDetached:
    return eRNBRunLoopModeExit;
  }

  // Catch all...
  return eRNBRunLoopModeExit;
}
// This function handles the case where our inferior program is stopped and
// we are waiting for gdb remote protocol packets. When a packet occurs that
// makes the inferior run, we need to leave this function with a new state
// as the return code.
RNBRunLoopMode RNBRunLoopInferiorExecuting(RNBRemote *remote) {
  DNBLogThreadedIf(LOG_RNB_MINIMAL, "#### %s", __FUNCTION__);
  RNBContext &ctx = remote->Context();

  // Init our mode and set 'is_running' based on the current process state
  RNBRunLoopMode mode = HandleProcessStateChange(remote, true);

  while (ctx.ProcessID() != INVALID_NUB_PROCESS) {

    std::string set_events_str;
    uint32_t event_mask = ctx.NormalEventBits();

    if (!ctx.ProcessStateRunning()) {
      // Clear some bits if we are not running so we don't send any async
      // packets
      event_mask &= ~RNBContext::event_proc_stdio_available;
      event_mask &= ~RNBContext::event_proc_profile_data;
      // When we enable async structured data packets over another logical
      // channel,
      // this can be relaxed.
      event_mask &= ~RNBContext::event_darwin_log_data_available;
    }

    // We want to make sure we consume all process state changes and have
    // whomever is notifying us to wait for us to reset the event bit before
    // continuing.
    // ctx.Events().SetResetAckMask (RNBContext::event_proc_state_changed);

    DNBLogThreadedIf(LOG_RNB_EVENTS,
                     "%s ctx.Events().WaitForSetEvents(0x%08x) ...",
                     __FUNCTION__, event_mask);
    nub_event_t set_events = ctx.Events().WaitForSetEvents(event_mask);
    DNBLogThreadedIf(LOG_RNB_EVENTS,
                     "%s ctx.Events().WaitForSetEvents(0x%08x) => 0x%08x (%s)",
                     __FUNCTION__, event_mask, set_events,
                     ctx.EventsAsString(set_events, set_events_str));

    if (set_events) {
      if ((set_events & RNBContext::event_proc_thread_exiting) ||
          (set_events & RNBContext::event_proc_stdio_available)) {
        remote->FlushSTDIO();
      }

      if (set_events & RNBContext::event_proc_profile_data) {
        remote->SendAsyncProfileData();
      }

      if (set_events & RNBContext::event_darwin_log_data_available) {
        remote->SendAsyncDarwinLogData();
      }

      if (set_events & RNBContext::event_read_packet_available) {
        // handleReceivedPacket will take care of resetting the
        // event_read_packet_available events when there are no more...
        set_events ^= RNBContext::event_read_packet_available;

        if (ctx.ProcessStateRunning()) {
          if (remote->HandleAsyncPacket() == rnb_not_connected) {
            // TODO: connect again? Exit?
          }
        } else {
          if (remote->HandleReceivedPacket() == rnb_not_connected) {
            // TODO: connect again? Exit?
          }
        }
      }

      if (set_events & RNBContext::event_proc_state_changed) {
        mode = HandleProcessStateChange(remote, false);
        ctx.Events().ResetEvents(RNBContext::event_proc_state_changed);
        set_events ^= RNBContext::event_proc_state_changed;
      }

      if (set_events & RNBContext::event_proc_thread_exiting) {
        mode = eRNBRunLoopModeExit;
      }

      if (set_events & RNBContext::event_read_thread_exiting) {
        // Out remote packet receiving thread exited, exit for now.
        if (ctx.HasValidProcessID()) {
          // TODO: We should add code that will leave the current process
          // in its current state and listen for another connection...
          if (ctx.ProcessStateRunning()) {
            if (ctx.GetDetachOnError()) {
              DNBLog("debugserver's event read thread is exiting, detaching "
                     "from the inferior process.");
              DNBProcessDetach(ctx.ProcessID());
            } else {
              DNBLog("debugserver's event read thread is exiting, killing the "
                     "inferior process.");
              DNBProcessKill(ctx.ProcessID());
            }
          } else {
            if (ctx.GetDetachOnError()) {
              DNBLog("debugserver's event read thread is exiting, detaching "
                     "from the inferior process.");
              DNBProcessDetach(ctx.ProcessID());
            }
          }
        }
        mode = eRNBRunLoopModeExit;
      }
    }

    // Reset all event bits that weren't reset for now...
    if (set_events != 0)
      ctx.Events().ResetEvents(set_events);

    if (mode != eRNBRunLoopModeInferiorExecuting)
      break;
  }

  return mode;
}

RNBRunLoopMode RNBRunLoopPlatform(RNBRemote *remote) {
  RNBRunLoopMode mode = eRNBRunLoopModePlatformMode;
  RNBContext &ctx = remote->Context();

  while (mode == eRNBRunLoopModePlatformMode) {
    std::string set_events_str;
    const uint32_t event_mask = RNBContext::event_read_packet_available |
                                RNBContext::event_read_thread_exiting;

    DNBLogThreadedIf(LOG_RNB_EVENTS,
                     "%s ctx.Events().WaitForSetEvents(0x%08x) ...",
                     __FUNCTION__, event_mask);
    nub_event_t set_events = ctx.Events().WaitForSetEvents(event_mask);
    DNBLogThreadedIf(LOG_RNB_EVENTS,
                     "%s ctx.Events().WaitForSetEvents(0x%08x) => 0x%08x (%s)",
                     __FUNCTION__, event_mask, set_events,
                     ctx.EventsAsString(set_events, set_events_str));

    if (set_events) {
      if (set_events & RNBContext::event_read_packet_available) {
        if (remote->HandleReceivedPacket() == rnb_not_connected)
          mode = eRNBRunLoopModeExit;
      }

      if (set_events & RNBContext::event_read_thread_exiting) {
        mode = eRNBRunLoopModeExit;
      }
      ctx.Events().ResetEvents(set_events);
    }
  }
  return eRNBRunLoopModeExit;
}

//----------------------------------------------------------------------
// Convenience function to set up the remote listening port
// Returns 1 for success 0 for failure.
//----------------------------------------------------------------------

static void PortWasBoundCallbackUnixSocket(const void *baton, in_port_t port) {
  //::printf ("PortWasBoundCallbackUnixSocket (baton = %p, port = %u)\n", baton,
  //port);

  const char *unix_socket_name = (const char *)baton;

  if (unix_socket_name && unix_socket_name[0]) {
    // We were given a unix socket name to use to communicate the port
    // that we ended up binding to back to our parent process
    struct sockaddr_un saddr_un;
    int s = ::socket(AF_UNIX, SOCK_STREAM, 0);
    if (s < 0) {
      perror("error: socket (AF_UNIX, SOCK_STREAM, 0)");
      exit(1);
    }

    saddr_un.sun_family = AF_UNIX;
    ::strlcpy(saddr_un.sun_path, unix_socket_name,
              sizeof(saddr_un.sun_path) - 1);
    saddr_un.sun_path[sizeof(saddr_un.sun_path) - 1] = '\0';
    saddr_un.sun_len = SUN_LEN(&saddr_un);

    if (::connect(s, (struct sockaddr *)&saddr_un,
                  static_cast<socklen_t>(SUN_LEN(&saddr_un))) < 0) {
      perror("error: connect (socket, &saddr_un, saddr_un_len)");
      exit(1);
    }

    //::printf ("connect () sucess!!\n");

    // We were able to connect to the socket, now write our PID so whomever
    // launched us will know this process's ID
    RNBLogSTDOUT("Listening to port %i...\n", port);

    char pid_str[64];
    const int pid_str_len = ::snprintf(pid_str, sizeof(pid_str), "%u", port);
    const ssize_t bytes_sent = ::send(s, pid_str, pid_str_len, 0);

    if (pid_str_len != bytes_sent) {
      perror("error: send (s, pid_str, pid_str_len, 0)");
      exit(1);
    }

    //::printf ("send () sucess!!\n");

    // We are done with the socket
    close(s);
  }
}

static void PortWasBoundCallbackNamedPipe(const void *baton, uint16_t port) {
  const char *named_pipe = (const char *)baton;
  if (named_pipe && named_pipe[0]) {
    int fd = ::open(named_pipe, O_WRONLY);
    if (fd > -1) {
      char port_str[64];
      const ssize_t port_str_len =
          ::snprintf(port_str, sizeof(port_str), "%u", port);
      // Write the port number as a C string with the NULL terminator
      ::write(fd, port_str, port_str_len + 1);
      close(fd);
    }
  }
}

static int ConnectRemote(RNBRemote *remote, const char *host, int port,
                         bool reverse_connect, const char *named_pipe_path,
                         const char *unix_socket_name) {
  if (!remote->Comm().IsConnected()) {
    if (reverse_connect) {
      if (port == 0) {
        DNBLogThreaded(
            "error: invalid port supplied for reverse connection: %i.\n", port);
        return 0;
      }
      if (remote->Comm().Connect(host, port) != rnb_success) {
        DNBLogThreaded("Failed to reverse connect to %s:%i.\n", host, port);
        return 0;
      }
    } else {
      if (port != 0)
        RNBLogSTDOUT("Listening to port %i for a connection from %s...\n", port,
                     host ? host : "127.0.0.1");
      if (unix_socket_name && unix_socket_name[0]) {
        if (remote->Comm().Listen(host, port, PortWasBoundCallbackUnixSocket,
                                  unix_socket_name) != rnb_success) {
          RNBLogSTDERR("Failed to get connection from a remote gdb process.\n");
          return 0;
        }
      } else {
        if (remote->Comm().Listen(host, port, PortWasBoundCallbackNamedPipe,
                                  named_pipe_path) != rnb_success) {
          RNBLogSTDERR("Failed to get connection from a remote gdb process.\n");
          return 0;
        }
      }
    }
    remote->StartReadRemoteDataThread();
  }
  return 1;
}

//----------------------------------------------------------------------
// ASL Logging callback that can be registered with DNBLogSetLogCallback
//----------------------------------------------------------------------
void ASLLogCallback(void *baton, uint32_t flags, const char *format,
                    va_list args) {
  if (format == NULL)
    return;
  static aslmsg g_aslmsg = NULL;
  if (g_aslmsg == NULL) {
    g_aslmsg = ::asl_new(ASL_TYPE_MSG);
    char asl_key_sender[PATH_MAX];
    snprintf(asl_key_sender, sizeof(asl_key_sender), "com.apple.%s-%s",
             DEBUGSERVER_PROGRAM_NAME, DEBUGSERVER_VERSION_STR);
    ::asl_set(g_aslmsg, ASL_KEY_SENDER, asl_key_sender);
  }

  int asl_level;
  if (flags & DNBLOG_FLAG_FATAL)
    asl_level = ASL_LEVEL_CRIT;
  else if (flags & DNBLOG_FLAG_ERROR)
    asl_level = ASL_LEVEL_ERR;
  else if (flags & DNBLOG_FLAG_WARNING)
    asl_level = ASL_LEVEL_WARNING;
  else if (flags & DNBLOG_FLAG_VERBOSE)
    asl_level = ASL_LEVEL_WARNING; // ASL_LEVEL_INFO;
  else
    asl_level = ASL_LEVEL_WARNING; // ASL_LEVEL_DEBUG;

  ::asl_vlog(NULL, g_aslmsg, asl_level, format, args);
}

//----------------------------------------------------------------------
// FILE based Logging callback that can be registered with
// DNBLogSetLogCallback
//----------------------------------------------------------------------
void FileLogCallback(void *baton, uint32_t flags, const char *format,
                     va_list args) {
  if (baton == NULL || format == NULL)
    return;

  ::vfprintf((FILE *)baton, format, args);
  ::fprintf((FILE *)baton, "\n");
  ::fflush((FILE *)baton);
}

void show_usage_and_exit(int exit_code) {
  RNBLogSTDERR(
      "Usage:\n  %s host:port [program-name program-arg1 program-arg2 ...]\n",
      DEBUGSERVER_PROGRAM_NAME);
  RNBLogSTDERR("  %s /path/file [program-name program-arg1 program-arg2 ...]\n",
               DEBUGSERVER_PROGRAM_NAME);
  RNBLogSTDERR("  %s host:port --attach=<pid>\n", DEBUGSERVER_PROGRAM_NAME);
  RNBLogSTDERR("  %s /path/file --attach=<pid>\n", DEBUGSERVER_PROGRAM_NAME);
  RNBLogSTDERR("  %s host:port --attach=<process_name>\n",
               DEBUGSERVER_PROGRAM_NAME);
  RNBLogSTDERR("  %s /path/file --attach=<process_name>\n",
               DEBUGSERVER_PROGRAM_NAME);
  exit(exit_code);
}

//----------------------------------------------------------------------
// option descriptors for getopt_long_only()
//----------------------------------------------------------------------
static struct option g_long_options[] = {
    {"attach", required_argument, NULL, 'a'},
    {"arch", required_argument, NULL, 'A'},
    {"debug", no_argument, NULL, 'g'},
    {"kill-on-error", no_argument, NULL, 'K'},
    {"verbose", no_argument, NULL, 'v'},
    {"lockdown", no_argument, &g_lockdown_opt, 1}, // short option "-k"
    {"applist", no_argument, &g_applist_opt, 1},   // short option "-t"
    {"log-file", required_argument, NULL, 'l'},
    {"log-flags", required_argument, NULL, 'f'},
    {"launch", required_argument, NULL, 'x'}, // Valid values are "auto",
                                              // "posix-spawn", "fork-exec",
                                              // "springboard" (arm only)
    {"waitfor", required_argument, NULL,
     'w'}, // Wait for a process whose name starts with ARG
    {"waitfor-interval", required_argument, NULL,
     'i'}, // Time in usecs to wait between sampling the pid list when waiting
           // for a process by name
    {"waitfor-duration", required_argument, NULL,
     'd'}, // The time in seconds to wait for a process to show up by name
    {"native-regs", no_argument, NULL, 'r'}, // Specify to use the native
                                             // registers instead of the gdb
                                             // defaults for the architecture.
    {"stdio-path", required_argument, NULL,
     's'}, // Set the STDIO path to be used when launching applications (STDIN,
           // STDOUT and STDERR) (only if debugserver launches the process)
    {"stdin-path", required_argument, NULL,
     'I'}, // Set the STDIN path to be used when launching applications (only if
           // debugserver launches the process)
    {"stdout-path", required_argument, NULL,
     'O'}, // Set the STDOUT path to be used when launching applications (only
           // if debugserver launches the process)
    {"stderr-path", required_argument, NULL,
     'E'}, // Set the STDERR path to be used when launching applications (only
           // if debugserver launches the process)
    {"no-stdio", no_argument, NULL,
     'n'}, // Do not set up any stdio (perhaps the program is a GUI program)
           // (only if debugserver launches the process)
    {"setsid", no_argument, NULL,
     'S'}, // call setsid() to make debugserver run in its own session
    {"disable-aslr", no_argument, NULL, 'D'}, // Use _POSIX_SPAWN_DISABLE_ASLR
                                              // to avoid shared library
                                              // randomization
    {"working-dir", required_argument, NULL,
     'W'}, // The working directory that the inferior process should have (only
           // if debugserver launches the process)
    {"platform", required_argument, NULL,
     'p'}, // Put this executable into a remote platform mode
    {"unix-socket", required_argument, NULL,
     'u'}, // If we need to handshake with our parent process, an option will be
           // passed down that specifies a unix socket name to use
    {"fd", required_argument, NULL,
     '2'}, // A file descriptor was passed to this process when spawned that
           // is already open and ready for communication
    {"named-pipe", required_argument, NULL, 'P'},
    {"reverse-connect", no_argument, NULL, 'R'},
    {"env", required_argument, NULL,
     'e'}, // When debugserver launches the process, set a single environment
           // entry as specified by the option value ("./debugserver -e FOO=1 -e
           // BAR=2 localhost:1234 -- /bin/ls")
    {"forward-env", no_argument, NULL,
     'F'}, // When debugserver launches the process, forward debugserver's
           // current environment variables to the child process ("./debugserver
           // -F localhost:1234 -- /bin/ls"
    {NULL, 0, NULL, 0}};

//----------------------------------------------------------------------
// main
//----------------------------------------------------------------------
int main(int argc, char *argv[]) {
  // If debugserver is launched with DYLD_INSERT_LIBRARIES, unset it so we
  // don't spawn child processes with this enabled.
  unsetenv("DYLD_INSERT_LIBRARIES");

  const char *argv_sub_zero =
      argv[0]; // save a copy of argv[0] for error reporting post-launch

#if defined(__APPLE__)
  pthread_setname_np("main thread");
#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
  struct sched_param thread_param;
  int thread_sched_policy;
  if (pthread_getschedparam(pthread_self(), &thread_sched_policy,
                            &thread_param) == 0) {
    thread_param.sched_priority = 47;
    pthread_setschedparam(pthread_self(), thread_sched_policy, &thread_param);
  }

  ::proc_set_wakemon_params(
      getpid(), 500,
      0); // Allow up to 500 wakeups/sec to avoid EXC_RESOURCE for normal use.
#endif
#endif

  g_isatty = ::isatty(STDIN_FILENO);

  //  ::printf ("uid=%u euid=%u gid=%u egid=%u\n",
  //            getuid(),
  //            geteuid(),
  //            getgid(),
  //            getegid());

  //    signal (SIGINT, signal_handler);
  signal(SIGPIPE, signal_handler);
  signal(SIGHUP, signal_handler);

  // We're always sitting in waitpid or kevent waiting on our target process'
  // death,
  // we don't need no stinking SIGCHLD's...

  sigset_t sigset;
  sigemptyset(&sigset);
  sigaddset(&sigset, SIGCHLD);
  sigprocmask(SIG_BLOCK, &sigset, NULL);

  g_remoteSP.reset(new RNBRemote());

  RNBRemote *remote = g_remoteSP.get();
  if (remote == NULL) {
    RNBLogSTDERR("error: failed to create a remote connection class\n");
    return -1;
  }

  RNBContext &ctx = remote->Context();

  int i;
  int attach_pid = INVALID_NUB_PROCESS;

  FILE *log_file = NULL;
  uint32_t log_flags = 0;
  // Parse our options
  int ch;
  int long_option_index = 0;
  int debug = 0;
  int communication_fd = -1;
  std::string compile_options;
  std::string waitfor_pid_name; // Wait for a process that starts with this name
  std::string attach_pid_name;
  std::string arch_name;
  std::string working_dir; // The new working directory to use for the inferior
  std::string unix_socket_name; // If we need to handshake with our parent
                                // process, an option will be passed down that
                                // specifies a unix socket name to use
  std::string named_pipe_path;  // If we need to handshake with our parent
                                // process, an option will be passed down that
                                // specifies a named pipe to use
  useconds_t waitfor_interval = 1000; // Time in usecs between process lists
                                      // polls when waiting for a process by
                                      // name, default 1 msec.
  useconds_t waitfor_duration =
      0; // Time in seconds to wait for a process by name, 0 means wait forever.
  bool no_stdio = false;
  bool reverse_connect = false; // Set to true by an option to indicate we
                                // should reverse connect to the host:port
                                // supplied as the first debugserver argument

#if !defined(DNBLOG_ENABLED)
  compile_options += "(no-logging) ";
#endif

  RNBRunLoopMode start_mode = eRNBRunLoopModeExit;

  char short_options[512];
  uint32_t short_options_idx = 0;

  // Handle the two case that don't have short options in g_long_options
  short_options[short_options_idx++] = 'k';
  short_options[short_options_idx++] = 't';

  for (i = 0; g_long_options[i].name != NULL; ++i) {
    if (isalpha(g_long_options[i].val)) {
      short_options[short_options_idx++] = g_long_options[i].val;
      switch (g_long_options[i].has_arg) {
      default:
      case no_argument:
        break;

      case optional_argument:
        short_options[short_options_idx++] = ':';
      // Fall through to required_argument case below...
      case required_argument:
        short_options[short_options_idx++] = ':';
        break;
      }
    }
  }
  // NULL terminate the short option string.
  short_options[short_options_idx++] = '\0';

#if __GLIBC__
  optind = 0;
#else
  optreset = 1;
  optind = 1;
#endif

  bool forward_env = false;
  while ((ch = getopt_long_only(argc, argv, short_options, g_long_options,
                                &long_option_index)) != -1) {
    DNBLogDebug("option: ch == %c (0x%2.2x) --%s%c%s\n", ch, (uint8_t)ch,
                g_long_options[long_option_index].name,
                g_long_options[long_option_index].has_arg ? '=' : ' ',
                optarg ? optarg : "");
    switch (ch) {
    case 0: // Any optional that auto set themselves will return 0
      break;

    case 'A':
      if (optarg && optarg[0])
        arch_name.assign(optarg);
      break;

    case 'a':
      if (optarg && optarg[0]) {
        if (isdigit(optarg[0])) {
          char *end = NULL;
          attach_pid = static_cast<int>(strtoul(optarg, &end, 0));
          if (end == NULL || *end != '\0') {
            RNBLogSTDERR("error: invalid pid option '%s'\n", optarg);
            exit(4);
          }
        } else {
          attach_pid_name = optarg;
        }
        start_mode = eRNBRunLoopModeInferiorAttaching;
      }
      break;

    // --waitfor=NAME
    case 'w':
      if (optarg && optarg[0]) {
        waitfor_pid_name = optarg;
        start_mode = eRNBRunLoopModeInferiorAttaching;
      }
      break;

    // --waitfor-interval=USEC
    case 'i':
      if (optarg && optarg[0]) {
        char *end = NULL;
        waitfor_interval = static_cast<useconds_t>(strtoul(optarg, &end, 0));
        if (end == NULL || *end != '\0') {
          RNBLogSTDERR("error: invalid waitfor-interval option value '%s'.\n",
                       optarg);
          exit(6);
        }
      }
      break;

    // --waitfor-duration=SEC
    case 'd':
      if (optarg && optarg[0]) {
        char *end = NULL;
        waitfor_duration = static_cast<useconds_t>(strtoul(optarg, &end, 0));
        if (end == NULL || *end != '\0') {
          RNBLogSTDERR("error: invalid waitfor-duration option value '%s'.\n",
                       optarg);
          exit(7);
        }
      }
      break;

    case 'K':
      g_detach_on_error = false;
      break;
    case 'W':
      if (optarg && optarg[0])
        working_dir.assign(optarg);
      break;

    case 'x':
      if (optarg && optarg[0]) {
        if (strcasecmp(optarg, "auto") == 0)
          g_launch_flavor = eLaunchFlavorDefault;
        else if (strcasestr(optarg, "posix") == optarg)
          g_launch_flavor = eLaunchFlavorPosixSpawn;
        else if (strcasestr(optarg, "fork") == optarg)
          g_launch_flavor = eLaunchFlavorForkExec;
#ifdef WITH_SPRINGBOARD
        else if (strcasestr(optarg, "spring") == optarg)
          g_launch_flavor = eLaunchFlavorSpringBoard;
#endif
#ifdef WITH_BKS
        else if (strcasestr(optarg, "backboard") == optarg)
          g_launch_flavor = eLaunchFlavorBKS;
#endif
#ifdef WITH_FBS
        else if (strcasestr(optarg, "frontboard") == optarg)
          g_launch_flavor = eLaunchFlavorFBS;
#endif

        else {
          RNBLogSTDERR("error: invalid TYPE for the --launch=TYPE (-x TYPE) "
                       "option: '%s'\n",
                       optarg);
          RNBLogSTDERR("Valid values TYPE are:\n");
          RNBLogSTDERR(
              "  auto       Auto-detect the best launch method to use.\n");
          RNBLogSTDERR(
              "  posix      Launch the executable using posix_spawn.\n");
          RNBLogSTDERR(
              "  fork       Launch the executable using fork and exec.\n");
#ifdef WITH_SPRINGBOARD
          RNBLogSTDERR(
              "  spring     Launch the executable through Springboard.\n");
#endif
#ifdef WITH_BKS
          RNBLogSTDERR("  backboard  Launch the executable through BackBoard "
                       "Services.\n");
#endif
#ifdef WITH_FBS
          RNBLogSTDERR("  frontboard  Launch the executable through FrontBoard "
                       "Services.\n");
#endif
          exit(5);
        }
      }
      break;

    case 'l': // Set Log File
      if (optarg && optarg[0]) {
        if (strcasecmp(optarg, "stdout") == 0)
          log_file = stdout;
        else if (strcasecmp(optarg, "stderr") == 0)
          log_file = stderr;
        else {
          log_file = fopen(optarg, "w");
          if (log_file != NULL)
            setlinebuf(log_file);
        }

        if (log_file == NULL) {
          const char *errno_str = strerror(errno);
          RNBLogSTDERR(
              "Failed to open log file '%s' for writing: errno = %i (%s)",
              optarg, errno, errno_str ? errno_str : "unknown error");
        }
      }
      break;

    case 'f': // Log Flags
      if (optarg && optarg[0])
        log_flags = static_cast<uint32_t>(strtoul(optarg, NULL, 0));
      break;

    case 'g':
      debug = 1;
      DNBLogSetDebug(debug);
      break;

    case 't':
      g_applist_opt = 1;
      break;

    case 'k':
      g_lockdown_opt = 1;
      break;

    case 'r':
      // Do nothing, native regs is the default these days
      break;

    case 'R':
      reverse_connect = true;
      break;
    case 'v':
      DNBLogSetVerbose(1);
      break;

    case 's':
      ctx.GetSTDIN().assign(optarg);
      ctx.GetSTDOUT().assign(optarg);
      ctx.GetSTDERR().assign(optarg);
      break;

    case 'I':
      ctx.GetSTDIN().assign(optarg);
      break;

    case 'O':
      ctx.GetSTDOUT().assign(optarg);
      break;

    case 'E':
      ctx.GetSTDERR().assign(optarg);
      break;

    case 'n':
      no_stdio = true;
      break;

    case 'S':
      // Put debugserver into a new session. Terminals group processes
      // into sessions and when a special terminal key sequences
      // (like control+c) are typed they can cause signals to go out to
      // all processes in a session. Using this --setsid (-S) option
      // will cause debugserver to run in its own sessions and be free
      // from such issues.
      //
      // This is useful when debugserver is spawned from a command
      // line application that uses debugserver to do the debugging,
      // yet that application doesn't want debugserver receiving the
      // signals sent to the session (i.e. dying when anyone hits ^C).
      setsid();
      break;
    case 'D':
      g_disable_aslr = 1;
      break;

    case 'p':
      start_mode = eRNBRunLoopModePlatformMode;
      break;

    case 'u':
      unix_socket_name.assign(optarg);
      break;

    case 'P':
      named_pipe_path.assign(optarg);
      break;

    case 'e':
      // Pass a single specified environment variable down to the process that
      // gets launched
      remote->Context().PushEnvironment(optarg);
      break;

    case 'F':
      forward_env = true;
      break;

    case '2':
      // File descriptor passed to this process during fork/exec and is already
      // open and ready for communication.
      communication_fd = atoi(optarg);
      break;
    }
  }

  if (arch_name.empty()) {
#if defined(__arm__)
    arch_name.assign("arm");
#endif
  } else {
    DNBSetArchitecture(arch_name.c_str());
  }

  //    if (arch_name.empty())
  //    {
  //        fprintf(stderr, "error: no architecture was specified\n");
  //        exit (8);
  //    }
  // Skip any options we consumed with getopt_long_only
  argc -= optind;
  argv += optind;

  if (!working_dir.empty()) {
    if (remote->Context().SetWorkingDirectory(working_dir.c_str()) == false) {
      RNBLogSTDERR("error: working directory doesn't exist '%s'.\n",
                   working_dir.c_str());
      exit(8);
    }
  }

  remote->Context().SetDetachOnError(g_detach_on_error);

  remote->Initialize();

  // It is ok for us to set NULL as the logfile (this will disable any logging)

  if (log_file != NULL) {
    DNBLogSetLogCallback(FileLogCallback, log_file);
    // If our log file was set, yet we have no log flags, log everything!
    if (log_flags == 0)
      log_flags = LOG_ALL | LOG_RNB_ALL;

    DNBLogSetLogMask(log_flags);
  } else {
    // Enable DNB logging

    // if os_log() support is available, log through that.
    auto log_callback = OsLogger::GetLogFunction();
    if (log_callback) {
      DNBLogSetLogCallback(log_callback, nullptr);
      DNBLog("debugserver will use os_log for internal logging.");
    } else {
      // Fall back to ASL support.
      DNBLogSetLogCallback(ASLLogCallback, NULL);
      DNBLog("debugserver will use ASL for internal logging.");
    }
    DNBLogSetLogMask(log_flags);
  }

  if (DNBLogEnabled()) {
    for (i = 0; i < argc; i++)
      DNBLogDebug("argv[%i] = %s", i, argv[i]);
  }

  // as long as we're dropping remotenub in as a replacement for gdbserver,
  // explicitly note that this is not gdbserver.

  RNBLogSTDOUT("%s-%s %sfor %s.\n", DEBUGSERVER_PROGRAM_NAME,
               DEBUGSERVER_VERSION_STR, compile_options.c_str(), RNB_ARCH);

  std::string host;
  int port = INT32_MAX;
  char str[PATH_MAX];
  str[0] = '\0';

  if (g_lockdown_opt == 0 && g_applist_opt == 0 && communication_fd == -1) {
    // Make sure we at least have port
    if (argc < 1) {
      show_usage_and_exit(1);
    }
    // accept 'localhost:' prefix on port number
    std::string host_specifier = argv[0];
    auto colon_location = host_specifier.rfind(':');
    if (colon_location != std::string::npos) {
      host = host_specifier.substr(0, colon_location);
      std::string port_str =
          host_specifier.substr(colon_location + 1, std::string::npos);
      char *end_ptr;
      port = strtoul(port_str.c_str(), &end_ptr, 0);
      if (end_ptr < port_str.c_str() + port_str.size())
        show_usage_and_exit(2);
      if (host.front() == '[' && host.back() == ']')
        host = host.substr(1, host.size() - 2);
      DNBLogDebug("host = '%s'  port = %i", host.c_str(), port);
    } else {
      // No hostname means "localhost"
      int items_scanned = ::sscanf(argv[0], "%i", &port);
      if (items_scanned == 1) {
        host = "127.0.0.1";
        DNBLogDebug("host = '%s'  port = %i", host.c_str(), port);
      } else if (argv[0][0] == '/') {
        port = INT32_MAX;
        strlcpy(str, argv[0], sizeof(str));
      } else {
        show_usage_and_exit(2);
      }
    }

    // We just used the 'host:port' or the '/path/file' arg...
    argc--;
    argv++;
  }

  //  If we know we're waiting to attach, we don't need any of this other info.
  if (start_mode != eRNBRunLoopModeInferiorAttaching &&
      start_mode != eRNBRunLoopModePlatformMode) {
    if (argc == 0 || g_lockdown_opt) {
      if (g_lockdown_opt != 0) {
        // Work around for SIGPIPE crashes due to posix_spawn issue.
        // We have to close STDOUT and STDERR, else the first time we
        // try and do any, we get SIGPIPE and die as posix_spawn is
        // doing bad things with our file descriptors at the moment.
        int null = open("/dev/null", O_RDWR);
        dup2(null, STDOUT_FILENO);
        dup2(null, STDERR_FILENO);
      } else if (g_applist_opt != 0) {
        // List all applications we are able to see
        std::string applist_plist;
        int err = ListApplications(applist_plist, false, false);
        if (err == 0) {
          fputs(applist_plist.c_str(), stdout);
        } else {
          RNBLogSTDERR("error: ListApplications returned error %i\n", err);
        }
        // Exit with appropriate error if we were asked to list the applications
        // with no other args were given (and we weren't trying to do this over
        // lockdown)
        return err;
      }

      DNBLogDebug("Get args from remote protocol...");
      start_mode = eRNBRunLoopModeGetStartModeFromRemoteProtocol;
    } else {
      start_mode = eRNBRunLoopModeInferiorLaunching;
      // Fill in the argv array in the context from the rest of our args.
      // Skip the name of this executable and the port number
      for (int i = 0; i < argc; i++) {
        DNBLogDebug("inferior_argv[%i] = '%s'", i, argv[i]);
        ctx.PushArgument(argv[i]);
      }
    }
  }

  if (start_mode == eRNBRunLoopModeExit)
    return -1;

  if (forward_env || start_mode == eRNBRunLoopModeInferiorLaunching) {
    // Pass the current environment down to the process that gets launched
    // This happens automatically in the "launching" mode. For the rest, we
    // only do that if the user explicitly requested this via --forward-env
    // argument.
    char **host_env = *_NSGetEnviron();
    char *env_entry;
    size_t i;
    for (i = 0; (env_entry = host_env[i]) != NULL; ++i)
      remote->Context().PushEnvironmentIfNeeded(env_entry);
  }

  RNBRunLoopMode mode = start_mode;
  char err_str[1024] = {'\0'};

  while (mode != eRNBRunLoopModeExit) {
    switch (mode) {
    case eRNBRunLoopModeGetStartModeFromRemoteProtocol:
#ifdef WITH_LOCKDOWN
      if (g_lockdown_opt) {
        if (!remote->Comm().IsConnected()) {
          if (remote->Comm().ConnectToService() != rnb_success) {
            RNBLogSTDERR(
                "Failed to get connection from a remote gdb process.\n");
            mode = eRNBRunLoopModeExit;
          } else if (g_applist_opt != 0) {
            // List all applications we are able to see
            std::string applist_plist;
            if (ListApplications(applist_plist, false, false) == 0) {
              DNBLogDebug("Task list: %s", applist_plist.c_str());

              remote->Comm().Write(applist_plist.c_str(), applist_plist.size());
              // Issue a read that will never yield any data until the other
              // side
              // closes the socket so this process doesn't just exit and cause
              // the
              // socket to close prematurely on the other end and cause data
              // loss.
              std::string buf;
              remote->Comm().Read(buf);
            }
            remote->Comm().Disconnect(false);
            mode = eRNBRunLoopModeExit;
            break;
          } else {
            // Start watching for remote packets
            remote->StartReadRemoteDataThread();
          }
        }
      } else
#endif
          if (port != INT32_MAX) {
        if (!ConnectRemote(remote, host.c_str(), port, reverse_connect,
                           named_pipe_path.c_str(), unix_socket_name.c_str()))
          mode = eRNBRunLoopModeExit;
      } else if (str[0] == '/') {
        if (remote->Comm().OpenFile(str))
          mode = eRNBRunLoopModeExit;
      } else if (communication_fd >= 0) {
        // We were passed a file descriptor to use during fork/exec that is
        // already open
        // in our process, so lets just use it!
        if (remote->Comm().useFD(communication_fd))
          mode = eRNBRunLoopModeExit;
        else
          remote->StartReadRemoteDataThread();
      }

      if (mode != eRNBRunLoopModeExit) {
        RNBLogSTDOUT("Got a connection, waiting for process information for "
                     "launching or attaching.\n");

        mode = RNBRunLoopGetStartModeFromRemote(remote);
      }
      break;

    case eRNBRunLoopModeInferiorAttaching:
      if (!waitfor_pid_name.empty()) {
        // Set our end wait time if we are using a waitfor-duration
        // option that may have been specified
        struct timespec attach_timeout_abstime, *timeout_ptr = NULL;
        if (waitfor_duration != 0) {
          DNBTimer::OffsetTimeOfDay(&attach_timeout_abstime, waitfor_duration,
                                    0);
          timeout_ptr = &attach_timeout_abstime;
        }
        nub_launch_flavor_t launch_flavor = g_launch_flavor;
        if (launch_flavor == eLaunchFlavorDefault) {
          // Our default launch method is posix spawn
          launch_flavor = eLaunchFlavorPosixSpawn;

#if defined WITH_FBS
          // Check if we have an app bundle, if so launch using SpringBoard.
          if (waitfor_pid_name.find(".app") != std::string::npos) {
            launch_flavor = eLaunchFlavorFBS;
          }
#elif defined WITH_BKS
          // Check if we have an app bundle, if so launch using SpringBoard.
          if (waitfor_pid_name.find(".app") != std::string::npos) {
            launch_flavor = eLaunchFlavorBKS;
          }
#elif defined WITH_SPRINGBOARD
          // Check if we have an app bundle, if so launch using SpringBoard.
          if (waitfor_pid_name.find(".app") != std::string::npos) {
            launch_flavor = eLaunchFlavorSpringBoard;
          }
#endif
        }

        ctx.SetLaunchFlavor(launch_flavor);
        bool ignore_existing = false;
        RNBLogSTDOUT("Waiting to attach to process %s...\n",
                     waitfor_pid_name.c_str());
        nub_process_t pid = DNBProcessAttachWait(
            waitfor_pid_name.c_str(), launch_flavor, ignore_existing,
            timeout_ptr, waitfor_interval, err_str, sizeof(err_str));
        g_pid = pid;

        if (pid == INVALID_NUB_PROCESS) {
          ctx.LaunchStatus().SetError(-1, DNBError::Generic);
          if (err_str[0])
            ctx.LaunchStatus().SetErrorString(err_str);
          RNBLogSTDERR("error: failed to attach to process named: \"%s\" %s\n",
                       waitfor_pid_name.c_str(), err_str);
          mode = eRNBRunLoopModeExit;
        } else {
          ctx.SetProcessID(pid);
          mode = eRNBRunLoopModeInferiorExecuting;
        }
      } else if (attach_pid != INVALID_NUB_PROCESS) {

        RNBLogSTDOUT("Attaching to process %i...\n", attach_pid);
        nub_process_t attached_pid;
        mode = RNBRunLoopLaunchAttaching(remote, attach_pid, attached_pid);
        if (mode != eRNBRunLoopModeInferiorExecuting) {
          const char *error_str = remote->Context().LaunchStatus().AsString();
          RNBLogSTDERR("error: failed to attach process %i: %s\n", attach_pid,
                       error_str ? error_str : "unknown error.");
          mode = eRNBRunLoopModeExit;
        }
      } else if (!attach_pid_name.empty()) {
        struct timespec attach_timeout_abstime, *timeout_ptr = NULL;
        if (waitfor_duration != 0) {
          DNBTimer::OffsetTimeOfDay(&attach_timeout_abstime, waitfor_duration,
                                    0);
          timeout_ptr = &attach_timeout_abstime;
        }

        RNBLogSTDOUT("Attaching to process %s...\n", attach_pid_name.c_str());
        nub_process_t pid = DNBProcessAttachByName(
            attach_pid_name.c_str(), timeout_ptr, err_str, sizeof(err_str));
        g_pid = pid;
        if (pid == INVALID_NUB_PROCESS) {
          ctx.LaunchStatus().SetError(-1, DNBError::Generic);
          if (err_str[0])
            ctx.LaunchStatus().SetErrorString(err_str);
          RNBLogSTDERR("error: failed to attach to process named: \"%s\" %s\n",
                       waitfor_pid_name.c_str(), err_str);
          mode = eRNBRunLoopModeExit;
        } else {
          ctx.SetProcessID(pid);
          mode = eRNBRunLoopModeInferiorExecuting;
        }

      } else {
        RNBLogSTDERR(
            "error: asked to attach with empty name and invalid PID.\n");
        mode = eRNBRunLoopModeExit;
      }

      if (mode != eRNBRunLoopModeExit) {
        if (port != INT32_MAX) {
          if (!ConnectRemote(remote, host.c_str(), port, reverse_connect,
                             named_pipe_path.c_str(), unix_socket_name.c_str()))
            mode = eRNBRunLoopModeExit;
        } else if (str[0] == '/') {
          if (remote->Comm().OpenFile(str))
            mode = eRNBRunLoopModeExit;
        } else if (communication_fd >= 0) {
          // We were passed a file descriptor to use during fork/exec that is
          // already open
          // in our process, so lets just use it!
          if (remote->Comm().useFD(communication_fd))
            mode = eRNBRunLoopModeExit;
          else
            remote->StartReadRemoteDataThread();
        }

        if (mode != eRNBRunLoopModeExit)
          RNBLogSTDOUT("Waiting for debugger instructions for process %d.\n",
                       attach_pid);
      }
      break;

    case eRNBRunLoopModeInferiorLaunching: {
      mode = RNBRunLoopLaunchInferior(remote, ctx.GetSTDINPath(),
                                      ctx.GetSTDOUTPath(), ctx.GetSTDERRPath(),
                                      no_stdio);

      if (mode == eRNBRunLoopModeInferiorExecuting) {
        if (port != INT32_MAX) {
          if (!ConnectRemote(remote, host.c_str(), port, reverse_connect,
                             named_pipe_path.c_str(), unix_socket_name.c_str()))
            mode = eRNBRunLoopModeExit;
        } else if (str[0] == '/') {
          if (remote->Comm().OpenFile(str))
            mode = eRNBRunLoopModeExit;
        } else if (communication_fd >= 0) {
          // We were passed a file descriptor to use during fork/exec that is
          // already open
          // in our process, so lets just use it!
          if (remote->Comm().useFD(communication_fd))
            mode = eRNBRunLoopModeExit;
          else
            remote->StartReadRemoteDataThread();
        }

        if (mode != eRNBRunLoopModeExit) {
          const char *proc_name = "<unknown>";
          if (ctx.ArgumentCount() > 0)
            proc_name = ctx.ArgumentAtIndex(0);
          RNBLogSTDOUT("Got a connection, launched process %s (pid = %d).\n",
                       proc_name, ctx.ProcessID());
        }
      } else {
        const char *error_str = remote->Context().LaunchStatus().AsString();
        RNBLogSTDERR("error: failed to launch process %s: %s\n", argv_sub_zero,
                     error_str ? error_str : "unknown error.");
      }
    } break;

    case eRNBRunLoopModeInferiorExecuting:
      mode = RNBRunLoopInferiorExecuting(remote);
      break;

    case eRNBRunLoopModePlatformMode:
      if (port != INT32_MAX) {
        if (!ConnectRemote(remote, host.c_str(), port, reverse_connect,
                           named_pipe_path.c_str(), unix_socket_name.c_str()))
          mode = eRNBRunLoopModeExit;
      } else if (str[0] == '/') {
        if (remote->Comm().OpenFile(str))
          mode = eRNBRunLoopModeExit;
      } else if (communication_fd >= 0) {
        // We were passed a file descriptor to use during fork/exec that is
        // already open
        // in our process, so lets just use it!
        if (remote->Comm().useFD(communication_fd))
          mode = eRNBRunLoopModeExit;
        else
          remote->StartReadRemoteDataThread();
      }

      if (mode != eRNBRunLoopModeExit)
        mode = RNBRunLoopPlatform(remote);
      break;

    default:
      mode = eRNBRunLoopModeExit;
    case eRNBRunLoopModeExit:
      break;
    }
  }

  remote->StopReadRemoteDataThread();
  remote->Context().SetProcessID(INVALID_NUB_PROCESS);
  RNBLogSTDOUT("Exiting.\n");

  return 0;
}
