// Copyright (c) 2017, 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.

#if !defined(DART_IO_DISABLED)

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

#include "bin/sync_socket.h"

#include <errno.h>  // NOLINT

#include "bin/fdutils.h"
#include "bin/socket_base.h"
#include "platform/signal_blocker.h"

namespace dart {
namespace bin {

bool SynchronousSocket::Initialize() {
  // Nothing to do on Android.
  return true;
}


static intptr_t Create(const RawAddr& addr) {
  intptr_t fd;
  intptr_t type = SOCK_STREAM;
  fd = NO_RETRY_EXPECTED(socket(addr.ss.ss_family, type, 0));
  if (fd < 0) {
    return -1;
  }
  return fd;
}


static intptr_t Connect(intptr_t fd, const RawAddr& addr) {
  intptr_t result = TEMP_FAILURE_RETRY(
      connect(fd, &addr.addr, SocketAddress::GetAddrLength(addr)));
  if (result == 0) {
    return fd;
  }
  ASSERT(errno != EINPROGRESS);
  FDUtils::FDUtils::SaveErrorAndClose(fd);
  return -1;
}


intptr_t SynchronousSocket::CreateConnect(const RawAddr& addr) {
  intptr_t fd = Create(addr);
  if (fd < 0) {
    return fd;
  }
  return Connect(fd, addr);
}


intptr_t SynchronousSocket::Available(intptr_t fd) {
  return SocketBase::Available(fd);
}


intptr_t SynchronousSocket::GetPort(intptr_t fd) {
  return SocketBase::GetPort(fd);
}


SocketAddress* SynchronousSocket::GetRemotePeer(intptr_t fd, intptr_t* port) {
  return SocketBase::GetRemotePeer(fd, port);
}


intptr_t SynchronousSocket::Read(intptr_t fd,
                                 void* buffer,
                                 intptr_t num_bytes) {
  return SocketBase::Read(fd, buffer, num_bytes, SocketBase::kSync);
}


intptr_t SynchronousSocket::Write(intptr_t fd,
                                  const void* buffer,
                                  intptr_t num_bytes) {
  return SocketBase::Write(fd, buffer, num_bytes, SocketBase::kSync);
}


void SynchronousSocket::ShutdownRead(intptr_t fd) {
  VOID_NO_RETRY_EXPECTED(shutdown(fd, SHUT_RD));
}


void SynchronousSocket::ShutdownWrite(intptr_t fd) {
  VOID_NO_RETRY_EXPECTED(shutdown(fd, SHUT_WR));
}


void SynchronousSocket::Close(intptr_t fd) {
  return SocketBase::Close(fd);
}

}  // namespace bin
}  // namespace dart

#endif  // defined(HOST_OS_ANDROID)

#endif  // !defined(DART_IO_DISABLED)
