1 //===-- TTYState.cpp --------------------------------------------*- C++ -*-===//
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-exception
7 //===----------------------------------------------------------------------===//
9 // Created by Greg Clayton on 3/26/07.
11 //===----------------------------------------------------------------------===//
15 #include <sys/signal.h>
19 : m_fd(-1), m_tflags(-1), m_ttystateErr(-1), m_processGroup(-1) {}
21 TTYState::~TTYState() = default;
23 bool TTYState::GetTTYState(int fd
, bool saveProcessGroup
) {
24 if (fd
>= 0 && ::isatty(fd
)) {
26 m_tflags
= fcntl(fd
, F_GETFL
, 0);
27 m_ttystateErr
= tcgetattr(fd
, &m_ttystate
);
29 m_processGroup
= tcgetpgrp(0);
38 return m_ttystateErr
== 0;
41 bool TTYState::SetTTYState() const {
44 fcntl(m_fd
, F_SETFL
, m_tflags
);
47 tcsetattr(m_fd
, TCSANOW
, &m_ttystate
);
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 group
54 tcsetpgrp(m_fd
, m_processGroup
);
55 // Restore the original signal handler.
56 signal(SIGTTOU
, saved_sigttou_callback
);
63 TTYStateSwitcher::TTYStateSwitcher() : m_currentState(~0) {}
65 TTYStateSwitcher::~TTYStateSwitcher() = default;
67 bool TTYStateSwitcher::GetState(uint32_t idx
, int fd
, bool saveProcessGroup
) {
68 if (ValidStateIndex(idx
))
69 return m_ttystates
[idx
].GetTTYState(fd
, saveProcessGroup
);
73 bool TTYStateSwitcher::SetState(uint32_t idx
) const {
74 if (!ValidStateIndex(idx
))
77 // See if we already are in this state?
78 if (ValidStateIndex(m_currentState
) && (idx
== m_currentState
) &&
79 m_ttystates
[idx
].IsValid())
82 // Set the state to match the index passed in and only update the
83 // current state if there are no errors.
84 if (m_ttystates
[idx
].SetTTYState()) {
89 // We failed to set the state. The tty state was invalid or not