brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.5 KiB · d097bc8 Raw
93 lines · cpp
1//===-- TTYState.cpp --------------------------------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9//  Created by Greg Clayton on 3/26/07.10//11//===----------------------------------------------------------------------===//12 13#include "TTYState.h"14#include <fcntl.h>15#include <sys/signal.h>16#include <unistd.h>17 18TTYState::TTYState()19    : m_fd(-1), m_tflags(-1), m_ttystateErr(-1), m_processGroup(-1) {}20 21TTYState::~TTYState() = default;22 23bool TTYState::GetTTYState(int fd, bool saveProcessGroup) {24  if (fd >= 0 && ::isatty(fd)) {25    m_fd = fd;26    m_tflags = fcntl(fd, F_GETFL, 0);27    m_ttystateErr = tcgetattr(fd, &m_ttystate);28    if (saveProcessGroup)29      m_processGroup = tcgetpgrp(0);30    else31      m_processGroup = -1;32  } else {33    m_fd = -1;34    m_tflags = -1;35    m_ttystateErr = -1;36    m_processGroup = -1;37  }38  return m_ttystateErr == 0;39}40 41bool TTYState::SetTTYState() const {42  if (IsValid()) {43    if (TFlagsValid())44      fcntl(m_fd, F_SETFL, m_tflags);45 46    if (TTYStateValid())47      tcsetattr(m_fd, TCSANOW, &m_ttystate);48 49    if (ProcessGroupValid()) {50      // Save the original signal handler.51      void (*saved_sigttou_callback)(int) = NULL;52      saved_sigttou_callback = (void (*)(int))signal(SIGTTOU, SIG_IGN);53      // Set the process group54      tcsetpgrp(m_fd, m_processGroup);55      // Restore the original signal handler.56      signal(SIGTTOU, saved_sigttou_callback);57    }58    return true;59  }60  return false;61}62 63TTYStateSwitcher::TTYStateSwitcher() : m_currentState(~0) {}64 65TTYStateSwitcher::~TTYStateSwitcher() = default;66 67bool TTYStateSwitcher::GetState(uint32_t idx, int fd, bool saveProcessGroup) {68  if (ValidStateIndex(idx))69    return m_ttystates[idx].GetTTYState(fd, saveProcessGroup);70  return false;71}72 73bool TTYStateSwitcher::SetState(uint32_t idx) const {74  if (!ValidStateIndex(idx))75    return false;76 77  // See if we already are in this state?78  if (ValidStateIndex(m_currentState) && (idx == m_currentState) &&79      m_ttystates[idx].IsValid())80    return true;81 82  // Set the state to match the index passed in and only update the83  // current state if there are no errors.84  if (m_ttystates[idx].SetTTYState()) {85    m_currentState = idx;86    return true;87  }88 89  // We failed to set the state. The tty state was invalid or not90  // initialized.91  return false;92}93