// 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/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_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 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_handle_wait_many: %ld items\n",
               item_count_);
      mx_status_t status =
          mx_handle_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_handle_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] = return_code;
      exit_message[1] = 0;  // Do not negate return_code.
      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 message pipe.
  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;
}


class BufferList : public BufferListBase {
 public:
  BufferList() {}

  bool Read(int fd, intptr_t available) {
    // Read all available bytes.
    while (available > 0) {
      if (free_size_ == 0) {
        Allocate();
      }
      ASSERT(free_size_ > 0);
      ASSERT(free_size_ <= kBufferSize);
      intptr_t block_size = dart::Utils::Minimum(free_size_, available);
      intptr_t bytes = NO_RETRY_EXPECTED(
          read(fd, reinterpret_cast<void*>(FreeSpaceAddress()), block_size));
      if (bytes < 0) {
        return false;
      }
      data_size_ += bytes;
      free_size_ -= bytes;
      available -= bytes;
    }
    return true;
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(BufferList);
};


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

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

  return true;
}


bool Process::Kill(intptr_t id, int signal) {
  errno = ENOSYS;
  return false;
}


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

    binary_vmo_ = MX_HANDLE_INVALID;
    launchpad_ = NULL;
  }

  ~ProcessStarter() {
    if (binary_vmo_ != MX_HANDLE_INVALID) {
      mx_handle_close(binary_vmo_);
    }
    if (launchpad_ != NULL) {
      launchpad_destroy(launchpad_);
    }
    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]);

    mx_status_t status = SetupLaunchpad();
    if (status != NO_ERROR) {
      close(exit_pipe_fds[0]);
      close(exit_pipe_fds[1]);
      return status;
    }

    LOG_INFO("ProcessStarter: Start() Calling launchpad_start\n");
    mx_handle_t process = launchpad_start(launchpad_);
    launchpad_destroy(launchpad_);
    launchpad_ = NULL;
    if (process < 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__, mx_status_get_string(process));
      *os_error_message_ = message;
      return process;
    }

    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() {
    mx_handle_t binary_vmo = launchpad_vmo_from_file(path_);
    CHECK_FOR_ERROR(binary_vmo, "launchpad_vmo_from_file");
    binary_vmo_ = binary_vmo;

    launchpad_t* lp;
    mx_status_t status;

    status = launchpad_create(0, program_arguments_[0], &lp);
    CHECK_FOR_ERROR(status, "launchpad_create");
    launchpad_ = lp;

    status =
        launchpad_arguments(lp, program_arguments_count_, program_arguments_);
    CHECK_FOR_ERROR(status, "launchpad_arguments");

    status = launchpad_environ(lp, program_environment_);
    CHECK_FOR_ERROR(status, "launchpad_environ");

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

    status = launchpad_clone_mxio_root(lp);
    CHECK_FOR_ERROR(status, "launchpad_clone_mxio_root");

    status = launchpad_add_pipe(lp, &write_out_, 0);
    CHECK_FOR_ERROR(status, "launchpad_add_pipe");

    status = launchpad_add_pipe(lp, &read_in_, 1);
    CHECK_FOR_ERROR(status, "launchpad_add_pipe");

    status = launchpad_add_pipe(lp, &read_err_, 2);
    CHECK_FOR_ERROR(status, "launchpad_add_pipe");

    status = launchpad_add_vdso_vmo(lp);
    CHECK_FOR_ERROR(status, "launchpad_add_vdso_vmo");

    status = launchpad_elf_load(lp, binary_vmo);
    CHECK_FOR_ERROR(status, "launchpad_elf_load");
    binary_vmo_ = MX_HANDLE_INVALID;  // launchpad_elf_load consumes the handle.

    status = launchpad_load_vdso(lp, MX_HANDLE_INVALID);
    CHECK_FOR_ERROR(status, "launchpad_load_vdso");

    status = launchpad_clone_mxio_cwd(lp);
    CHECK_FOR_ERROR(status, "launchpad_clone_mxio_cwd");

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

  mx_handle_t binary_vmo_;
  launchpad_t* launchpad_;

  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)
