// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "platform/globals.h"
#if defined(HOST_OS_FUCHSIA)

#include "bin/process.h"

#include <errno.h>
#include <fcntl.h>
#include <lib/fdio/io.h>
#include <lib/fdio/namespace.h>
#include <lib/fdio/spawn.h>
#include <poll.h>
#include <pthread.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <zircon/process.h>
#include <zircon/processargs.h>
#include <zircon/status.h>
#include <zircon/syscalls.h>
#include <zircon/syscalls/object.h>
#include <zircon/types.h>

#include "bin/dartutils.h"
#include "bin/eventhandler.h"
#include "bin/fdutils.h"
#include "bin/file.h"
#include "bin/lockers.h"
#include "bin/namespace.h"
#include "bin/namespace_fuchsia.h"
#include "platform/signal_blocker.h"
#include "platform/syslog.h"
#include "platform/utils.h"

// #define PROCESS_LOGGING 1
#if defined(PROCESS_LOGGING)
#define LOG_ERR(msg, ...) Syslog::PrintErr("Dart Process: " msg, ##__VA_ARGS__)
#define LOG_INFO(msg, ...) Syslog::Print("Dart Process: " msg, ##__VA_ARGS__)
#else
#define LOG_ERR(msg, ...)
#define LOG_INFO(msg, ...)
#endif  // defined(PROCESS_LOGGING)

namespace dart {
namespace bin {

int Process::global_exit_code_ = 0;
Mutex* Process::global_exit_code_mutex_ = new Mutex();
Process::ExitHook Process::exit_hook_ = NULL;

// ProcessInfo is used to map a process id to the file descriptor for
// the pipe used to communicate the exit code of the process to Dart.
// ProcessInfo objects are kept in the static singly-linked
// ProcessInfoList.
class ProcessInfo {
 public:
  ProcessInfo(zx_handle_t process, intptr_t fd)
      : process_(process), exit_pipe_fd_(fd) {}
  ~ProcessInfo() {
    int closed = NO_RETRY_EXPECTED(close(exit_pipe_fd_));
    if (closed != 0) {
      LOG_ERR("Failed to close process exit code pipe");
    }
    zx_handle_close(process_);
  }
  zx_handle_t process() const { return process_; }
  intptr_t exit_pipe_fd() const { return exit_pipe_fd_; }
  ProcessInfo* next() const { return next_; }
  void set_next(ProcessInfo* info) { next_ = info; }

 private:
  zx_handle_t process_;
  intptr_t exit_pipe_fd_;
  ProcessInfo* next_;

  DISALLOW_COPY_AND_ASSIGN(ProcessInfo);
};

// Singly-linked list of ProcessInfo objects for all active processes
// started from Dart.
class ProcessInfoList {
 public:
  static void AddProcess(zx_handle_t process, intptr_t fd) {
    MutexLocker locker(mutex_);
    ProcessInfo* info = new ProcessInfo(process, fd);
    info->set_next(active_processes_);
    active_processes_ = info;
  }

  static intptr_t LookupProcessExitFd(zx_handle_t process) {
    MutexLocker locker(mutex_);
    ProcessInfo* current = active_processes_;
    while (current != NULL) {
      if (current->process() == process) {
        return current->exit_pipe_fd();
      }
      current = current->next();
    }
    return 0;
  }

  static bool Exists(zx_handle_t process) {
    return LookupProcessExitFd(process) != 0;
  }

  static void RemoveProcess(zx_handle_t process) {
    MutexLocker locker(mutex_);
    ProcessInfo* prev = NULL;
    ProcessInfo* current = active_processes_;
    while (current != NULL) {
      if (current->process() == process) {
        if (prev == NULL) {
          active_processes_ = current->next();
        } else {
          prev->set_next(current->next());
        }
        delete current;
        return;
      }
      prev = current;
      current = current->next();
    }
  }

 private:
  // Linked list of ProcessInfo objects for all active processes
  // started from Dart code.
  static ProcessInfo* active_processes_;
  // Mutex protecting all accesses to the linked list of active
  // processes.
  static Mutex* mutex_;

  DISALLOW_ALLOCATION();
  DISALLOW_IMPLICIT_CONSTRUCTORS(ProcessInfoList);
};

ProcessInfo* ProcessInfoList::active_processes_ = NULL;
Mutex* ProcessInfoList::mutex_ = new Mutex();

// The exit code handler sets up a separate thread which waits for child
// processes to terminate. That separate thread can then get the exit code from
// processes that have exited and communicate it to Dart through the
// event loop.
class ExitCodeHandler {
 public:
  // Notify the ExitCodeHandler that another process exists.
  static void Start() {
    // Multiple isolates could be starting processes at the same
    // time. Make sure that only one ExitCodeHandler thread exists.
    MonitorLocker locker(monitor_);
    if (running_) {
      return;
    }
    LOG_INFO("ExitCodeHandler Starting\n");

    zx_status_t status = zx_port_create(0, &port_);
    if (status != ZX_OK) {
      FATAL1("ExitCodeHandler: zx_port_create failed: %s\n",
             zx_status_get_string(status));
      return;
    }

    // Start thread that handles process exits when wait returns.
    intptr_t result =
        Thread::Start("dart:io Process.start", ExitCodeHandlerEntry, 0);
    if (result != 0) {
      FATAL1("Failed to start exit code handler worker thread %ld", result);
    }

    running_ = true;
  }

  static zx_status_t Add(zx_handle_t process) {
    MonitorLocker locker(monitor_);
    LOG_INFO("ExitCodeHandler Adding Process: %u\n", process);
    return zx_object_wait_async(process, port_, static_cast<uint64_t>(process),
                                ZX_TASK_TERMINATED, ZX_WAIT_ASYNC_ONCE);
  }

  static void Terminate() {
    MonitorLocker locker(monitor_);
    if (!running_) {
      return;
    }
    running_ = false;

    LOG_INFO("ExitCodeHandler Terminating\n");
    SendShutdownMessage();

    while (!terminate_done_) {
      monitor_->Wait(Monitor::kNoTimeout);
    }
    zx_handle_close(port_);
    LOG_INFO("ExitCodeHandler Terminated\n");
  }

 private:
  static const uint64_t kShutdownPacketKey = 1;

  static void SendShutdownMessage() {
    zx_port_packet_t pkt;
    pkt.key = kShutdownPacketKey;
    zx_status_t status = zx_port_queue(port_, &pkt);
    if (status != ZX_OK) {
      Syslog::PrintErr("ExitCodeHandler: zx_port_queue failed: %s\n",
                       zx_status_get_string(status));
    }
  }

  // Entry point for the separate exit code handler thread started by
  // the ExitCodeHandler.
  static void ExitCodeHandlerEntry(uword param) {
    LOG_INFO("ExitCodeHandler Entering ExitCodeHandler thread\n");

    zx_port_packet_t pkt;
    while (true) {
      zx_status_t status = zx_port_wait(port_, ZX_TIME_INFINITE, &pkt);
      if (status != ZX_OK) {
        FATAL1("ExitCodeHandler: zx_port_wait failed: %s\n",
               zx_status_get_string(status));
      }
      if (pkt.type == ZX_PKT_TYPE_USER) {
        ASSERT(pkt.key == kShutdownPacketKey);
        break;
      }
      zx_handle_t process = static_cast<zx_handle_t>(pkt.key);
      zx_signals_t observed = pkt.signal.observed;
      if ((observed & ZX_TASK_TERMINATED) == ZX_SIGNAL_NONE) {
        LOG_ERR("ExitCodeHandler: Unexpected signals, process %u: %ux\n",
                process, observed);
      }
      SendProcessStatus(process);
    }

    LOG_INFO("ExitCodeHandler thread shutting down\n");
    terminate_done_ = true;
    monitor_->Notify();
  }

  static void SendProcessStatus(zx_handle_t process) {
    LOG_INFO("ExitCodeHandler thread getting process status: %u\n", process);
    int return_code = -1;
    zx_info_process_t proc_info;
    zx_status_t status = zx_object_get_info(
        process, ZX_INFO_PROCESS, &proc_info, sizeof(proc_info), NULL, NULL);
    if (status != ZX_OK) {
      Syslog::PrintErr("ExitCodeHandler: zx_object_get_info failed: %s\n",
                       zx_status_get_string(status));
    } else {
      return_code = proc_info.return_code;
    }
    zx_handle_close(process);
    LOG_INFO("ExitCodeHandler thread process %u exited with %d\n", process,
             return_code);

    const intptr_t exit_code_fd = ProcessInfoList::LookupProcessExitFd(process);
    LOG_INFO("ExitCodeHandler thread sending %u code %d on fd %ld\n", process,
             return_code, exit_code_fd);
    if (exit_code_fd != 0) {
      int exit_message[2];
      exit_message[0] = abs(return_code);
      exit_message[1] = return_code >= 0 ? 0 : 1;
      intptr_t result = FDUtils::WriteToBlocking(exit_code_fd, &exit_message,
                                                 sizeof(exit_message));
      ASSERT((result == -1) || (result == sizeof(exit_code_fd)));
      if ((result == -1) && (errno != EPIPE)) {
        int err = errno;
        Syslog::PrintErr("Failed to write exit code for process %d: errno=%d\n",
                         process, err);
      }
      LOG_INFO("ExitCodeHandler thread wrote %ld bytes to fd %ld\n", result,
               exit_code_fd);
      LOG_INFO("ExitCodeHandler thread removing process %u from list\n",
               process);
      ProcessInfoList::RemoveProcess(process);
    } else {
      LOG_ERR("ExitCodeHandler: Process %u not found\n", process);
    }
  }

  static zx_handle_t port_;

  // Protected by monitor_.
  static bool terminate_done_;
  static bool running_;
  static Monitor* monitor_;

  DISALLOW_ALLOCATION();
  DISALLOW_IMPLICIT_CONSTRUCTORS(ExitCodeHandler);
};

zx_handle_t ExitCodeHandler::port_ = ZX_HANDLE_INVALID;
bool ExitCodeHandler::running_ = false;
bool ExitCodeHandler::terminate_done_ = false;
Monitor* ExitCodeHandler::monitor_ = new Monitor();

void Process::TerminateExitCodeHandler() {
  ExitCodeHandler::Terminate();
}

intptr_t Process::CurrentProcessId() {
  return static_cast<intptr_t>(getpid());
}

int64_t Process::CurrentRSS() {
  zx_info_task_stats_t task_stats;
  zx_handle_t process = zx_process_self();
  zx_status_t status = zx_object_get_info(
      process, ZX_INFO_TASK_STATS, &task_stats, sizeof(task_stats), NULL, NULL);
  if (status != ZX_OK) {
    // TODO(zra): Translate this to a Unix errno.
    errno = status;
    return -1;
  }
  return task_stats.mem_private_bytes + task_stats.mem_shared_bytes;
}

int64_t Process::MaxRSS() {
  // There is currently no way to get the high watermark value on Fuchsia, so
  // just return the current RSS value.
  return CurrentRSS();
}

class IOHandleScope {
 public:
  explicit IOHandleScope(IOHandle* io_handle) : io_handle_(io_handle) {}
  ~IOHandleScope() {
    io_handle_->Close();
    io_handle_->Release();
  }

 private:
  IOHandle* io_handle_;

  DISALLOW_ALLOCATION();
  DISALLOW_COPY_AND_ASSIGN(IOHandleScope);
};

bool Process::Wait(intptr_t pid,
                   intptr_t in,
                   intptr_t out,
                   intptr_t err,
                   intptr_t exit_event,
                   ProcessResult* result) {
  IOHandle* out_iohandle = reinterpret_cast<IOHandle*>(out);
  IOHandle* err_iohandle = reinterpret_cast<IOHandle*>(err);
  IOHandle* exit_iohandle = reinterpret_cast<IOHandle*>(exit_event);

  // There is no return from this function using Dart_PropagateError
  // as memory used by the buffer lists is freed through their
  // destructors.
  BufferList out_data;
  BufferList err_data;
  union {
    uint8_t bytes[8];
    int32_t ints[2];
  } exit_code_data;

  // Create a port, which is like an epoll() fd on Linux.
  zx_handle_t port;
  zx_status_t status = zx_port_create(0, &port);
  if (status != ZX_OK) {
    Syslog::PrintErr("Process::Wait: zx_port_create failed: %s\n",
                     zx_status_get_string(status));
    return false;
  }

  IOHandle* out_tmp = out_iohandle;
  IOHandle* err_tmp = err_iohandle;
  IOHandle* exit_tmp = exit_iohandle;
  const uint64_t out_key = reinterpret_cast<uint64_t>(out_tmp);
  const uint64_t err_key = reinterpret_cast<uint64_t>(err_tmp);
  const uint64_t exit_key = reinterpret_cast<uint64_t>(exit_tmp);
  const uint32_t events = POLLRDHUP | POLLIN;
  if (!out_tmp->AsyncWait(port, events, out_key)) {
    return false;
  }
  if (!err_tmp->AsyncWait(port, events, err_key)) {
    return false;
  }
  if (!exit_tmp->AsyncWait(port, events, exit_key)) {
    return false;
  }
  while ((out_tmp != NULL) || (err_tmp != NULL) || (exit_tmp != NULL)) {
    zx_port_packet_t pkt;
    status = zx_port_wait(port, ZX_TIME_INFINITE, &pkt);
    if (status != ZX_OK) {
      Syslog::PrintErr("Process::Wait: zx_port_wait failed: %s\n",
                       zx_status_get_string(status));
      return false;
    }
    IOHandle* event_handle = reinterpret_cast<IOHandle*>(pkt.key);
    const intptr_t event_mask = event_handle->WaitEnd(pkt.signal.observed);
    if (event_handle == out_tmp) {
      if ((event_mask & POLLIN) != 0) {
        const intptr_t avail = FDUtils::AvailableBytes(out_tmp->fd());
        if (!out_data.Read(out_tmp->fd(), avail)) {
          return false;
        }
      }
      if ((event_mask & POLLRDHUP) != 0) {
        out_tmp->CancelWait(port, out_key);
        out_tmp = NULL;
      }
    } else if (event_handle == err_tmp) {
      if ((event_mask & POLLIN) != 0) {
        const intptr_t avail = FDUtils::AvailableBytes(err_tmp->fd());
        if (!err_data.Read(err_tmp->fd(), avail)) {
          return false;
        }
      }
      if ((event_mask & POLLRDHUP) != 0) {
        err_tmp->CancelWait(port, err_key);
        err_tmp = NULL;
      }
    } else if (event_handle == exit_tmp) {
      if ((event_mask & POLLIN) != 0) {
        const intptr_t avail = FDUtils::AvailableBytes(exit_tmp->fd());
        if (avail == 8) {
          intptr_t b =
              NO_RETRY_EXPECTED(read(exit_tmp->fd(), exit_code_data.bytes, 8));
          if (b != 8) {
            return false;
          }
        }
      }
      if ((event_mask & POLLRDHUP) != 0) {
        exit_tmp->CancelWait(port, exit_key);
        exit_tmp = NULL;
      }
    } else {
      Syslog::PrintErr("Process::Wait: Unexpected wait key: %p\n",
                       event_handle);
    }
    if (out_tmp != NULL) {
      if (!out_tmp->AsyncWait(port, events, out_key)) {
        return false;
      }
    }
    if (err_tmp != NULL) {
      if (!err_tmp->AsyncWait(port, events, err_key)) {
        return false;
      }
    }
    if (exit_tmp != NULL) {
      if (!exit_tmp->AsyncWait(port, events, exit_key)) {
        return false;
      }
    }
  }

  // All handles closed and all data read.
  result->set_stdout_data(out_data.GetData());
  result->set_stderr_data(err_data.GetData());
  DEBUG_ASSERT(out_data.IsEmpty());
  DEBUG_ASSERT(err_data.IsEmpty());

  // Calculate the exit code.
  intptr_t exit_code = exit_code_data.ints[0];
  intptr_t negative = exit_code_data.ints[1];
  if (negative != 0) {
    exit_code = -exit_code;
  }
  result->set_exit_code(exit_code);

  // Close the process handle.
  zx_handle_t process = static_cast<zx_handle_t>(pid);
  zx_handle_close(process);
  return true;
}

bool Process::Kill(intptr_t id, int signal) {
  LOG_INFO("Sending signal %d to process with id %ld\n", signal, id);
  // zx_task_kill is definitely going to kill the process.
  if ((signal != SIGTERM) && (signal != SIGKILL)) {
    LOG_ERR("Signal %d not supported\n", signal);
    errno = ENOSYS;
    return false;
  }
  // We can only use zx_task_kill if we know id is a process handle, and we only
  // know that for sure if it's in our list.
  zx_handle_t process = static_cast<zx_handle_t>(id);
  if (!ProcessInfoList::Exists(process)) {
    LOG_ERR("Process %ld wasn't in the ProcessInfoList\n", id);
    errno = ESRCH;  // No such process.
    return false;
  }
  zx_status_t status = zx_task_kill(process);
  if (status != ZX_OK) {
    LOG_ERR("zx_task_kill failed: %s\n", zx_status_get_string(status));
    errno = EPERM;  // TODO(zra): Figure out what it really should be.
    return false;
  }
  LOG_INFO("Signal %d sent successfully to process %ld\n", signal, id);
  return true;
}

class ProcessStarter {
 public:
  ProcessStarter(Namespace* namespc,
                 const char* path,
                 char* arguments[],
                 intptr_t arguments_length,
                 const char* working_directory,
                 char* environment[],
                 intptr_t environment_length,
                 ProcessStartMode mode,
                 intptr_t* in,
                 intptr_t* out,
                 intptr_t* err,
                 intptr_t* id,
                 intptr_t* exit_event,
                 char** os_error_message)
      : namespc_(namespc),
        path_(path),
        working_directory_(working_directory),
        mode_(mode),
        in_(in),
        out_(out),
        err_(err),
        id_(id),
        exit_event_(exit_event),
        os_error_message_(os_error_message) {
    LOG_INFO("ProcessStarter: ctor %s with %ld args, mode = %d\n", path,
             arguments_length, mode);

    read_in_ = -1;
    read_err_ = -1;
    write_out_ = -1;

    program_arguments_ = reinterpret_cast<char**>(Dart_ScopeAllocate(
        (arguments_length + 2) * sizeof(*program_arguments_)));
    program_arguments_[0] = const_cast<char*>(path_);
    for (int i = 0; i < arguments_length; i++) {
      program_arguments_[i + 1] = arguments[i];
    }
    program_arguments_[arguments_length + 1] = NULL;

    program_environment_ = NULL;
    if (environment != NULL) {
      program_environment_ = reinterpret_cast<char**>(Dart_ScopeAllocate(
          (environment_length + 1) * sizeof(*program_environment_)));
      for (int i = 0; i < environment_length; i++) {
        program_environment_[i] = environment[i];
      }
      program_environment_[environment_length] = NULL;
    }
  }

  ~ProcessStarter() {
    if (read_in_ != -1) {
      close(read_in_);
    }
    if (read_err_ != -1) {
      close(read_err_);
    }
    if (write_out_ != -1) {
      close(write_out_);
    }
  }

  int Start() {
    LOG_INFO("ProcessStarter: Start()\n");
    int exit_pipe_fds[2];
    intptr_t result = NO_RETRY_EXPECTED(pipe(exit_pipe_fds));
    if (result != 0) {
      *os_error_message_ = DartUtils::ScopedCopyCString(
          "Failed to create exit code pipe for process start.");
      return result;
    }
    LOG_INFO("ProcessStarter: Start() set up exit_pipe_fds (%d, %d)\n",
             exit_pipe_fds[0], exit_pipe_fds[1]);

    NamespaceScope ns(namespc_, path_);
    const int pathfd =
        TEMP_FAILURE_RETRY(openat(ns.fd(), ns.path(), O_RDONLY));
    zx_handle_t vmo = ZX_HANDLE_INVALID;
    zx_status_t status = fdio_get_vmo_clone(pathfd, &vmo);
    close(pathfd);
    if (status != ZX_OK) {
      close(exit_pipe_fds[0]);
      close(exit_pipe_fds[1]);
      *os_error_message_ = DartUtils::ScopedCopyCString(
          "Failed to load executable for process start.");
      return status;
    }

    // After reading the binary into a VMO, we need to mark it as executable,
    // since the VMO returned by fdio_get_vmo_clone should be read-only.
    status = zx_vmo_replace_as_executable(vmo, ZX_HANDLE_INVALID, &vmo);
    if (status != ZX_OK) {
      close(exit_pipe_fds[0]);
      close(exit_pipe_fds[1]);
      *os_error_message_ = DartUtils::ScopedCopyCString(
          "Failed to mark binary as executable for process start.");
      return status;
    }

    fdio_spawn_action_t* actions;
    const intptr_t actions_count = BuildSpawnActions(
        namespc_->namespc()->fdio_ns(), &actions);
    if (actions_count < 0) {
      zx_handle_close(vmo);
      close(exit_pipe_fds[0]);
      close(exit_pipe_fds[1]);
      *os_error_message_ = DartUtils::ScopedCopyCString(
          "Failed to build spawn actions array.");
      return ZX_ERR_IO;
    }

    // TODO(zra): Use the supplied working directory when fdio_spawn_vmo adds an
    // API to set it.

    LOG_INFO("ProcessStarter: Start() Calling fdio_spawn_vmo\n");
    zx_handle_t process = ZX_HANDLE_INVALID;
    char err_msg[FDIO_SPAWN_ERR_MSG_MAX_LENGTH];
    uint32_t flags = FDIO_SPAWN_CLONE_JOB | FDIO_SPAWN_CLONE_LDSVC;
    status = fdio_spawn_vmo(ZX_HANDLE_INVALID, flags, vmo, program_arguments_,
                            program_environment_, actions_count, actions,
                            &process, err_msg);
    // Handles are consumed by fdio_spawn_vmo even if it fails.
    delete[] actions;
    if (status != ZX_OK) {
      LOG_ERR("ProcessStarter: Start() fdio_spawn_vmo failed\n");
      close(exit_pipe_fds[0]);
      close(exit_pipe_fds[1]);
      ReportStartError(err_msg);
      return status;
    }

    LOG_INFO("ProcessStarter: Start() adding %u to list with exit_pipe %d\n",
             process, exit_pipe_fds[1]);
    ProcessInfoList::AddProcess(process, exit_pipe_fds[1]);
    ExitCodeHandler::Start();
    status = ExitCodeHandler::Add(process);
    if (status != ZX_OK) {
      LOG_ERR("ProcessStarter: ExitCodeHandler: Add failed: %s\n",
              zx_status_get_string(status));
      close(exit_pipe_fds[0]);
      close(exit_pipe_fds[1]);
      zx_task_kill(process);
      ProcessInfoList::RemoveProcess(process);
      ReportStartError(zx_status_get_string(status));
      return status;
    }

    // The IOHandles allocated below are returned to Dart code. The Dart code
    // calls into the runtime again to allocate a C++ Socket object, which
    // becomes the native field of a Dart _NativeSocket object. The C++ Socket
    // object and the EventHandler manage the lifetime of these IOHandles.
    *id_ = process;
    FDUtils::SetNonBlocking(read_in_);
    *in_ = reinterpret_cast<intptr_t>(new IOHandle(read_in_));
    read_in_ = -1;
    FDUtils::SetNonBlocking(read_err_);
    *err_ = reinterpret_cast<intptr_t>(new IOHandle(read_err_));
    read_err_ = -1;
    FDUtils::SetNonBlocking(write_out_);
    *out_ = reinterpret_cast<intptr_t>(new IOHandle(write_out_));
    write_out_ = -1;
    FDUtils::SetNonBlocking(exit_pipe_fds[0]);
    *exit_event_ = reinterpret_cast<intptr_t>(new IOHandle(exit_pipe_fds[0]));
    return 0;
  }

 private:
  void ReportStartError(const char* errormsg) {
    const intptr_t kMaxMessageSize = 256;
    char* message = DartUtils::ScopedCString(kMaxMessageSize);
    snprintf(message, kMaxMessageSize, "Process start failed: %s\n", errormsg);
    *os_error_message_ = message;
  }

  zx_status_t AddPipe(int target_fd, int* local_fd,
                      fdio_spawn_action_t* action) {
    zx_status_t status = fdio_pipe_half2(local_fd, &action->h.handle);
    if (status != ZX_OK) return status;
    action->action = FDIO_SPAWN_ACTION_ADD_HANDLE;
    action->h.id = PA_HND(PA_HND_TYPE(PA_FD), target_fd);
    return ZX_OK;
  }

  // Fills in 'actions_out' and returns action count.
  intptr_t BuildSpawnActions(fdio_ns_t* ns, fdio_spawn_action_t** actions_out) {
    const intptr_t fixed_actions_cnt = 4;
    intptr_t ns_cnt = 0;
    zx_status_t status;

    // First, figure out how many namespace actions are needed.
    fdio_flat_namespace_t* flat_ns = nullptr;
    if (ns != nullptr) {
      status = fdio_ns_export(ns, &flat_ns);
      if (status != ZX_OK) {
        LOG_ERR("ProcessStarter: BuildSpawnActions: fdio_ns_export: %s\n",
                zx_status_get_string(status));
        return -1;
      }
      ns_cnt = flat_ns->count;
    }

    // Allocate the actions array.
    const intptr_t actions_cnt = ns_cnt + fixed_actions_cnt;
    fdio_spawn_action_t* actions = new fdio_spawn_action_t[actions_cnt];

    // Fill in the entries for passing stdin/out/err handles, and the program
    // name.
    status = AddPipe(0, &write_out_, &actions[0]);
    if (status != ZX_OK) {
      LOG_ERR("ProcessStarter: BuildSpawnActions: stdout AddPipe failed: %s\n",
              zx_status_get_string(status));
      if (flat_ns != nullptr) {
        fdio_ns_free_flat_ns(flat_ns);
      }
      return -1;
    }
    status = AddPipe(1, &read_in_, &actions[1]);
    if (status != ZX_OK) {
      LOG_ERR("ProcessStarter: BuildSpawnActions: stdin AddPipe failed: %s\n",
              zx_status_get_string(status));
      if (flat_ns != nullptr) {
        fdio_ns_free_flat_ns(flat_ns);
      }
      return -1;
    }
    status = AddPipe(2, &read_err_, &actions[2]);
    if (status != ZX_OK) {
      LOG_ERR("ProcessStarter: BuildSpawnActions: stderr AddPipe failed: %s\n",
              zx_status_get_string(status));
      if (flat_ns != nullptr) {
        fdio_ns_free_flat_ns(flat_ns);
      }
      return -1;
    }
    actions[3] = {
      .action = FDIO_SPAWN_ACTION_SET_NAME,
      .name.data = program_arguments_[0],
    };

    // Then fill in the namespace actions.
    if (ns != nullptr) {
      for (size_t i = 0; i < flat_ns->count; i++) {
        actions[fixed_actions_cnt + i] = {
          .action = FDIO_SPAWN_ACTION_ADD_NS_ENTRY,
          .ns.prefix = flat_ns->path[i],
          .ns.handle = flat_ns->handle[i],
        };
      }
      free(flat_ns);
      flat_ns = nullptr;
    }

    *actions_out = actions;
    return actions_cnt;
  }

  int read_in_;    // Pipe for stdout to child process.
  int read_err_;   // Pipe for stderr to child process.
  int write_out_;  // Pipe for stdin to child process.

  char** program_arguments_;
  char** program_environment_;

  Namespace* namespc_;
  const char* path_;
  const char* working_directory_;
  ProcessStartMode mode_;
  intptr_t* in_;
  intptr_t* out_;
  intptr_t* err_;
  intptr_t* id_;
  intptr_t* exit_event_;
  char** os_error_message_;

  DISALLOW_ALLOCATION();
  DISALLOW_IMPLICIT_CONSTRUCTORS(ProcessStarter);
};

int Process::Start(Namespace* namespc,
                   const char* path,
                   char* arguments[],
                   intptr_t arguments_length,
                   const char* working_directory,
                   char* environment[],
                   intptr_t environment_length,
                   ProcessStartMode mode,
                   intptr_t* in,
                   intptr_t* out,
                   intptr_t* err,
                   intptr_t* id,
                   intptr_t* exit_event,
                   char** os_error_message) {
  if (mode != kNormal) {
    *os_error_message = DartUtils::ScopedCopyCString(
        "Only ProcessStartMode.NORMAL is supported on this platform");
    return -1;
  }
  ProcessStarter starter(namespc, path, arguments, arguments_length,
                         working_directory, environment, environment_length,
                         mode, in, out, err, id, exit_event, os_error_message);
  return starter.Start();
}

intptr_t Process::SetSignalHandler(intptr_t signal) {
  errno = ENOSYS;
  return -1;
}

void Process::ClearSignalHandler(intptr_t signal, Dart_Port port) {}

}  // namespace bin
}  // namespace dart

#endif  // defined(HOST_OS_FUCHSIA)
