// 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/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 dart::Mutex* mutex_;
};


ProcessInfo* ProcessInfoList::active_processes_ = NULL;
dart::Mutex* ProcessInfoList::mutex_ = new dart::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 = dart::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(dart::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(dart::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 dart::Monitor* monitor_;
};


bool ExitCodeHandler::running_ = false;
int ExitCodeHandler::process_count_ = 0;
bool ExitCodeHandler::terminate_done_ = false;
dart::Monitor* ExitCodeHandler::monitor_ = new dart::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);
}


int Process::Start(const char* path,
                   char* arguments[],
                   intptr_t arguments_length,
                   const char* working_directory,
                   char* environment[],
                   intptr_t environment_length,
                   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];  // Pipe for stdout to child process.
  int read_err[2];  // Pipe for stderr to child process.
  int write_out[2];  // Pipe for stdin to child process.
  int exec_control[2];  // Pipe to get the result from exec.
  int result;

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

  result = TEMP_FAILURE_RETRY(pipe(read_err));
  if (result < 0) {
    SetChildOsErrorMessage(os_error_message);
    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(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]);

  result = TEMP_FAILURE_RETRY(pipe(exec_control));
  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(exec_control[0]);
  FDUtils::SetCloseOnExec(exec_control[1]);

  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]));
    VOID_TEMP_FAILURE_RETRY(close(exec_control[0]));
    VOID_TEMP_FAILURE_RETRY(close(exec_control[1]));
    Log::PrintErr("fcntl failed: %s\n", *os_error_message);
    return errno;
  }

  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(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]));
    VOID_TEMP_FAILURE_RETRY(close(exec_control[0]));
    VOID_TEMP_FAILURE_RETRY(close(exec_control[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);
    }

    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;

  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]));
  int child_errno;
  int bytes_read = -1;
  ASSERT(sizeof(child_errno) == sizeof(errno));
  bytes_read =
      FDUtils::ReadFromBlocking(
          exec_control[0], &child_errno, sizeof(child_errno));
  if (bytes_read == sizeof(child_errno)) {
    static const int kMaxMessageSize = 256;
    char* message = static_cast<char*>(malloc(kMaxMessageSize));
    bytes_read = FDUtils::ReadFromBlocking(exec_control[0],
                                           message,
                                           kMaxMessageSize);
    message[kMaxMessageSize - 1] = '\0';
    *os_error_message = message;
  }
  VOID_TEMP_FAILURE_RETRY(close(exec_control[0]));

  // Return error code if any failures.
  if (bytes_read != 0) {
    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)
