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

#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(HOST_OS_LINUX)
