// 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 <errno.h>  // NOLINT
#include <fcntl.h>  // NOLINT
#include <unistd.h>  // NOLINT
#include <sys/ioctl.h>  // NOLINT

#include "bin/fdutils.h"

#include "platform/signal_blocker.h"


namespace dart {
namespace bin {

bool FDUtils::SetCloseOnExec(intptr_t fd) {
  intptr_t status;
  status = NO_RETRY_EXPECTED(fcntl(fd, F_GETFD));
  if (status < 0) {
    return false;
  }
  status |= FD_CLOEXEC;
  if (NO_RETRY_EXPECTED(fcntl(fd, F_SETFD, status)) < 0) {
    return false;
  }
  return true;
}


static bool SetBlockingHelper(intptr_t fd, bool blocking) {
  intptr_t status;
  status = NO_RETRY_EXPECTED(fcntl(fd, F_GETFL));
  if (status < 0) {
    return false;
  }
  status = blocking ? (status & ~O_NONBLOCK) : (status | O_NONBLOCK);
  if (NO_RETRY_EXPECTED(fcntl(fd, F_SETFL, status)) < 0) {
    return false;
  }
  return true;
}


bool FDUtils::SetNonBlocking(intptr_t fd) {
  return SetBlockingHelper(fd, false);
}


bool FDUtils::SetBlocking(intptr_t fd) {
  return SetBlockingHelper(fd, true);
}


bool FDUtils::IsBlocking(intptr_t fd, bool* is_blocking) {
  intptr_t status;
  status = NO_RETRY_EXPECTED(fcntl(fd, F_GETFL));
  if (status < 0) {
    return false;
  }
  *is_blocking = (status & O_NONBLOCK) == 0;
  return true;
}


intptr_t FDUtils::AvailableBytes(intptr_t fd) {
  int available;  // ioctl for FIONREAD expects an 'int*' argument.
  int result = NO_RETRY_EXPECTED(ioctl(fd, FIONREAD, &available));
  if (result < 0) {
    return result;
  }
#ifdef DEBUG
  ASSERT(available >= 0);
#endif
  return static_cast<intptr_t>(available);
}


ssize_t FDUtils::ReadFromBlocking(int fd, void* buffer, size_t count) {
#ifdef DEBUG
  bool is_blocking = false;
  ASSERT(FDUtils::IsBlocking(fd, &is_blocking));
  ASSERT(is_blocking);
#endif
  size_t remaining = count;
  char* buffer_pos = reinterpret_cast<char*>(buffer);
  while (remaining > 0) {
    ssize_t bytes_read = TEMP_FAILURE_RETRY(read(fd, buffer_pos, remaining));
    if (bytes_read == 0) {
      return count - remaining;
    } else if (bytes_read == -1) {
      ASSERT(EAGAIN == EWOULDBLOCK);
      // Error code EWOULDBLOCK should only happen for non blocking
      // file descriptors.
      ASSERT(errno != EWOULDBLOCK);
      return -1;
    } else {
      ASSERT((bytes_read > 0));
      remaining -= bytes_read;
      buffer_pos += bytes_read;
    }
  }
  return count;
}


ssize_t FDUtils::WriteToBlocking(int fd, const void* buffer, size_t count) {
#ifdef DEBUG
  bool is_blocking = false;
  ASSERT(FDUtils::IsBlocking(fd, &is_blocking));
  ASSERT(is_blocking);
#endif
  size_t remaining = count;
  char* buffer_pos = const_cast<char*>(reinterpret_cast<const char*>(buffer));
  while (remaining > 0) {
    ssize_t bytes_written =
        TEMP_FAILURE_RETRY(write(fd, buffer_pos, remaining));
    if (bytes_written == 0) {
      return count - remaining;
    } else if (bytes_written == -1) {
      ASSERT(EAGAIN == EWOULDBLOCK);
      // Error code EWOULDBLOCK should only happen for non blocking
      // file descriptors.
      ASSERT(errno != EWOULDBLOCK);
      return -1;
    } else {
      ASSERT(bytes_written > 0);
      remaining -= bytes_written;
      buffer_pos += bytes_written;
    }
  }
  return count;
}

}  // namespace bin
}  // namespace dart

#endif  // defined(TARGET_OS_MACOS)
