我的进程作为守护进程运行。 我想用信号重新加载configuration。 问题是,如果configuration是错误的,它应该以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; }
现在你有源进程的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 ); } }
我不知道是/dev/pts
技巧正确/最好的方法来做到这一点。 但它似乎在我的Linux机器中工作:
~ # killall temp_test Hello! ~ #
我猜你喜欢赶上SIGUSR1
,然后重新加载配置?
您应该记住,信号处理程序应尽可能小而快,而不要做可能会导致另一个信号的事情。 所以基本上你应该尽可能避免I / O。 可能最好的方法是使用一个非常简单的信号处理程序,只设置一个标志,然后在主循环中检查这个标志,然后在主线程的上下文中重新载入配置。 在那里你可以输出到控制台所有你想要的。
你可以做到这一点,但没有办法做到这一点。 你需要安排一个守护进程的机制来反馈发送信号的进程。
一些可能的做法包括:
其中一个命名管道将是我的第一选择,我认为 – 你可以用普通的权限来限制对它的访问,而且这是最简单的做法。
我怀疑,你可以确定信号的来源,甚至如果可以的话,它不一定是一个终端。 那么使用简单的TCP / IP协议呢? 接受特殊端口上的tcp / ip连接。 读一个命令,直到第一个新行。 如果该命令是“重新配置”,则执行重新配置并通过建立的TCP / IP连接发送消息。