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

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

#include "bin/process.h"

#include <errno.h>  // NOLINT
#include <fcntl.h>  // NOLINT
#include <poll.h>  // NOLINT
#include <signal.h>  // NOLINT
#include <stdio.h>  // NOLINT
#include <stdlib.h>  // NOLINT
#include <string.h>  // NOLINT
#include <unistd.h>  // NOLINT

#include "bin/fdutils.h"
#include "bin/lockers.h"
#include "bin/log.h"
#include "bin/thread.h"

#include "platform/signal_blocker.h"


extern char **environ;


namespace dart {
namespace bin {

// 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(pid_t pid, intptr_t fd) : pid_(pid), fd_(fd) { }
  ~ProcessInfo() {
    int closed = TEMP_FAILURE_RETRY(close(fd_));
    if (closed != 0) {
      FATAL("Failed to close process exit code pipe");
    }
  }
  pid_t pid() { return pid_; }
  intptr_t fd() { return fd_; }
  ProcessInfo* next() { return next_; }
  void set_next(ProcessInfo* info) { next_ = info; }

 private:
  pid_t pid_;
  intptr_t fd_;
  ProcessInfo* next_;
};


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


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


  static void RemoveProcess(pid_t pid) {
    MutexLocker locker(mutex_);
    ProcessInfo* prev = NULL;
    ProcessInfo* current = active_processes_;
    while (current != NULL) {
      if (current->pid() == pid) {
        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_;
};


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 ProcessStarted() {
    // Multiple isolates could be starting processes at the same
    // time. Make sure that only one ExitCodeHandler thread exists.
    MonitorLocker locker(monitor_);
    process_count_++;

    monitor_->Notify();

    if (running_) {
      return;
    }

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

    running_ = true;
  }

  static void TerminateExitCodeThread() {
    MonitorLocker locker(monitor_);

    if (!running_) {
      return;
    }

    // Set terminate_done_ to false, so we can use it as a guard for our
    // monitor.
    running_ = false;

    // Fork to wake up waitpid.
    if (TEMP_FAILURE_RETRY(fork()) == 0) {
      exit(0);
    }

    monitor_->Notify();

    while (!terminate_done_) {
      monitor_->Wait(Monitor::kNoTimeout);
    }
  }

 private:
  // Entry point for the separate exit code handler thread started by
  // the ExitCodeHandler.
  static void ExitCodeHandlerEntry(uword param) {
    pid_t pid = 0;
    int status = 0;
    while (true) {
      {
        MonitorLocker locker(monitor_);
        while (running_ && process_count_ == 0) {
          monitor_->Wait(Monitor::kNoTimeout);
        }
        if (!running_) {
          terminate_done_ = true;
          monitor_->Notify();
          return;
        }
      }

      if ((pid = TEMP_FAILURE_RETRY(wait(&status))) > 0) {
        int exit_code = 0;
        int negative = 0;
        if (WIFEXITED(status)) {
          exit_code = WEXITSTATUS(status);
        }
        if (WIFSIGNALED(status)) {
          exit_code = WTERMSIG(status);
          negative = 1;
        }
        intptr_t exit_code_fd = ProcessInfoList::LookupProcessExitFd(pid);
        if (exit_code_fd != 0) {
          int message[2] = { exit_code, negative };
          ssize_t result =
              FDUtils::WriteToBlocking(exit_code_fd, &message, sizeof(message));
          // If the process has been closed, the read end of the exit
          // pipe has been closed. It is therefore not a problem that
          // write fails with a broken pipe error. Other errors should
          // not happen.
          if (result != -1 && result != sizeof(message)) {
            FATAL("Failed to write entire process exit message");
          } else if (result == -1 && errno != EPIPE) {
            FATAL1("Failed to write exit code: %d", errno);
          }
          ProcessInfoList::RemoveProcess(pid);
          {
            MonitorLocker locker(monitor_);
            process_count_--;
          }
        }
      }
    }
  }

  static bool terminate_done_;
  static int process_count_;
  static bool running_;
  static Monitor* monitor_;
};


bool ExitCodeHandler::running_ = false;
int ExitCodeHandler::process_count_ = 0;
bool ExitCodeHandler::terminate_done_ = false;
Monitor* ExitCodeHandler::monitor_ = new Monitor();


static void SetChildOsErrorMessage(char** os_error_message) {
  const int kBufferSize = 1024;
  char error_message[kBufferSize];
  strerror_r(errno, error_message, kBufferSize);
  *os_error_message = strdup(error_message);
}


static void ReportChildError(int exec_control_fd) {
  // In the case of failure in the child process write the errno and
  // the OS error message to the exec control pipe and exit.
  int child_errno = errno;
  const int kBufferSize = 1024;
  char os_error_message[kBufferSize];
  strerror_r(errno, os_error_message, kBufferSize);
  ASSERT(sizeof(child_errno) == sizeof(errno));
  int bytes_written =
      FDUtils::WriteToBlocking(
          exec_control_fd, &child_errno, sizeof(child_errno));
  if (bytes_written == sizeof(child_errno)) {
    FDUtils::WriteToBlocking(
        exec_control_fd, os_error_message, strlen(os_error_message) + 1);
  }
  VOID_TEMP_FAILURE_RETRY(close(exec_control_fd));
  exit(1);
}


static void ReportPid(int exec_control_fd, int pid) {
  // In the case of starting a detached process the actual pid of that process
  // is communicated using the exec control pipe.
  int bytes_written =
      FDUtils::WriteToBlocking(exec_control_fd, &pid, sizeof(pid));
  ASSERT(bytes_written == sizeof(int));
  USE(bytes_written);
}


static void ReadChildError(int exec_control_fd, char** error_message) {
  const int kMaxMessageSize = 256;
  char* message = static_cast<char*>(malloc(kMaxMessageSize));
  if (message != NULL) {
    FDUtils::ReadFromBlocking(exec_control_fd, message, kMaxMessageSize);
    message[kMaxMessageSize - 1] = '\0';
    *error_message = message;
  } else {
    static const char* no_message = "Cannot get error message, out of memory";
    *error_message = const_cast<char*>(no_message);
  }
}


int Process::Start(const char* path,
                   char* arguments[],
                   intptr_t arguments_length,
                   const char* working_directory,
                   char* environment[],
                   intptr_t environment_length,
                   bool detach,
                   intptr_t* in,
                   intptr_t* out,
                   intptr_t* err,
                   intptr_t* id,
                   intptr_t* exit_event,
                   char** os_error_message) {
  pid_t pid;
  int read_in[2] = {-1, -1};  // Pipe for stdout to child process.
  int read_err[2] = {-1, -1};  // Pipe for stderr to child process.
  int write_out[2] = {-1, -1};  // Pipe for stdin to child process.
  int exec_control[2] = {-1, -1};  // Pipe to get the result from exec.
  int result;

  result = TEMP_FAILURE_RETRY(pipe(exec_control));
  if (result < 0) {
    SetChildOsErrorMessage(os_error_message);
    Log::PrintErr("Error pipe creation failed: %s\n", *os_error_message);
    return errno;
  }
  FDUtils::SetCloseOnExec(exec_control[0]);
  FDUtils::SetCloseOnExec(exec_control[1]);

  // For a detached process the pipe to connect stdout is still used for
  // signaling when to do the first fork.
  result = TEMP_FAILURE_RETRY(pipe(read_in));
  if (result < 0) {
    SetChildOsErrorMessage(os_error_message);
    VOID_TEMP_FAILURE_RETRY(close(exec_control[0]));
    VOID_TEMP_FAILURE_RETRY(close(exec_control[1]));
    Log::PrintErr("Error pipe creation failed: %s\n", *os_error_message);
    return errno;
  }
  FDUtils::SetCloseOnExec(read_in[0]);

  // For detached processes the pipe to connect stderr and stdin are not used.
  if (!detach) {
    result = TEMP_FAILURE_RETRY(pipe(read_err));
    if (result < 0) {
      SetChildOsErrorMessage(os_error_message);
      VOID_TEMP_FAILURE_RETRY(close(exec_control[0]));
      VOID_TEMP_FAILURE_RETRY(close(exec_control[1]));
      VOID_TEMP_FAILURE_RETRY(close(read_in[0]));
      VOID_TEMP_FAILURE_RETRY(close(read_in[1]));
      Log::PrintErr("Error pipe creation failed: %s\n", *os_error_message);
      return errno;
    }
    FDUtils::SetCloseOnExec(read_err[0]);

    result = TEMP_FAILURE_RETRY(pipe(write_out));
    if (result < 0) {
      SetChildOsErrorMessage(os_error_message);
      VOID_TEMP_FAILURE_RETRY(close(exec_control[0]));
      VOID_TEMP_FAILURE_RETRY(close(exec_control[1]));
      VOID_TEMP_FAILURE_RETRY(close(read_in[0]));
      VOID_TEMP_FAILURE_RETRY(close(read_in[1]));
      VOID_TEMP_FAILURE_RETRY(close(read_err[0]));
      VOID_TEMP_FAILURE_RETRY(close(read_err[1]));
      Log::PrintErr("Error pipe creation failed: %s\n", *os_error_message);
      return errno;
    }
    FDUtils::SetCloseOnExec(write_out[1]);
  }

  char** program_arguments = new char*[arguments_length + 2];
  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;

  char** program_environment = NULL;
  if (environment != NULL) {
    program_environment = new char*[environment_length + 1];
    for (int i = 0; i < environment_length; i++) {
      program_environment[i] = environment[i];
    }
    program_environment[environment_length] = NULL;
  }

  pid = TEMP_FAILURE_RETRY(fork());
  if (pid < 0) {
    SetChildOsErrorMessage(os_error_message);
    delete[] program_arguments;
    VOID_TEMP_FAILURE_RETRY(close(exec_control[0]));
    VOID_TEMP_FAILURE_RETRY(close(exec_control[1]));
    VOID_TEMP_FAILURE_RETRY(close(read_in[0]));
    VOID_TEMP_FAILURE_RETRY(close(read_in[1]));
    if (detach) {
      VOID_TEMP_FAILURE_RETRY(close(read_err[0]));
      VOID_TEMP_FAILURE_RETRY(close(read_err[1]));
      VOID_TEMP_FAILURE_RETRY(close(write_out[0]));
      VOID_TEMP_FAILURE_RETRY(close(write_out[1]));
    }
    return errno;
  } else if (pid == 0) {
    // Wait for parent process before setting up the child process.
    char msg;
    int bytes_read = FDUtils::ReadFromBlocking(read_in[0], &msg, sizeof(msg));
    if (bytes_read != sizeof(msg)) {
      perror("Failed receiving notification message");
      exit(1);
    }
    if (detach) {
      // For a detached process the pipe to connect stdout is only used for
      // signaling when to do the first fork.
      VOID_TEMP_FAILURE_RETRY(close(read_in[0]));
      VOID_TEMP_FAILURE_RETRY(close(read_in[1]));
      // Fork once more to start a new session.
      pid = TEMP_FAILURE_RETRY(fork());
      if (pid < 0) {
        ReportChildError(exec_control[1]);
      } else if (pid == 0) {
        // Start a new session.
        if (TEMP_FAILURE_RETRY(setsid()) == -1) {
          ReportChildError(exec_control[1]);
        } else {
          // Do a final fork to not be the session leader.
          pid = TEMP_FAILURE_RETRY(fork());
          if (pid < 0) {
            ReportChildError(exec_control[1]);
          } else if (pid == 0) {
            // Close all open file descriptors except for exec_control[1].
            int max_fds = sysconf(_SC_OPEN_MAX);
            if (max_fds == -1) max_fds = _POSIX_OPEN_MAX;
            for (int fd = 0; fd < max_fds; fd++) {
              if (fd != exec_control[1]) {
                VOID_TEMP_FAILURE_RETRY(close(fd));
              }
            }

            // Re-open stdin, stdout and stderr and connect them to /dev/null.
            // The loop above should already have closed all of them, so
            // creating new file descriptors should start at STDIN_FILENO.
            int fd = TEMP_FAILURE_RETRY(open("/dev/null", O_RDWR));
            if (fd != STDIN_FILENO) {
              ReportChildError(exec_control[1]);
            }
            if (TEMP_FAILURE_RETRY(dup2(STDIN_FILENO, STDOUT_FILENO)) !=
                STDOUT_FILENO) {
              ReportChildError(exec_control[1]);
            }
            if (TEMP_FAILURE_RETRY(dup2(STDIN_FILENO, STDERR_FILENO)) !=
                STDERR_FILENO) {
              ReportChildError(exec_control[1]);
            }

            // Report the final PID and do the exec.
            ReportPid(exec_control[1], getpid());  // getpid cannot fail.
            VOID_TEMP_FAILURE_RETRY(
                execvp(path, const_cast<char* const*>(program_arguments)));
            ReportChildError(exec_control[1]);
          } else {
            exit(0);
          }
        }
      } else {
        exit(0);
      }
    } else {
      VOID_TEMP_FAILURE_RETRY(close(write_out[1]));
      VOID_TEMP_FAILURE_RETRY(close(read_in[0]));
      VOID_TEMP_FAILURE_RETRY(close(read_err[0]));
      VOID_TEMP_FAILURE_RETRY(close(exec_control[0]));

      if (TEMP_FAILURE_RETRY(dup2(write_out[0], STDIN_FILENO)) == -1) {
        ReportChildError(exec_control[1]);
      }
      VOID_TEMP_FAILURE_RETRY(close(write_out[0]));

      if (TEMP_FAILURE_RETRY(dup2(read_in[1], STDOUT_FILENO)) == -1) {
        ReportChildError(exec_control[1]);
      }
      VOID_TEMP_FAILURE_RETRY(close(read_in[1]));

      if (TEMP_FAILURE_RETRY(dup2(read_err[1], STDERR_FILENO)) == -1) {
        ReportChildError(exec_control[1]);
      }
      VOID_TEMP_FAILURE_RETRY(close(read_err[1]));

      if (working_directory != NULL &&
          TEMP_FAILURE_RETRY(chdir(working_directory)) == -1) {
        ReportChildError(exec_control[1]);
      }

      if (program_environment != NULL) {
        environ = program_environment;
      }

      VOID_TEMP_FAILURE_RETRY(
          execvp(path, const_cast<char* const*>(program_arguments)));

      ReportChildError(exec_control[1]);
    }
  }

  // Be sure to listen for exit-codes, now we have a child-process.
  ExitCodeHandler::ProcessStarted();

  // The arguments and environment for the spawned process are not needed
  // any longer.
  delete[] program_arguments;
  delete[] program_environment;

  if (!detach) {
    int event_fds[2];
    result = TEMP_FAILURE_RETRY(pipe(event_fds));
    if (result < 0) {
      SetChildOsErrorMessage(os_error_message);
      VOID_TEMP_FAILURE_RETRY(close(read_in[0]));
      VOID_TEMP_FAILURE_RETRY(close(read_in[1]));
      VOID_TEMP_FAILURE_RETRY(close(read_err[0]));
      VOID_TEMP_FAILURE_RETRY(close(read_err[1]));
      VOID_TEMP_FAILURE_RETRY(close(write_out[0]));
      VOID_TEMP_FAILURE_RETRY(close(write_out[1]));
      Log::PrintErr("Error pipe creation failed: %s\n", *os_error_message);
      return errno;
    }
    FDUtils::SetCloseOnExec(event_fds[0]);
    FDUtils::SetCloseOnExec(event_fds[1]);

    ProcessInfoList::AddProcess(pid, event_fds[1]);
    *exit_event = event_fds[0];
    FDUtils::SetNonBlocking(event_fds[0]);
  }

  // Notify child process to start.
  char msg = '1';
  result = FDUtils::WriteToBlocking(read_in[1], &msg, sizeof(msg));
  if (result != sizeof(msg)) {
    perror("Failed sending notification message");
  }

  // Read exec result from child. If no data is returned the exec was
  // successful and the exec call closed the pipe. Otherwise the errno
  // is written to the pipe.
  VOID_TEMP_FAILURE_RETRY(close(exec_control[1]));
  bool failed = false;
  int child_errno;
  int bytes_read = -1;
  ASSERT(sizeof(child_errno) == sizeof(errno));
  if (!detach) {
    // Read exec result from child. If no data is returned the exec was
    // successful and the exec call closed the pipe. Otherwise the errno
    // is written to the pipe.
    bytes_read =
        FDUtils::ReadFromBlocking(
            exec_control[0], &child_errno, sizeof(child_errno));
    if (bytes_read == sizeof(child_errno)) {
      ReadChildError(exec_control[0], os_error_message);
      failed = true;
    }
  } else {
    // Read exec result from child. If only pid data is returned the exec was
    // successful and the exec call closed the pipe. Otherwise the errno
    // is written to the pipe as well.
    int result[2];
    ASSERT(sizeof(int) == sizeof(child_errno));
    bytes_read =
        FDUtils::ReadFromBlocking(
            exec_control[0], result, sizeof(result));
    if (bytes_read == sizeof(int)) {
      pid = result[0];
    } else if (bytes_read == 2 * sizeof(int)) {
      pid = result[0];
      child_errno = result[1];
      ReadChildError(exec_control[0], os_error_message);
      failed = true;
    }
  }
  VOID_TEMP_FAILURE_RETRY(close(exec_control[0]));

  // Return error code if any failures.
  if (failed) {
    if (!detach) {
      VOID_TEMP_FAILURE_RETRY(close(read_in[0]));
      VOID_TEMP_FAILURE_RETRY(close(read_in[1]));
      VOID_TEMP_FAILURE_RETRY(close(read_err[0]));
      VOID_TEMP_FAILURE_RETRY(close(read_err[1]));
      VOID_TEMP_FAILURE_RETRY(close(write_out[0]));
      VOID_TEMP_FAILURE_RETRY(close(write_out[1]));

      // Since exec() failed, we're not interested in the exit code.
      // We close the reading side of the exit code pipe here.
      // GetProcessExitCodes will get a broken pipe error when it tries to write
      // to the writing side of the pipe and it will ignore the error.
      VOID_TEMP_FAILURE_RETRY(close(*exit_event));
      *exit_event = -1;
    }
    if (bytes_read == -1) {
      return errno;  // Read failed.
    } else {
      return child_errno;  // Exec failed.
    }
  }

  FDUtils::SetNonBlocking(read_in[0]);
  *in = read_in[0];
  VOID_TEMP_FAILURE_RETRY(close(read_in[1]));
  FDUtils::SetNonBlocking(write_out[1]);
  *out = write_out[1];
  VOID_TEMP_FAILURE_RETRY(close(write_out[0]));
  FDUtils::SetNonBlocking(read_err[0]);
  *err = read_err[0];
  VOID_TEMP_FAILURE_RETRY(close(read_err[1]));

  *id = pid;
  return 0;
}


class BufferList: public BufferListBase {
 public:
  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);
      size_t block_size = dart::Utils::Minimum(free_size_, available);
      ssize_t bytes = TEMP_FAILURE_RETRY(read(
          fd,
          reinterpret_cast<void*>(FreeSpaceAddress()),
          block_size));
      if (bytes < 0) return false;
      data_size_ += bytes;
      free_size_ -= bytes;
      available -= bytes;
    }
    return true;
  }
};


static bool CloseProcessBuffers(struct pollfd fds[3]) {
  int e = errno;
  VOID_TEMP_FAILURE_RETRY(close(fds[0].fd));
  VOID_TEMP_FAILURE_RETRY(close(fds[1].fd));
  VOID_TEMP_FAILURE_RETRY(close(fds[2].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) {
  // Close input to the process right away.
  VOID_TEMP_FAILURE_RETRY(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;

  struct pollfd fds[3];
  fds[0].fd = out;
  fds[1].fd = err;
  fds[2].fd = exit_event;

  for (int i = 0; i < 3; i++) {
    fds[i].events = POLLIN;
  }

  int alive = 3;
  while (alive > 0) {
    // Blocking call waiting for events from the child process.
    if (TEMP_FAILURE_RETRY(poll(fds, alive, -1)) <= 0) {
      return CloseProcessBuffers(fds);
    }

    // Process incoming data.
    int current_alive = alive;
    for (int i = 0; i < current_alive; i++) {
      intptr_t avail;
      if (fds[i].revents & POLLIN) {
        avail = FDUtils::AvailableBytes(fds[i].fd);
        // On Mac OS POLLIN can be set with zero available
        // bytes. POLLHUP is most likely also set in this case.
        if (avail > 0) {
          if (fds[i].fd == out) {
            if (!out_data.Read(out, avail)) {
              return CloseProcessBuffers(fds);
            }
          } else if (fds[i].fd == err) {
            if (!err_data.Read(err, avail)) {
              return CloseProcessBuffers(fds);
            }
          } else if (fds[i].fd == exit_event) {
            if (avail == 8) {
              intptr_t b = TEMP_FAILURE_RETRY(read(fds[i].fd,
                                                   exit_code_data.bytes, 8));
              if (b != 8) {
                return CloseProcessBuffers(fds);
              }
            }
          } else {
            UNREACHABLE();
          }
        }
      }
      if (fds[i].revents & POLLHUP ||
          ((fds[i].revents & POLLIN) && avail == 0)) {
        VOID_TEMP_FAILURE_RETRY(close(fds[i].fd));
        alive--;
        if (i < alive) {
          fds[i] = fds[alive];
        }
      }
    }
  }

  // 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) exit_code = -exit_code;
  result->set_exit_code(exit_code);

  return true;
}


static int SignalMap(intptr_t id) {
  switch (static_cast<ProcessSignals>(id)) {
    case kSighup: return SIGHUP;
    case kSigint: return SIGINT;
    case kSigquit: return SIGQUIT;
    case kSigill: return SIGILL;
    case kSigtrap: return SIGTRAP;
    case kSigabrt: return SIGABRT;
    case kSigbus: return SIGBUS;
    case kSigfpe: return SIGFPE;
    case kSigkill: return SIGKILL;
    case kSigusr1: return SIGUSR1;
    case kSigsegv: return SIGSEGV;
    case kSigusr2: return SIGUSR2;
    case kSigpipe: return SIGPIPE;
    case kSigalrm: return SIGALRM;
    case kSigterm: return SIGTERM;
    case kSigchld: return SIGCHLD;
    case kSigcont: return SIGCONT;
    case kSigstop: return SIGSTOP;
    case kSigtstp: return SIGTSTP;
    case kSigttin: return SIGTTIN;
    case kSigttou: return SIGTTOU;
    case kSigurg: return SIGURG;
    case kSigxcpu: return SIGXCPU;
    case kSigxfsz: return SIGXFSZ;
    case kSigvtalrm: return SIGVTALRM;
    case kSigprof: return SIGPROF;
    case kSigwinch: return SIGWINCH;
    case kSigpoll: return -1;
    case kSigsys: return SIGSYS;
  }
  return -1;
}


bool Process::Kill(intptr_t id, int signal) {
  return (TEMP_FAILURE_RETRY(kill(id, SignalMap(signal))) != -1);
}


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


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


static Mutex* signal_mutex = new Mutex();
static SignalInfo* signal_handlers = NULL;
static const int kSignalsCount = 7;
static const int kSignals[kSignalsCount] = {
  SIGHUP,
  SIGINT,
  SIGTERM,
  SIGUSR1,
  SIGUSR2,
  SIGWINCH,
  SIGQUIT  // Allow VMService to listen on SIGQUIT.
};


SignalInfo::~SignalInfo() {
  VOID_TEMP_FAILURE_RETRY(close(fd_));
}


static void SignalHandler(int signal) {
  MutexLocker lock(signal_mutex);
  const SignalInfo* handler = signal_handlers;
  while (handler != NULL) {
    if (handler->signal() == signal) {
      int value = 0;
      VOID_TEMP_FAILURE_RETRY(write(handler->fd(), &value, 1));
    }
    handler = handler->next();
  }
}


intptr_t Process::SetSignalHandler(intptr_t signal) {
  signal = SignalMap(signal);
  if (signal == -1) return -1;
  bool found = false;
  for (int i = 0; i < kSignalsCount; i++) {
    if (kSignals[i] == signal) {
      found = true;
      break;
    }
  }
  if (!found) return -1;
  int fds[2];
  if (NO_RETRY_EXPECTED(pipe(fds)) != 0) {
    return -1;
  }
  if (!FDUtils::SetCloseOnExec(fds[0]) ||
      !FDUtils::SetCloseOnExec(fds[1]) ||
      !FDUtils::SetNonBlocking(fds[0])) {
    VOID_TEMP_FAILURE_RETRY(close(fds[0]));
    VOID_TEMP_FAILURE_RETRY(close(fds[1]));
    return -1;
  }
  ThreadSignalBlocker blocker(kSignalsCount, kSignals);
  MutexLocker lock(signal_mutex);
  SignalInfo* handler = signal_handlers;
  bool listen = true;
  while (handler != NULL) {
    if (handler->signal() == signal) {
      listen = false;
      break;
    }
    handler = handler->next();
  }
  if (listen) {
    struct sigaction act;
    bzero(&act, sizeof(act));
    act.sa_handler = SignalHandler;
    sigemptyset(&act.sa_mask);
    for (int i = 0; i < kSignalsCount; i++) {
      sigaddset(&act.sa_mask, kSignals[i]);
    }
    intptr_t status = NO_RETRY_EXPECTED(sigaction(signal, &act, NULL));
    if (status < 0) {
      VOID_TEMP_FAILURE_RETRY(close(fds[0]));
      VOID_TEMP_FAILURE_RETRY(close(fds[1]));
      return -1;
    }
  }
  signal_handlers = new SignalInfo(fds[1], signal, signal_handlers);
  return fds[0];
}


void Process::ClearSignalHandler(intptr_t signal) {
  signal = SignalMap(signal);
  if (signal == -1) return;
  ThreadSignalBlocker blocker(kSignalsCount, kSignals);
  MutexLocker lock(signal_mutex);
  SignalInfo* handler = signal_handlers;
  bool unlisten = true;
  while (handler != NULL) {
    bool remove = false;
    if (handler->signal() == signal) {
      if (handler->port() == Dart_GetMainPortId()) {
        if (signal_handlers == handler) signal_handlers = handler->next();
        handler->Unlink();
        remove = true;
      } else {
        unlisten = false;
      }
    }
    SignalInfo* next = handler->next();
    if (remove) delete handler;
    handler = next;
  }
  if (unlisten) {
    struct sigaction act;
    bzero(&act, sizeof(act));
    act.sa_handler = SIG_DFL;
    VOID_NO_RETRY_EXPECTED(sigaction(signal, &act, NULL));
  }
}

}  // namespace bin
}  // namespace dart

#endif  // defined(TARGET_OS_MACOS)
