// 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(DART_HOST_OS_ANDROID)

#include "bin/fdutils.h"

#include <errno.h>      // NOLINT
#include <fcntl.h>      // NOLINT
#include <sys/ioctl.h>  // NOLINT
#include <unistd.h>     // NOLINT

#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) {
    perror("fcntl(F_GETFD) failed");
    return false;
  }
  status |= FD_CLOEXEC;
  if (NO_RETRY_EXPECTED(fcntl(fd, F_SETFD, status)) < 0) {
    perror("fcntl(F_SETFD, FD_CLOEXEC) failed");
    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) {
    perror("fcntl(F_GETFL) failed");
    return false;
  }
  status = blocking ? (status & ~O_NONBLOCK) : (status | O_NONBLOCK);
  if (NO_RETRY_EXPECTED(fcntl(fd, F_SETFL, status)) < 0) {
    perror("fcntl(F_SETFL, O_NONBLOCK) failed");
    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;
  }
  ASSERT(available >= 0);
  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;
}

void FDUtils::SaveErrorAndClose(intptr_t fd) {
  int err = errno;
  close(fd);
  errno = err;
}

}  // namespace bin
}  // namespace dart

#endif  // defined(DART_HOST_OS_ANDROID)
