我能阻止用户在后台运行我的C++程序吗?

22 浏览
0 Comments

我能阻止用户在后台运行我的C++程序吗?

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

0
0 Comments

在C++编程中,有一个问题是如何阻止用户在后台运行程序。但是,这样做是不好的做法。UNIX的约定是假设用户是正确操作的,因此应该相应地进行调整。要么修改程序,使其能够作为后台进程干净地运行,要么假设用户会将输出导向到像/dev/null或日志文件中的东西。

以下是一种解决方法,可以修改程序使其在后台运行。修改的代码示例如下:

#include 
#include 
int main() {
    pid_t pid = fork();
    if (pid < 0) {
        std::cerr << "Fork failed." << std::endl;
        return 1;
    }
    if (pid > 0) {
        // Parent process
        return 0;
    }
    // Child process
    // Your program logic goes here
    return 0;
}

上述代码使用了`fork()`函数来创建一个子进程。如果`fork()`返回的值小于0,则表示创建子进程失败。如果返回的值大于0,则表示当前进程是父进程,可以直接退出。如果返回的值等于0,则表示当前进程是子进程,可以在其中编写程序逻辑。

另一种解决方法是假设用户会将程序的输出导向到/dev/null或日志文件中。这样可以确保程序在后台运行时不会产生任何输出。以下是示例代码:

#include 
int main() {
    // Your program logic goes here
    // Redirect output to /dev/null or a log file
    freopen("/dev/null", "w", stdout);
    freopen("/dev/null", "w", stderr);
    return 0;
}

以上代码使用了`freopen()`函数将标准输出和标准错误输出重定向到/dev/null文件,这样程序在后台运行时就不会在终端上产生任何输出。你也可以将输出重定向到其他日志文件中。

总之,要么修改程序使其能够干净地作为后台进程运行,要么假设用户会将输出导向到/dev/null或日志文件中,以防止用户在后台运行程序时产生不必要的输出。

0
0 Comments

可以通过以下方法防止用户在后台运行C++程序:

#define _POSIX_SOURCE
#include 
#include 
#include    // fileno
#include   // isatty
#include   // signal
#include    // fcntl
#include  // 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() {
        if(tcgetattr(m_fd, &m_attr) != 0)
            m_fd = -1;
    }
    TCAttr(FILE* fp) : TCAttr(fileno(fp)) {}
    TCAttr() : m_fd(-1), m_attr() {}
    ~TCAttr() {
        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))) {
        signal(SIGTTIN, handle_input);
    }
    if(isatty(fileno(stdout))) {
        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";
}

以上代码会阻止程序在后台运行时输出到标准输出(std::cout),但仍然可以将输出重定向到文件或管道中。程序运行时,如果在后台模式下请求终端输入,会触发SIGTTIN信号,通过信号处理函数handle_inputstd::cin设置为失败状态。同样地,如果在后台模式下请求终端输出,会触发SIGTTOU信号,通过信号处理函数handle_outputstd::cout设置为失败状态,并且还会使用tca.add_lmode(TOSTOP)函数将输入模式设置为TOSTOP。最后,程序会打印一条消息,然后从终端输入一个字符串,将其输出到终端。

0