// 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(0, &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)
