在发送信号的terminal上显示一条消息

我的进程作为守护进程运行。 我想用信号重新加载configuration。 问题是,如果configuration是错误的,它应该以tty格式发送信号的错误消息。

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

如果不是推荐的方法。 什么将是一个更合适的方式来检查是否成功?

为了获得信号源的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_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! ~ # 

我猜你喜欢赶上SIGUSR1 ,然后重新加载配置?

您应该记住,信号处理程序应尽可能小而快,而不要做可能会导致另一个信号的事情。 所以基本上你应该尽可能避免I / O。 可能最好的方法是使用一个非常简单的信号处理程序,只设置一个标志,然后在主循环中检查这个标志,然后在主线程的上下文中重新载入配置。 在那里你可以输出到控制台所有你想要的。

你可以做到这一点,但没有办法做到这一点。 你需要安排一个守护进程的机制来反馈发送信号的进程。

一些可能的做法包括:

  • 将(时间戳)结果写入到预定位置的文件中。
  • 让守护进程保持共享内存段与已知结构中的信息。
  • 让守护进程在某种有名的管道/套接字上进行侦听,并以这种方式给出反馈。 (您也可以通过该频道发送重新载入命令)。
  • 有发送信号和守护进程链接到共享库的事情,以便两者都能够验证配置文件。 提升信号之前验证文件。

其中一个命名管道将是我的第一选择,我认为 – 你可以用普通的权限来限制对它的访问,而且这是最简单的做法。

我怀疑,你可以确定信号的来源,甚至如果可以的话,它不一定是一个终端。 那么使用简单的TCP / IP协议呢? 接受特殊端口上的tcp / ip连接。 读一个命令,直到第一个新行。 如果该命令是“重新配置”,则执行重新配置并通过建立的TCP / IP连接发送消息。