1 //===-- TTYState.cpp --------------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // Created by Greg Clayton on 3/26/07.
12 //===----------------------------------------------------------------------===//
16 #include <sys/signal.h>
20 : m_fd(-1), m_tflags(-1), m_ttystateErr(-1), m_processGroup(-1) {}
22 TTYState::~TTYState() {}
24 bool TTYState::GetTTYState(int fd, bool saveProcessGroup) {
25 if (fd >= 0 && ::isatty(fd)) {
27 m_tflags = fcntl(fd, F_GETFL, 0);
28 m_ttystateErr = tcgetattr(fd, &m_ttystate);
30 m_processGroup = tcgetpgrp(0);
39 return m_ttystateErr == 0;
42 bool TTYState::SetTTYState() const {
46 result = fcntl(m_fd, F_SETFL, m_tflags);
49 result = tcsetattr(m_fd, TCSANOW, &m_ttystate);
51 if (ProcessGroupValid()) {
52 // Save the original signal handler.
53 void (*saved_sigttou_callback)(int) = NULL;
54 saved_sigttou_callback = (void (*)(int))signal(SIGTTOU, SIG_IGN);
55 // Set the process group
56 result = tcsetpgrp(m_fd, m_processGroup);
57 // Restore the original signal handler.
58 signal(SIGTTOU, saved_sigttou_callback);
65 TTYStateSwitcher::TTYStateSwitcher() : m_currentState(~0) {}
67 TTYStateSwitcher::~TTYStateSwitcher() {}
69 bool TTYStateSwitcher::GetState(uint32_t idx, int fd, bool saveProcessGroup) {
70 if (ValidStateIndex(idx))
71 return m_ttystates[idx].GetTTYState(fd, saveProcessGroup);
75 bool TTYStateSwitcher::SetState(uint32_t idx) const {
76 if (!ValidStateIndex(idx))
79 // See if we already are in this state?
80 if (ValidStateIndex(m_currentState) && (idx == m_currentState) &&
81 m_ttystates[idx].IsValid())
84 // Set the state to match the index passed in and only update the
85 // current state if there are no errors.
86 if (m_ttystates[idx].SetTTYState()) {
91 // We failed to set the state. The tty state was invalid or not