Хотя я согласен с комментариями о том, что вы, как правило, должны доверять пользователям, он пытается ответить на вопрос, как я понял, прочитав комментарии (« Если моя программа работает в фоновом режиме,Командный терминал является работоспособным и работоспособным, но выходные данные программы скрывают пользовательский ввод и выводят подсказку").
Это не помешает запуску программы, но потоковая передача на std::cout
будет отброшенаТаким образом, программа может работать, не мешая пользователю.Перенаправление вывода в файл или канал все равно будет работать.
#define _POSIX_SOURCE
#include <iostream>
#include <stdexcept>
#include <stdio.h> // fileno
#include <unistd.h> // isatty
#include <signal.h> // signal
#include <fcntl.h> // fcntl
#include <termios.h> // tcgetattr/tcsetattr
void handle_input(int /*sig*/) {
signal(SIGTTIN, SIG_IGN);
std::cin.setstate(std::ios::failbit);
}
void handle_output(int /*sig*/) {
signal(SIGTTOU, SIG_IGN);
std::cout.setstate(std::ios::failbit);
}
class TCAttr {
int m_fd;
termios m_attr;
public:
TCAttr(int fd) : m_fd(fd), m_attr() {
// get input, output and local attributes
if(tcgetattr(m_fd, &m_attr) != 0)
m_fd = -1;
}
TCAttr(FILE* fp) : TCAttr(fileno(fp)) {}
TCAttr() : m_fd(-1), m_attr() {}
~TCAttr() {
// restore original input, output and local attributes
if(m_fd>=0)
tcsetattr(m_fd, TCSADRAIN, &m_attr);
}
//
bool set_lmode(tcflag_t flag) {
termios tmp;
if(tcgetattr(m_fd, &tmp)!=0) return false;
tmp.c_lflag = flag;
return tcsetattr(m_fd, TCSADRAIN, &tmp)==0;
}
bool add_lmode(tcflag_t flag) {
termios tmp;
if(tcgetattr(m_fd, &tmp)!=0) return false;
tmp.c_lflag |= flag;
return tcsetattr(m_fd, TCSADRAIN, &tmp)==0;
}
bool remove_lmode(tcflag_t flag) {
termios tmp;
if(tcgetattr(m_fd, &tmp)!=0) return false;
tmp.c_lflag &= ~flag;
return tcsetattr(m_fd, TCSADRAIN, &tmp)==0;
}
};
int main() {
TCAttr tca(stdout);
if(isatty(fileno(stdin))) {
// if tty input is requested in background mode
// SIGTTIN will be sent
signal(SIGTTIN, handle_input);
}
if(isatty(fileno(stdout))) {
// if tty output is requested in background mode
// SIGTTOU will be sent
signal(SIGTTOU, handle_output);
tca.add_lmode(TOSTOP);
}
std::cout << "Thanks for not streaming to a tty in background mode\n";
std::string name;
std::cin >> name;
std::cout << name << "\n";
}