是否可以防止用户在后台运行C ++程序?

时间:2018-11-28 21:46:40

标签: c++ unix

我有一个C ++轮询程序,无法作为后台进程正常运行。因此,在Linux终端中调用我的程序名称后,我想防止用户使用&

如何防止用户在脚本名称后调用&

2 个答案:

答案 0 :(得分:1)

虽然我同意这些评论,即您通常应该信任用户,但这会尝试回答问题,因为我通过阅读评论来理解了该问题(“ 如果我的程序在后台运行,命令终端是可用且可操作的,但程序的输出会遮挡用户输入并替换提示“)。

这不会阻止程序运行,但是流向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";
}

答案 1 :(得分:0)

这样做是不好的做法。 UNIX惯例是假定用户做正确的事并做出相应的调整。要么修改程序以使其能够在后台进程中正常运行,要么假定用户会将输出通过管道传输到/dev/null或日志中。