我作为守护进程运行的进程.我想使用信号重新加载配置.问题是,如果配置错误,它应该以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;
}
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)