Могу ли я запретить пользователю запускать мою C ++ программу в фоновом режиме? - PullRequest
0 голосов
/ 29 ноября 2018

У меня есть программа опроса на C ++, которая не может работать чисто как фоновый процесс.Поэтому я хочу запретить пользователю возможность использовать & после вызова имени моей программы в терминале Linux.

Как я могу запретить пользователю вызывать & после названия моего сценария?

Ответы [ 2 ]

0 голосов
/ 01 декабря 2018

Это плохая практика.Соглашение UNIX состоит в том, чтобы предполагать, что пользователь делает правильные вещи, и вносить соответствующие изменения.Либо измените программу, чтобы она работала чисто как фоновый процесс, либо предположите, что пользователь перенаправит вывод во что-то вроде /dev/null или в журнал.

0 голосов
/ 29 ноября 2018

Хотя я согласен с комментариями о том, что вы, как правило, должны доверять пользователям, он пытается ответить на вопрос, как я понял, прочитав комментарии (« Если моя программа работает в фоновом режиме,Командный терминал является работоспособным и работоспособным, но выходные данные программы скрывают пользовательский ввод и выводят подсказку").

Это не помешает запуску программы, но потоковая передача на 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";
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...