//===-- PseudoTerminal.cpp ------------------------------------------------===//
//
// 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 "lldb/Host/PseudoTerminal.h"
#include "lldb/Host/Config.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/Errno.h"
#include <cassert>
#include <limits.h>
#include <mutex>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if defined(TIOCSCTTY)
#include <sys/ioctl.h>
#endif

#include "lldb/Host/PosixApi.h"

#if defined(__ANDROID__)
int posix_openpt(int flags);
#endif

using namespace lldb_private;

// PseudoTerminal constructor
PseudoTerminal::PseudoTerminal()
    : m_primary_fd(invalid_fd), m_secondary_fd(invalid_fd) {}

// Destructor
//
// The destructor will close the primary and secondary file descriptors if they
// are valid and ownership has not been released using the
// ReleasePrimaryFileDescriptor() or the ReleaseSaveFileDescriptor() member
// functions.
PseudoTerminal::~PseudoTerminal() {
  ClosePrimaryFileDescriptor();
  CloseSecondaryFileDescriptor();
}

// Close the primary file descriptor if it is valid.
void PseudoTerminal::ClosePrimaryFileDescriptor() {
  if (m_primary_fd >= 0) {
    ::close(m_primary_fd);
    m_primary_fd = invalid_fd;
  }
}

// Close the secondary file descriptor if it is valid.
void PseudoTerminal::CloseSecondaryFileDescriptor() {
  if (m_secondary_fd >= 0) {
    ::close(m_secondary_fd);
    m_secondary_fd = invalid_fd;
  }
}

llvm::Error PseudoTerminal::OpenFirstAvailablePrimary(int oflag) {
#if LLDB_ENABLE_POSIX
  // Open the primary side of a pseudo terminal
  m_primary_fd = ::posix_openpt(oflag);
  if (m_primary_fd < 0) {
    return llvm::errorCodeToError(
        std::error_code(errno, std::generic_category()));
  }

  // Grant access to the secondary pseudo terminal
  if (::grantpt(m_primary_fd) < 0) {
    std::error_code EC(errno, std::generic_category());
    ClosePrimaryFileDescriptor();
    return llvm::errorCodeToError(EC);
  }

  // Clear the lock flag on the secondary pseudo terminal
  if (::unlockpt(m_primary_fd) < 0) {
    std::error_code EC(errno, std::generic_category());
    ClosePrimaryFileDescriptor();
    return llvm::errorCodeToError(EC);
  }

  return llvm::Error::success();
#else
  return llvm::errorCodeToError(llvm::errc::not_supported);
#endif
}

llvm::Error PseudoTerminal::OpenSecondary(int oflag) {
  CloseSecondaryFileDescriptor();

  std::string name = GetSecondaryName();
  m_secondary_fd = llvm::sys::RetryAfterSignal(-1, ::open, name.c_str(), oflag);
  if (m_secondary_fd >= 0)
    return llvm::Error::success();

  return llvm::errorCodeToError(
      std::error_code(errno, std::generic_category()));
}

std::string PseudoTerminal::GetSecondaryName() const {
  assert(m_primary_fd >= 0);
#if HAVE_PTSNAME_R
  char buf[PATH_MAX];
  buf[0] = '\0';
  int r = ptsname_r(m_primary_fd, buf, sizeof(buf));
  (void)r;
  assert(r == 0);
  return buf;
#else
  static std::mutex mutex;
  std::lock_guard<std::mutex> guard(mutex);
  const char *r = ptsname(m_primary_fd);
  assert(r != nullptr);
  return r;
#endif
}

llvm::Expected<lldb::pid_t> PseudoTerminal::Fork() {
#if LLDB_ENABLE_POSIX
  if (llvm::Error Err = OpenFirstAvailablePrimary(O_RDWR | O_CLOEXEC))
    return std::move(Err);

  pid_t pid = ::fork();
  if (pid < 0) {
    return llvm::errorCodeToError(
        std::error_code(errno, std::generic_category()));
  }
  if (pid > 0) {
    // Parent process.
    return pid;
  }

  // Child Process
  ::setsid();

  if (llvm::Error Err = OpenSecondary(O_RDWR))
    return std::move(Err);

  // Primary FD should have O_CLOEXEC set, but let's close it just in
  // case...
  ClosePrimaryFileDescriptor();

#if defined(TIOCSCTTY)
  // Acquire the controlling terminal
  if (::ioctl(m_secondary_fd, TIOCSCTTY, (char *)0) < 0) {
    return llvm::errorCodeToError(
        std::error_code(errno, std::generic_category()));
  }
#endif
  // Duplicate all stdio file descriptors to the secondary pseudo terminal
  for (int fd : {STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO}) {
    if (::dup2(m_secondary_fd, fd) != fd) {
      return llvm::errorCodeToError(
          std::error_code(errno, std::generic_category()));
    }
  }
#endif
  return 0;
}

// The primary file descriptor accessor. This object retains ownership of the
// primary file descriptor when this accessor is used. Use
// ReleasePrimaryFileDescriptor() if you wish this object to release ownership
// of the primary file descriptor.
//
// Returns the primary file descriptor, or -1 if the primary file descriptor is
// not currently valid.
int PseudoTerminal::GetPrimaryFileDescriptor() const { return m_primary_fd; }

// The secondary file descriptor accessor.
//
// Returns the secondary file descriptor, or -1 if the secondary file descriptor
// is not currently valid.
int PseudoTerminal::GetSecondaryFileDescriptor() const {
  return m_secondary_fd;
}

// Release ownership of the primary pseudo terminal file descriptor without
// closing it. The destructor for this class will close the primary file
// descriptor if the ownership isn't released using this call and the primary
// file descriptor has been opened.
int PseudoTerminal::ReleasePrimaryFileDescriptor() {
  // Release ownership of the primary pseudo terminal file descriptor without
  // closing it. (the destructor for this class will close it otherwise!)
  int fd = m_primary_fd;
  m_primary_fd = invalid_fd;
  return fd;
}

// Release ownership of the secondary pseudo terminal file descriptor without
// closing it. The destructor for this class will close the secondary file
// descriptor if the ownership isn't released using this call and the secondary
// file descriptor has been opened.
int PseudoTerminal::ReleaseSecondaryFileDescriptor() {
  // Release ownership of the secondary pseudo terminal file descriptor without
  // closing it (the destructor for this class will close it otherwise!)
  int fd = m_secondary_fd;
  m_secondary_fd = invalid_fd;
  return fd;
}
