Summary: A *.cpp file header in LLDB (and in LLDB) should like this: ``` //===-- TestUtilities.cpp -------------------------------------------------===// ``` However in LLDB most of our source files have arbitrary changes to this format and these changes are spreading through LLDB as folks usually just use the existing source files as templates for their new files (most notably the unnecessary editor language indicator `-*- C++ -*-` is spreading and in every review someone is pointing out that this is wrong, resulting in people pointing out that this is done in the same way in other files). This patch removes most of these inconsistencies including the editor language indicators, all the different missing/additional '-' characters, files that center the file name, missing trailing `===//` (mostly caused by clang-format breaking the line). Reviewers: aprantl, espindola, jfb, shafik, JDevlieghere Reviewed By: JDevlieghere Subscribers: dexonsmith, wuzish, emaste, sdardis, nemanjai, kbarton, MaskRay, atanasyan, arphaman, jfb, abidh, jsji, JDevlieghere, usaxena95, lldb-commits Tags: #lldb Differential Revision: https://reviews.llvm.org/D73258
237 lines
6.2 KiB
C++
237 lines
6.2 KiB
C++
//===-- Terminal.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/Terminal.h"
|
|
|
|
#include "lldb/Host/Config.h"
|
|
#include "lldb/Host/PosixApi.h"
|
|
#include "llvm/ADT/STLExtras.h"
|
|
|
|
#include <fcntl.h>
|
|
#include <signal.h>
|
|
|
|
#if LLDB_ENABLE_TERMIOS
|
|
#include <termios.h>
|
|
#endif
|
|
|
|
using namespace lldb_private;
|
|
|
|
bool Terminal::IsATerminal() const { return m_fd >= 0 && ::isatty(m_fd); }
|
|
|
|
bool Terminal::SetEcho(bool enabled) {
|
|
if (FileDescriptorIsValid()) {
|
|
#if LLDB_ENABLE_TERMIOS
|
|
if (IsATerminal()) {
|
|
struct termios fd_termios;
|
|
if (::tcgetattr(m_fd, &fd_termios) == 0) {
|
|
bool set_corectly = false;
|
|
if (enabled) {
|
|
if (fd_termios.c_lflag & ECHO)
|
|
set_corectly = true;
|
|
else
|
|
fd_termios.c_lflag |= ECHO;
|
|
} else {
|
|
if (fd_termios.c_lflag & ECHO)
|
|
fd_termios.c_lflag &= ~ECHO;
|
|
else
|
|
set_corectly = true;
|
|
}
|
|
|
|
if (set_corectly)
|
|
return true;
|
|
return ::tcsetattr(m_fd, TCSANOW, &fd_termios) == 0;
|
|
}
|
|
}
|
|
#endif // #if LLDB_ENABLE_TERMIOS
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool Terminal::SetCanonical(bool enabled) {
|
|
if (FileDescriptorIsValid()) {
|
|
#if LLDB_ENABLE_TERMIOS
|
|
if (IsATerminal()) {
|
|
struct termios fd_termios;
|
|
if (::tcgetattr(m_fd, &fd_termios) == 0) {
|
|
bool set_corectly = false;
|
|
if (enabled) {
|
|
if (fd_termios.c_lflag & ICANON)
|
|
set_corectly = true;
|
|
else
|
|
fd_termios.c_lflag |= ICANON;
|
|
} else {
|
|
if (fd_termios.c_lflag & ICANON)
|
|
fd_termios.c_lflag &= ~ICANON;
|
|
else
|
|
set_corectly = true;
|
|
}
|
|
|
|
if (set_corectly)
|
|
return true;
|
|
return ::tcsetattr(m_fd, TCSANOW, &fd_termios) == 0;
|
|
}
|
|
}
|
|
#endif // #if LLDB_ENABLE_TERMIOS
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// Default constructor
|
|
TerminalState::TerminalState()
|
|
: m_tty(), m_tflags(-1),
|
|
#if LLDB_ENABLE_TERMIOS
|
|
m_termios_up(),
|
|
#endif
|
|
m_process_group(-1) {
|
|
}
|
|
|
|
// Destructor
|
|
TerminalState::~TerminalState() {}
|
|
|
|
void TerminalState::Clear() {
|
|
m_tty.Clear();
|
|
m_tflags = -1;
|
|
#if LLDB_ENABLE_TERMIOS
|
|
m_termios_up.reset();
|
|
#endif
|
|
m_process_group = -1;
|
|
}
|
|
|
|
// Save the current state of the TTY for the file descriptor "fd" and if
|
|
// "save_process_group" is true, attempt to save the process group info for the
|
|
// TTY.
|
|
bool TerminalState::Save(int fd, bool save_process_group) {
|
|
m_tty.SetFileDescriptor(fd);
|
|
if (m_tty.IsATerminal()) {
|
|
#if LLDB_ENABLE_POSIX
|
|
m_tflags = ::fcntl(fd, F_GETFL, 0);
|
|
#endif
|
|
#if LLDB_ENABLE_TERMIOS
|
|
if (m_termios_up == nullptr)
|
|
m_termios_up.reset(new struct termios);
|
|
int err = ::tcgetattr(fd, m_termios_up.get());
|
|
if (err != 0)
|
|
m_termios_up.reset();
|
|
#endif // #if LLDB_ENABLE_TERMIOS
|
|
#if LLDB_ENABLE_POSIX
|
|
if (save_process_group)
|
|
m_process_group = ::tcgetpgrp(0);
|
|
else
|
|
m_process_group = -1;
|
|
#endif
|
|
} else {
|
|
m_tty.Clear();
|
|
m_tflags = -1;
|
|
#if LLDB_ENABLE_TERMIOS
|
|
m_termios_up.reset();
|
|
#endif
|
|
m_process_group = -1;
|
|
}
|
|
return IsValid();
|
|
}
|
|
|
|
// Restore the state of the TTY using the cached values from a previous call to
|
|
// Save().
|
|
bool TerminalState::Restore() const {
|
|
#if LLDB_ENABLE_POSIX
|
|
if (IsValid()) {
|
|
const int fd = m_tty.GetFileDescriptor();
|
|
if (TFlagsIsValid())
|
|
fcntl(fd, F_SETFL, m_tflags);
|
|
|
|
#if LLDB_ENABLE_TERMIOS
|
|
if (TTYStateIsValid())
|
|
tcsetattr(fd, TCSANOW, m_termios_up.get());
|
|
#endif // #if LLDB_ENABLE_TERMIOS
|
|
|
|
if (ProcessGroupIsValid()) {
|
|
// Save the original signal handler.
|
|
void (*saved_sigttou_callback)(int) = nullptr;
|
|
saved_sigttou_callback = (void (*)(int))signal(SIGTTOU, SIG_IGN);
|
|
// Set the process group
|
|
tcsetpgrp(fd, m_process_group);
|
|
// Restore the original signal handler.
|
|
signal(SIGTTOU, saved_sigttou_callback);
|
|
}
|
|
return true;
|
|
}
|
|
#endif
|
|
return false;
|
|
}
|
|
|
|
// Returns true if this object has valid saved TTY state settings that can be
|
|
// used to restore a previous state.
|
|
bool TerminalState::IsValid() const {
|
|
return m_tty.FileDescriptorIsValid() &&
|
|
(TFlagsIsValid() || TTYStateIsValid());
|
|
}
|
|
|
|
// Returns true if m_tflags is valid
|
|
bool TerminalState::TFlagsIsValid() const { return m_tflags != -1; }
|
|
|
|
// Returns true if m_ttystate is valid
|
|
bool TerminalState::TTYStateIsValid() const {
|
|
#if LLDB_ENABLE_TERMIOS
|
|
return m_termios_up != nullptr;
|
|
#else
|
|
return false;
|
|
#endif
|
|
}
|
|
|
|
// Returns true if m_process_group is valid
|
|
bool TerminalState::ProcessGroupIsValid() const {
|
|
return static_cast<int32_t>(m_process_group) != -1;
|
|
}
|
|
|
|
// Constructor
|
|
TerminalStateSwitcher::TerminalStateSwitcher() : m_currentState(UINT32_MAX) {}
|
|
|
|
// Destructor
|
|
TerminalStateSwitcher::~TerminalStateSwitcher() {}
|
|
|
|
// Returns the number of states that this switcher contains
|
|
uint32_t TerminalStateSwitcher::GetNumberOfStates() const {
|
|
return llvm::array_lengthof(m_ttystates);
|
|
}
|
|
|
|
// Restore the state at index "idx".
|
|
//
|
|
// Returns true if the restore was successful, false otherwise.
|
|
bool TerminalStateSwitcher::Restore(uint32_t idx) const {
|
|
const uint32_t num_states = GetNumberOfStates();
|
|
if (idx >= num_states)
|
|
return false;
|
|
|
|
// See if we already are in this state?
|
|
if (m_currentState < num_states && (idx == m_currentState) &&
|
|
m_ttystates[idx].IsValid())
|
|
return true;
|
|
|
|
// Set the state to match the index passed in and only update the current
|
|
// state if there are no errors.
|
|
if (m_ttystates[idx].Restore()) {
|
|
m_currentState = idx;
|
|
return true;
|
|
}
|
|
|
|
// We failed to set the state. The tty state was invalid or not initialized.
|
|
return false;
|
|
}
|
|
|
|
// Save the state at index "idx" for file descriptor "fd" and save the process
|
|
// group if requested.
|
|
//
|
|
// Returns true if the restore was successful, false otherwise.
|
|
bool TerminalStateSwitcher::Save(uint32_t idx, int fd,
|
|
bool save_process_group) {
|
|
const uint32_t num_states = GetNumberOfStates();
|
|
if (idx < num_states)
|
|
return m_ttystates[idx].Save(fd, save_process_group);
|
|
return false;
|
|
}
|