// 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.

#if !defined(DART_IO_DISABLED)

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

#include "bin/process.h"

#include <errno.h>
#include <fcntl.h>
#include <launchpad/launchpad.h>
#include <launchpad/vmo.h>
#include <magenta/process.h>
#include <magenta/status.h>
#include <magenta/syscalls.h>
#include <magenta/syscalls/object.h>
#include <magenta/types.h>
#include <mxio/private.h>
#include <mxio/util.h>
#include <poll.h>
#include <pthread.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "bin/dartutils.h"
#include "bin/eventhandler.h"
#include "bin/fdutils.h"
#include "bin/lockers.h"
#include "bin/log.h"
#include "platform/signal_blocker.h"
#include "platform/utils.h"

// #define PROCESS_LOGGING 1
#if defined(PROCESS_LOGGING)
#define LOG_ERR(msg, ...) Log::PrintErr("Dart Process: " msg, ##__VA_ARGS__)
#define LOG_INFO(msg, ...) Log::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(mx_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) {
      FATAL("Failed to close process exit code pipe");
    }
    mx_handle_close(process_);
  }
  mx_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:
  mx_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(mx_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(mx_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(mx_handle_t process) {
    return LookupProcessExitFd(process) != 0;
  }

  static void RemoveProcess(mx_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");

    mx_status_t status = mx_socket_create(0, &interrupt_in_, &interrupt_out_);
    if (status < 0) {
      FATAL1("Failed to create exit code handler interrupt socket: %s\n",
             mx_status_get_string(status));
    }

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

    running_ = true;
  }

  static void Add(mx_handle_t process) {
    MonitorLocker locker(monitor_);
    LOG_INFO("ExitCodeHandler Adding Process: %ld\n", process);
    SendMessage(Message::kAdd, process);
  }

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

    LOG_INFO("ExitCodeHandler Terminating\n");
    SendMessage(Message::kShutdown, MX_HANDLE_INVALID);

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

 private:
  class Message {
   public:
    enum Command {
      kAdd,
      kShutdown,
    };
    Command command;
    mx_handle_t handle;
  };

  static void SendMessage(Message::Command command, mx_handle_t handle) {
    Message msg;
    msg.command = command;
    msg.handle = handle;
    size_t actual;
    mx_status_t status =
        mx_socket_write(interrupt_in_, 0, &msg, sizeof(msg), &actual);
    if (status < 0) {
      FATAL1("Write to exit handler interrupt handle failed: %s\n",
             mx_status_get_string(status));
    }
    ASSERT(actual == sizeof(msg));
  }

  // 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");
    item_capacity_ = 16;
    items_ = reinterpret_cast<mx_wait_item_t*>(
        malloc(item_capacity_ * sizeof(*items_)));
    items_to_remove_ = reinterpret_cast<intptr_t*>(
        malloc(item_capacity_ * sizeof(*items_to_remove_)));

    // The interrupt handle is fixed to the first entry.
    items_[0].handle = interrupt_out_;
    items_[0].waitfor = MX_SOCKET_READABLE | MX_SOCKET_PEER_CLOSED;
    items_[0].pending = MX_SIGNAL_NONE;
    item_count_ = 1;

    while (!do_shutdown_) {
      LOG_INFO("ExitCodeHandler Calling mx_object_wait_many: %ld items\n",
               item_count_);
      mx_status_t status =
          mx_object_wait_many(items_, item_count_, MX_TIME_INFINITE);
      if (status < 0) {
        FATAL1("Exit code handler handle wait failed: %s\n",
               mx_status_get_string(status));
      }
      LOG_INFO("ExitCodeHandler mx_object_wait_many returned\n");

      bool have_interrupt = false;
      intptr_t remove_count = 0;
      for (intptr_t i = 0; i < item_count_; i++) {
        if (items_[i].pending == MX_SIGNAL_NONE) {
          continue;
        }
        if (i == 0) {
          LOG_INFO("ExitCodeHandler thread saw interrupt\n");
          have_interrupt = true;
          continue;
        }
        ASSERT(items_[i].waitfor == MX_TASK_TERMINATED);
        ASSERT((items_[i].pending & MX_TASK_TERMINATED) != 0);
        LOG_INFO("ExitCodeHandler signal for %ld\n", items_[i].handle);
        SendProcessStatus(items_[i].handle);
        items_to_remove_[remove_count++] = i;
      }
      for (intptr_t i = 0; i < remove_count; i++) {
        RemoveItem(items_to_remove_[i]);
      }
      if (have_interrupt) {
        HandleInterruptMsg();
      }
    }

    LOG_INFO("ExitCodeHandler thread shutting down\n");
    mx_handle_close(interrupt_out_);
    free(items_);
    items_ = NULL;
    free(items_to_remove_);
    items_to_remove_ = NULL;
    item_count_ = 0;
    item_capacity_ = 0;

    terminate_done_ = true;
    monitor_->Notify();
  }

  static void SendProcessStatus(mx_handle_t process) {
    LOG_INFO("ExitCodeHandler thread getting process status: %ld\n", process);
    mx_info_process_t proc_info;
    mx_status_t status = mx_object_get_info(
        process, MX_INFO_PROCESS, &proc_info, sizeof(proc_info), NULL, NULL);
    if (status < 0) {
      FATAL1("mx_object_get_info failed on process handle: %s\n",
             mx_status_get_string(status));
    }

    const int return_code = proc_info.return_code;
    status = mx_handle_close(process);
    if (status < 0) {
      FATAL1("Failed to close process handle: %s\n",
             mx_status_get_string(status));
    }
    LOG_INFO("ExitCodeHandler thread process %ld exited with %d\n", process,
             return_code);

    const intptr_t exit_code_fd = ProcessInfoList::LookupProcessExitFd(process);
    LOG_INFO("ExitCodeHandler thread sending %ld 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;
        FATAL1("Failed to write exit code to pipe: %d\n", err);
      }
      LOG_INFO("ExitCodeHandler thread wrote %ld bytes to fd %ld\n", result,
               exit_code_fd);
      LOG_INFO("ExitCodeHandler thread removing process %ld from list\n",
               process);
      ProcessInfoList::RemoveProcess(process);
    }
  }

  static void HandleInterruptMsg() {
    ASSERT(items_[0].handle == interrupt_out_);
    ASSERT(items_[0].waitfor == MX_SOCKET_READABLE);
    ASSERT((items_[0].pending & MX_SOCKET_READABLE) != 0);
    while (true) {
      Message msg;
      size_t actual = 0;
      LOG_INFO("ExitCodeHandler thread reading interrupt message\n");
      mx_status_t status =
          mx_socket_read(interrupt_out_, 0, &msg, sizeof(msg), &actual);
      if (status == MX_ERR_SHOULD_WAIT) {
        LOG_INFO("ExitCodeHandler thread done reading interrupt messages\n");
        return;
      }
      if (status < 0) {
        FATAL1("Failed to read exit handler interrupt handle: %s\n",
               mx_status_get_string(status));
      }
      if (actual < sizeof(msg)) {
        FATAL1("Short read from exit handler interrupt handle: %ld\n", actual);
      }
      switch (msg.command) {
        case Message::kShutdown:
          LOG_INFO("ExitCodeHandler thread got shutdown message\n");
          do_shutdown_ = true;
          break;
        case Message::kAdd:
          LOG_INFO("ExitCodeHandler thread got add message: %ld\n", msg.handle);
          AddItem(msg.handle);
          break;
      }
    }
  }

  static void AddItem(mx_handle_t h) {
    if (item_count_ == item_capacity_) {
      item_capacity_ = item_capacity_ + (item_capacity_ >> 1);
      items_ =
          reinterpret_cast<mx_wait_item_t*>(realloc(items_, item_capacity_));
      items_to_remove_ = reinterpret_cast<intptr_t*>(
          realloc(items_to_remove_, item_capacity_));
    }
    LOG_INFO("ExitCodeHandler thread adding item %ld at %ld\n", h, item_count_);
    items_[item_count_].handle = h;
    items_[item_count_].waitfor = MX_TASK_TERMINATED;
    items_[item_count_].pending = MX_SIGNAL_NONE;
    item_count_++;
  }

  static void RemoveItem(intptr_t idx) {
    LOG_INFO("ExitCodeHandler thread removing item %ld at %ld\n",
             items_[idx].handle, idx);
    ASSERT(idx != 0);
    const intptr_t last = item_count_ - 1;
    items_[idx].handle = MX_HANDLE_INVALID;
    items_[idx].waitfor = MX_SIGNAL_NONE;
    items_[idx].pending = MX_SIGNAL_NONE;
    if (idx != last) {
      items_[idx] = items_[last];
    }
    item_count_--;
  }

  // Interrupt channel.
  static mx_handle_t interrupt_in_;
  static mx_handle_t interrupt_out_;

  // Accessed only by the ExitCodeHandler thread.
  static mx_wait_item_t* items_;
  static intptr_t* items_to_remove_;
  static intptr_t item_count_;
  static intptr_t item_capacity_;

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

  DISALLOW_ALLOCATION();
  DISALLOW_IMPLICIT_CONSTRUCTORS(ExitCodeHandler);
};

mx_handle_t ExitCodeHandler::interrupt_in_ = MX_HANDLE_INVALID;
mx_handle_t ExitCodeHandler::interrupt_out_ = MX_HANDLE_INVALID;
mx_wait_item_t* ExitCodeHandler::items_ = NULL;
intptr_t* ExitCodeHandler::items_to_remove_ = NULL;
intptr_t ExitCodeHandler::item_count_ = 0;
intptr_t ExitCodeHandler::item_capacity_ = 0;

bool ExitCodeHandler::do_shutdown_ = false;
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() {
  mx_info_task_stats_t task_stats;
  mx_handle_t process = mx_process_self();
  mx_status_t status = mx_object_get_info(
      process, MX_INFO_TASK_STATS, &task_stats, sizeof(task_stats), NULL, NULL);
  if (status != MX_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) {
  // input not needed.
  IOHandle* in_iohandle = reinterpret_cast<IOHandle*>(in);
  in_iohandle->Close();
  in_iohandle->Release();
  in_iohandle = NULL;

  IOHandle* out_iohandle = reinterpret_cast<IOHandle*>(out);
  IOHandle* err_iohandle = reinterpret_cast<IOHandle*>(err);
  IOHandle* exit_iohandle = reinterpret_cast<IOHandle*>(exit_event);
  IOHandleScope out_ioscope(out_iohandle);
  IOHandleScope err_ioscope(err_iohandle);
  IOHandleScope exit_ioscope(exit_iohandle);

  // 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.
  mx_handle_t port;
  mx_status_t status = mx_port_create(MX_PORT_OPT_V2, &port);
  if (status != MX_OK) {
    Log::PrintErr("Process::Wait: mx_port_create failed: %s\n",
                  mx_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)) {
    mx_port_packet_t pkt;
    status =
        mx_port_wait(port, MX_TIME_INFINITE, reinterpret_cast<void*>(&pkt), 0);
    if (status != MX_OK) {
      Log::PrintErr("Process::Wait: mx_port_wait failed: %s\n",
                    mx_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 {
      Log::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.
  mx_handle_t process = static_cast<mx_handle_t>(pid);
  mx_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);
  // mx_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 mx_task_kill if we know id is a process handle, and we only
  // know that for sure if it's in our list.
  mx_handle_t process = static_cast<mx_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;
  }
  mx_status_t status = mx_task_kill(process);
  if (status != MX_OK) {
    LOG_ERR("mx_task_kill failed: %s\n", mx_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(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)
      : 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_arguments_count_ = arguments_length + 1;

    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]);

    // Set up a launchpad.
    launchpad_t* lp = NULL;
    mx_status_t status = SetupLaunchpad(&lp);
    if (status != MX_OK) {
      close(exit_pipe_fds[0]);
      close(exit_pipe_fds[1]);
      return status;
    }
    ASSERT(lp != NULL);

    // Launch it.
    LOG_INFO("ProcessStarter: Start() Calling launchpad_start\n");
    mx_handle_t process = MX_HANDLE_INVALID;
    const char* errormsg = NULL;
    status = launchpad_go(lp, &process, &errormsg);
    lp = NULL;  // launchpad_go() calls launchpad_destroy() on the launchpad.
    if (status < 0) {
      LOG_INFO("ProcessStarter: Start() launchpad_start failed\n");
      const intptr_t kMaxMessageSize = 256;
      close(exit_pipe_fds[0]);
      close(exit_pipe_fds[1]);
      char* message = DartUtils::ScopedCString(kMaxMessageSize);
      snprintf(message, kMaxMessageSize, "%s:%d: launchpad_start failed: %s\n",
               __FILE__, __LINE__, errormsg);
      *os_error_message_ = message;
      return status;
    }

    LOG_INFO("ProcessStarter: Start() adding %ld to list with exit_pipe %d\n",
             process, exit_pipe_fds[1]);
    ProcessInfoList::AddProcess(process, exit_pipe_fds[1]);
    ExitCodeHandler::Start();
    ExitCodeHandler::Add(process);

    // 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:
#define CHECK_FOR_ERROR(status, msg)                                           \
  if (status < 0) {                                                            \
    const intptr_t kMaxMessageSize = 256;                                      \
    char* message = DartUtils::ScopedCString(kMaxMessageSize);                 \
    snprintf(message, kMaxMessageSize, "%s:%d: %s: %s\n", __FILE__, __LINE__,  \
             msg, mx_status_get_string(status));                               \
    *os_error_message_ = message;                                              \
    return status;                                                             \
  }

  mx_status_t SetupLaunchpad(launchpad_t** launchpad) {
    // Set up a vmo for the binary.
    mx_handle_t binary_vmo = launchpad_vmo_from_file(path_);
    CHECK_FOR_ERROR(binary_vmo, "launchpad_vmo_from_file");

    // Run the child process in the same "job".
    mx_handle_t job = MX_HANDLE_INVALID;
    mx_status_t status =
        mx_handle_duplicate(mx_job_default(), MX_RIGHT_SAME_RIGHTS, &job);
    if (status != MX_OK) {
      mx_handle_close(binary_vmo);
    }
    CHECK_FOR_ERROR(status, "mx_handle_duplicate");

    // Set up the launchpad.
    launchpad_t* lp = NULL;
    launchpad_create(job, program_arguments_[0], &lp);
    launchpad_set_args(lp, program_arguments_count_, program_arguments_);
    launchpad_set_environ(lp, program_environment_);
    launchpad_clone(lp, LP_CLONE_MXIO_NAMESPACE);
    // TODO(zra): Use the supplied working directory when launchpad adds an
    // API to set it.
    launchpad_clone(lp, LP_CLONE_MXIO_CWD);
    launchpad_add_pipe(lp, &write_out_, 0);
    launchpad_add_pipe(lp, &read_in_, 1);
    launchpad_add_pipe(lp, &read_err_, 2);
    launchpad_add_vdso_vmo(lp);
    launchpad_elf_load(lp, binary_vmo);
    launchpad_load_vdso(lp, MX_HANDLE_INVALID);
    *launchpad = lp;
    return MX_OK;
  }

#undef CHECK_FOR_ERROR

  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_;
  intptr_t program_arguments_count_;
  char** program_environment_;

  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(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(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)

#endif  // !defined(DART_IO_DISABLED)
