我的进程作为守护程序运行。
我想使用信号重新加载配置。
问题是,如果配置错误,则应该以tty形式发送错误消息,该错误消息发送给哪个信号。

  • 有没有办法做到这一点?
  • 是推荐方法吗?

  • 如果不推荐的方式。有什么更合适的方法来检查它是否成功?

    最佳答案

    为了获取信号源的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;
    }
    

    现在,您已经掌握了源代码处理的过程。

    要获取源进程的终端ID并不是那么简单。
    一种方法是从proc/<pid>/stat文件中读取它。文件中的一个数字是tty_nrtty_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 );
        }
    }
    

    我不确定/dev/pts技巧是否正确/最佳方法。但这似乎可以在我的Linux系统中使用:
    ~ # killall temp_test
    Hello!
    ~ #
    

    09-10 03:06
    查看更多