Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何输出到当前可见的终端_C++_C_Linux_Tty - Fatal编程技术网

C++ 如何输出到当前可见的终端

C++ 如何输出到当前可见的终端,c++,c,linux,tty,C++,C,Linux,Tty,我想输出一些文本作为对信号的响应SIGUSR1 即,用户将kill-USR1发送到后台或另一个终端中启动的进程 我想在调用kill的终端中获得一些输出 我怎样才能做到这一点?关于@BoBTFish的评论正在发挥作用。一种可能的伪C++实现: // somewhere in code: std::memset(&sa, 0, sizeof(struct sigaction)); sa.sa_sigaction = sh_dump; sa.sa_flags = static_cast<

我想输出一些文本作为对信号的响应
SIGUSR1

即,用户将
kill-USR1
发送到后台或另一个终端中启动的进程

我想在调用
kill
的终端中获得一些输出


我怎样才能做到这一点?

关于@BoBTFish的评论正在发挥作用。一种可能的伪C++实现:

// somewhere in code:
std::memset(&sa, 0, sizeof(struct sigaction));
sa.sa_sigaction = sh_dump;
sa.sa_flags = static_cast<int>(SA_SIGINFO); // <- important, else you'll get an invalid siginfo_t pointer
sigaction(SIGUSR1, &sa, NULL);

void sh_dump(int, siginfo_t *info, void *) {

    if(info) {

        // do some locking of your choice

        char *p = NULL;
        char sp[PATH_MAX] = "";

        std::snprintf(sp, PATH_MAX, "/proc/%d/stat", info->si_pid);

        int tty_nr = 0;
        FILE *spf;

        if((spf = std::fopen(sp, "r"))) {

            int iDummy;
            char cDummy, *sDummy;

            // proc(5)
            if(std::fscanf(spf, "%d %ms %c %d %d %d %d", &iDummy, &sDummy, &cDummy, &iDummy, &iDummy, &iDummy, &tty_nr)) {}

            free(sDummy);
            std::fclose(spf);
        }

        // see http://goo.gl/L0pGK1 for an implementation
        if(!(p = ttynameCheckDir(static_cast<dev_t>(tty_nr), "/dev/pts"))) {
            p = ttynameCheckDir(static_cast<dev_t>(tty_nr), "/dev");
        }

        std::ofstream out(p ? p : "/dev/null");

        free(p);

        if(out.is_open()) out << "HELLO" << std::endl;

        // do some unlocking of your choice
    }
}
//代码中的某个地方:
std::memset(&sa,0,sizeof(struct-sigaction));
sa.sa_sigaction=sh_dump;

sa.sa_flags=static_cast(sa_SIGINFO);// 为了确保写入控制终端,有一个设备专门用于此操作。如果您处于分离(无控制终端)过程中,它将不起作用。只需打开(2)它并写入(2)通常,stdin/stdout/stderr可以重定向,因此为了确保您正在用户将看到的地方写入,请打开
/dev/tty
并写入它
/dev/tty
早于unix的古代。为了兼容性,它被保存了下来。它还可以用来获取密码,并确保您没有重定向某些提供给进程的文件描述符。

可能是一个很好的开始。然后您可以查看
/proc//fd/1
,查看它将控制台输出发送到哪里。这确实是一个很好的起点:)实际上您不知道信号来自哪个终端:它可能是从不同的shell发出的。如果只有一个终端/窗口需要考虑,可以写入/DEV/tty@HeikoSch如果我没有时间尝试任何东西,而且似乎没有人知道一个明显的答案,那么如果您确实从该链接(或其他任何链接)中获得了任何有用的信息,请毫不犹豫地发布您自己问题的答案。@BoBTFish非常感谢,这就成功了:)/proc/fd/1与stdout相同,可以重定向。不是问题的答案。我不完全确定,但您的代码似乎无效,因为您的信号处理程序多次调用不可重入函数。据我所知,我尝试了
/dev/tty
,但是我想把输出拿到信号发射器终端。你说的信号发射器终端是什么意思?调用的终端,即,
kill-USR1
,你无法知道发送信号的进程。出于同样的原因,您无法知道它(发送信号的进程)正在运行的终端。控制终端用于选择从内核接收信号的进程(例如,来自tty设备驱动程序的SIGKILL或SIGINT,或会话结束时的SIGHUP)。在UN*X中,除了控制终端(与前台会话相关联的终端)之外,您没有通用/可移植的手段来了解其他终端在发送信号的进程中,要知道目标进程发生了什么,唯一的方法是从kill(2)系统调用中获取结果代码(如果返回0,则信号至少发送到一个进程)。这是在信号颁发者进程的终端上打印的唯一方法。