// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/memory/shared_memory.h"

#include <errno.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>

#include <limits>

#include "base/logging.h"

namespace base {

SharedMemoryCreateOptions::SharedMemoryCreateOptions()
    : name_deprecated(nullptr),
      open_existing_deprecated(false),
      size(0),
      executable(false),
      share_read_only(false) {}

SharedMemory::SharedMemory()
    : mapped_file_(-1),
      mapped_size_(0),
      memory_(NULL),
      read_only_(false),
      requested_size_(0) {
}

SharedMemory::SharedMemory(const SharedMemoryHandle& handle, bool read_only)
    : mapped_file_(handle.fd),
      mapped_size_(0),
      memory_(NULL),
      read_only_(read_only),
      requested_size_(0) {
}

SharedMemory::SharedMemory(const SharedMemoryHandle& handle,
                           bool read_only,
                           ProcessHandle process)
    : mapped_file_(handle.fd),
      mapped_size_(0),
      memory_(NULL),
      read_only_(read_only),
      requested_size_(0) {
  NOTREACHED();
}

SharedMemory::~SharedMemory() {
  Unmap();
  Close();
}

// static
bool SharedMemory::IsHandleValid(const SharedMemoryHandle& handle) {
  return handle.fd >= 0;
}

// static
SharedMemoryHandle SharedMemory::NULLHandle() {
  return SharedMemoryHandle();
}

// static
void SharedMemory::CloseHandle(const SharedMemoryHandle& handle) {
  DCHECK_GE(handle.fd, 0);
  if (close(handle.fd) < 0)
    DPLOG(ERROR) << "close";
}

// static
SharedMemoryHandle SharedMemory::DuplicateHandle(
    const SharedMemoryHandle& handle) {
  int duped_handle = HANDLE_EINTR(dup(handle.fd));
  if (duped_handle < 0)
    return base::SharedMemory::NULLHandle();
  return base::FileDescriptor(duped_handle, true);
}

bool SharedMemory::CreateAndMapAnonymous(size_t size) {
  // Untrusted code can't create descriptors or handles.
  return false;
}

bool SharedMemory::Create(const SharedMemoryCreateOptions& options) {
  // Untrusted code can't create descriptors or handles.
  return false;
}

bool SharedMemory::Delete(const std::string& name) {
  return false;
}

bool SharedMemory::Open(const std::string& name, bool read_only) {
  return false;
}

bool SharedMemory::MapAt(off_t offset, size_t bytes) {
  if (mapped_file_ == -1)
    return false;

  if (bytes > static_cast<size_t>(std::numeric_limits<int>::max()))
    return false;

  if (memory_)
    return false;

  memory_ = mmap(NULL, bytes, PROT_READ | (read_only_ ? 0 : PROT_WRITE),
                 MAP_SHARED, mapped_file_, offset);

  bool mmap_succeeded = memory_ != MAP_FAILED && memory_ != NULL;
  if (mmap_succeeded) {
    mapped_size_ = bytes;
    DCHECK_EQ(0U, reinterpret_cast<uintptr_t>(memory_) &
        (SharedMemory::MAP_MINIMUM_ALIGNMENT - 1));
  } else {
    memory_ = NULL;
  }

  return mmap_succeeded;
}

bool SharedMemory::Unmap() {
  if (memory_ == NULL)
    return false;

  if (munmap(memory_, mapped_size_) < 0)
    DPLOG(ERROR) << "munmap";
  memory_ = NULL;
  mapped_size_ = 0;
  return true;
}

SharedMemoryHandle SharedMemory::handle() const {
  return FileDescriptor(mapped_file_, false);
}

void SharedMemory::Close() {
  if (mapped_file_ > 0) {
    if (close(mapped_file_) < 0)
      DPLOG(ERROR) << "close";
    mapped_file_ = -1;
  }
}

bool SharedMemory::ShareToProcessCommon(ProcessHandle process,
                                        SharedMemoryHandle *new_handle,
                                        bool close_self,
                                        ShareMode share_mode) {
  if (share_mode == SHARE_READONLY) {
    // Untrusted code can't create descriptors or handles, which is needed to
    // drop permissions.
    return false;
  }
  const int new_fd = dup(mapped_file_);
  if (new_fd < 0) {
    DPLOG(ERROR) << "dup() failed.";
    return false;
  }

  new_handle->fd = new_fd;
  new_handle->auto_close = true;

  if (close_self) {
    Unmap();
    Close();
  }
  return true;
}

}  // namespace base
