// 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(TARGET_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 <mxio/util.h>
#include <pthread.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/epoll.h>
#include <unistd.h>

#include "bin/dartutils.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 == 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());
}


static bool ProcessWaitCleanup(intptr_t out,
                               intptr_t err,
                               intptr_t exit_event,
                               intptr_t epoll_fd) {
  int e = errno;
  VOID_NO_RETRY_EXPECTED(close(out));
  VOID_NO_RETRY_EXPECTED(close(err));
  VOID_NO_RETRY_EXPECTED(close(exit_event));
  VOID_NO_RETRY_EXPECTED(close(epoll_fd));
  errno = e;
  return false;
}


bool Process::Wait(intptr_t pid,
                   intptr_t in,
                   intptr_t out,
                   intptr_t err,
                   intptr_t exit_event,
                   ProcessResult* result) {
  VOID_NO_RETRY_EXPECTED(close(in));

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

  // The initial size passed to epoll_create is ignore on newer (>=
  // 2.6.8) Linux versions
  static const int kEpollInitialSize = 64;
  int epoll_fd = NO_RETRY_EXPECTED(epoll_create(kEpollInitialSize));
  if (epoll_fd == -1) {
    return ProcessWaitCleanup(out, err, exit_event, epoll_fd);
  }
  if (!FDUtils::SetCloseOnExec(epoll_fd)) {
    return ProcessWaitCleanup(out, err, exit_event, epoll_fd);
  }

  struct epoll_event event;
  event.events = EPOLLRDHUP | EPOLLIN;
  event.data.fd = out;
  int status = NO_RETRY_EXPECTED(
      epoll_ctl(epoll_fd, EPOLL_CTL_ADD, out, &event));
  if (status == -1) {
    return ProcessWaitCleanup(out, err, exit_event, epoll_fd);
  }
  event.data.fd = err;
  status = NO_RETRY_EXPECTED(
      epoll_ctl(epoll_fd, EPOLL_CTL_ADD, err, &event));
  if (status == -1) {
    return ProcessWaitCleanup(out, err, exit_event, epoll_fd);
  }
  event.data.fd = exit_event;
  status = NO_RETRY_EXPECTED(
      epoll_ctl(epoll_fd, EPOLL_CTL_ADD, exit_event, &event));
  if (status == -1) {
    return ProcessWaitCleanup(out, err, exit_event, epoll_fd);
  }
  intptr_t active = 3;

  static const intptr_t kMaxEvents = 16;
  struct epoll_event events[kMaxEvents];
  while (active > 0) {
    // TODO(US-109): When the epoll implementation is properly edge-triggered,
    // remove this sleep, which prevents the message queue from being
    // overwhelmed and leading to memory exhaustion.
    usleep(5000);
    intptr_t result = NO_RETRY_EXPECTED(
        epoll_wait(epoll_fd, events, kMaxEvents, -1));
    if ((result < 0) && (errno != EWOULDBLOCK)) {
      return ProcessWaitCleanup(out, err, exit_event, epoll_fd);
    }
    for (intptr_t i = 0; i < result; i++) {
      if ((events[i].events & EPOLLIN) != 0) {
        const intptr_t avail = FDUtils::AvailableBytes(events[i].data.fd);
        if (events[i].data.fd == out) {
          if (!out_data.Read(out, avail)) {
            return ProcessWaitCleanup(out, err, exit_event, epoll_fd);
          }
        } else if (events[i].data.fd == err) {
          if (!err_data.Read(err, avail)) {
            return ProcessWaitCleanup(out, err, exit_event, epoll_fd);
          }
        } else if (events[i].data.fd == exit_event) {
          if (avail == 8) {
            intptr_t b =
                NO_RETRY_EXPECTED(read(exit_event, exit_code_data.bytes, 8));
            if (b != 8) {
              return ProcessWaitCleanup(out, err, exit_event, epoll_fd);
            }
          }
        } else {
          UNREACHABLE();
        }
      }
      if ((events[i].events & (EPOLLHUP | EPOLLRDHUP)) != 0) {
        NO_RETRY_EXPECTED(close(events[i].data.fd));
        active--;
        VOID_NO_RETRY_EXPECTED(
            epoll_ctl(epoll_fd, EPOLL_CTL_DEL, events[i].data.fd, NULL));
      }
    }
  }
  VOID_NO_RETRY_EXPECTED(close(epoll_fd));

  // 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 != NO_ERROR) {
    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 != NO_ERROR) {
      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);

    *id_ = process;
    FDUtils::SetNonBlocking(read_in_);
    *in_ = read_in_;
    read_in_ = -1;
    FDUtils::SetNonBlocking(read_err_);
    *err_ = read_err_;
    read_err_ = -1;
    FDUtils::SetNonBlocking(write_out_);
    *out_ = write_out_;
    write_out_ = -1;
    FDUtils::SetNonBlocking(exit_pipe_fds[0]);
    *exit_event_ = 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 != NO_ERROR) {
      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_ROOT);
    // 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 NO_ERROR;
  }

#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) {
  UNIMPLEMENTED();
  return -1;
}


void Process::ClearSignalHandler(intptr_t signal) {
  UNIMPLEMENTED();
}

}  // namespace bin
}  // namespace dart

#endif  // defined(TARGET_OS_FUCHSIA)

#endif  // !defined(DART_IO_DISABLED)
