在发送信号的终端中显示消息

Viv*_*oel 4 c++ linux tty

我作为守护进程运行的进程.我想使用信号重新加载配置.问题是,如果配置错误,它应该以tty形式发出错误信息.

  1. 有没有办法做到这一点?
  2. 是推荐的方式吗?

如果不推荐的话.什么是更合适的方法来检查它是否成功?

SKi*_*SKi 6

要获得信号源的pid,您需要使用sa_sigaction而不是sa_handler在设置信号处理程序时:

static pid_t g_killer_pid = 0;

static void signal_handler( int num, siginfo_t *info, void* blabla )
{
    g_killer_pid = info->si_pid;
}

int main(void)
{    
    struct sigaction sa;

    memset( &sa, 0, sizeof(sa) );
    sa.sa_sigaction = &signal_handler;
    sa.sa_flags = SA_SIGINFO;
    sigaction( SIGTERM, &sa, NULL );
    sigaction( SIGINT,  &sa, NULL );

    pause();
    hello_killer( g_killer_pid );

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

现在你有了源进程的pid.

获取源进程的终端ID并不是那么简单.一种方法是从proc/<pid>/stat文件中读取它.文件中的一个数字是tty_nr. tty_nr对我来说有点奇怪,所以我不知道这是不是便携式的东西.但它包含次要编号,可用于打开正确的写入终端:

static void hello_killer( pid_t killer )
{
    char filename[200];
    FILE* fil;
    FILE* out;
    int tty_nr;

    sprintf( filename, "/proc/%ld/stat", (long int)killer );
    fil = fopen( filename, "r" );
    if( fil )
    {
        if( fscanf( fil, "%*s %*s %*s %*s %*s %*s %d ", &tty_nr ) == 1 )
        {
            sprintf( filename, "/dev/pts/%d", (tty_nr & 0xF) | ((tty_nr >> 20) & 0xFFF) );

            out = fopen( filename, "a" );
            if( out )
            {
                fprintf( out, "Hello!\n" );
                fclose( out );
            }
        }
        fclose( fil );
    }
}
Run Code Online (Sandbox Code Playgroud)

我不确定这是一种/dev/pts正确/最好的方法.但它似乎在我的Linux盒子中工作:

~ # killall temp_test
Hello!
~ #
Run Code Online (Sandbox Code Playgroud)