//===-- Named semaphore implementation for Linux --------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "src/semaphore/linux/semaphore.h"

#include "hdr/errno_macros.h"
#include "hdr/fcntl_macros.h"
#include "src/__support/CPP/array.h"
#include "src/__support/CPP/limits.h"
#include "src/__support/CPP/new.h"
#include "src/__support/CPP/string_view.h"
#include "src/__support/OSUtil/linux/syscall_wrappers/close.h"
#include "src/__support/OSUtil/linux/syscall_wrappers/ftruncate.h"
#include "src/__support/OSUtil/linux/syscall_wrappers/getrandom.h"
#include "src/__support/OSUtil/linux/syscall_wrappers/link.h"
#include "src/__support/OSUtil/linux/syscall_wrappers/mmap.h"
#include "src/__support/OSUtil/linux/syscall_wrappers/munmap.h"
#include "src/__support/OSUtil/linux/syscall_wrappers/open.h"
#include "src/__support/OSUtil/linux/syscall_wrappers/unlink.h"
#include "src/__support/ctype_utils.h"
#include "src/__support/error_or.h"
#include "src/__support/macros/config.h"
#include "src/string/memory_utils/inline_memcpy.h"
#include "src/sys/mman/linux/shm_common.h"

#include <linux/mman.h> // PROT_READ, PROT_WRITE, MAP_SHARED

namespace LIBC_NAMESPACE_DECL {

namespace {

// define SEM_VALUE_MAX as INT_MAX
constexpr unsigned int SEM_VALUE_MAX =
    static_cast<unsigned int>(cpp::numeric_limits<int>::max());

// Named semaphores are backed by files in /dev/shm/.
// a prefix "sem." is added to avoid name collision.
constexpr cpp::string_view SEM_PREFIX = "/dev/shm/sem.";

// use temporary file to solve data race and guarantee atomic publish.
// Temporary file use different prefix.
constexpr cpp::string_view SEM_TMP_PREFIX = "/dev/shm/sem.tmp_";

// 8 random bytes from getrandom() produce a 16 character hex suffix, giving
// 2^64 possible temp names to avoid collision.
constexpr size_t RANDOM_SUFFIX_BYTES = 8;
constexpr size_t RANDOM_SUFFIX_HEX_LEN = RANDOM_SUFFIX_BYTES * 2;

// fixed-size buffer for the temp path.
using TmpPath =
    cpp::array<char, SEM_TMP_PREFIX.size() + RANDOM_SUFFIX_HEX_LEN + 1>;

// O_NOFOLLOW prevents symlink attacks to /dev/shm/. O_CLOEXEC ensures the
// fd is not leaked to child processes across exec.
constexpr int DEFAULT_OFLAGS = O_NOFOLLOW | O_CLOEXEC;

ErrorOr<TmpPath> generate_tmp_path() {
  // fill out 8 random bytes.
  cpp::array<uint8_t, RANDOM_SUFFIX_BYTES> rand_bytes{};
  auto ret = linux_syscalls::getrandom(rand_bytes.data(), rand_bytes.size(), 0);
  if (!ret.has_value())
    return Error(ret.error());

  TmpPath path;
  inline_memcpy(path.data(), SEM_TMP_PREFIX.data(), SEM_TMP_PREFIX.size());

  // Encode each random byte as two hex digits, and fill out tmp path.
  char *dst = path.data() + SEM_TMP_PREFIX.size();
  for (size_t i = 0; i < RANDOM_SUFFIX_BYTES; ++i) {
    *dst++ = internal::int_to_b36_char(rand_bytes[i] >> 4);
    *dst++ = internal::int_to_b36_char(rand_bytes[i] & 0xf);
  }
  *dst = '\0';
  return path;
}

// map an open semaphore fd into memory.
ErrorOr<Semaphore *> map_semaphore(int fd) {
  auto mmap_or = linux_syscalls::mmap(
      nullptr, sizeof(Semaphore), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
  linux_syscalls::close(fd);

  if (!mmap_or.has_value())
    return Error(mmap_or.error());

  return reinterpret_cast<Semaphore *>(mmap_or.value());
}

// open an existing named semaphore file and map it.
ErrorOr<Semaphore *> open_existing(const char *path) {
  auto fd_or = linux_syscalls::open(path, O_RDWR | DEFAULT_OFLAGS, 0);
  if (!fd_or.has_value())
    return Error(fd_or.error());
  return map_semaphore(fd_or.value());
}

} // anonymous namespace

ErrorOr<Semaphore *> Semaphore::open(const char *name, int oflag, mode_t mode,
                                     unsigned int value) {
  auto path_or = shm_common::translate_name<SEM_PREFIX>(name);
  if (!path_or.has_value())
    return Error(path_or.error());

  // open an existing semaphore.
  if (!(oflag & O_CREAT))
    return open_existing(path_or->data());

  // check semaphore value.
  if (value > SEM_VALUE_MAX)
    return Error(EINVAL);

  // two step creation:
  // 1. create and fully initialize a temporary file.
  // 2. link() it and publish to the final path atomically.
  // This ensures no other process can observe a partially-initialized
  // semaphore through the final path. If link() fails with EEXIST and
  // O_EXCL is not set, fall back to opening the existing semaphore.

  auto tmp_or = generate_tmp_path();
  if (!tmp_or.has_value())
    return Error(tmp_or.error());

  // if two process happen to map the same random tmp_path, though rare
  // in 2^64 namespace, one succees and the other return EEXIST.
  auto fd_or = linux_syscalls::open(
      tmp_or->data(), O_RDWR | O_CREAT | O_EXCL | DEFAULT_OFLAGS, mode);
  if (!fd_or.has_value())
    return Error(fd_or.error());

  int fd = fd_or.value();

  // resizing temporary semaphore backing file.
  auto trunc_or =
      linux_syscalls::ftruncate(fd, static_cast<off_t>(sizeof(Semaphore)));
  if (!trunc_or.has_value()) {
    linux_syscalls::close(fd);
    linux_syscalls::unlink(tmp_or->data());
    return Error(trunc_or.error());
  }

  // map_semaphore closes the fd.
  auto sem_or = map_semaphore(fd);
  if (!sem_or.has_value()) {
    linux_syscalls::unlink(tmp_or->data());
    return Error(sem_or.error());
  }

  Semaphore *sem = sem_or.value();
  new (sem) Semaphore(value);

  // atomically publish the fully initialized semaphore.
  auto link_or = linux_syscalls::link(tmp_or->data(), path_or->data());

  // temp file is no longer needed.
  linux_syscalls::unlink(tmp_or->data());

  // link() succees
  if (link_or.has_value())
    return sem;

  // link() fail, clean up the mapping.
  linux_syscalls::munmap(sem, sizeof(Semaphore));

  // if the name already exists and O_EXCL was not set, open existing.
  if (link_or.error() == EEXIST && !(oflag & O_EXCL))
    return open_existing(path_or->data());

  return Error(link_or.error());
}

int Semaphore::close(Semaphore *sem) {
  auto result = linux_syscalls::munmap(sem, sizeof(Semaphore));
  if (!result.has_value())
    return result.error();
  return 0;
}

int Semaphore::unlink(const char *name) {
  auto path_or = shm_common::translate_name<SEM_PREFIX>(name);
  if (!path_or.has_value())
    return path_or.error();

  auto result = linux_syscalls::unlink(path_or->data());
  if (!result.has_value())
    return result.error();
  return 0;
}

} // namespace LIBC_NAMESPACE_DECL
