C++ 有没有办法阻止用户注册/使用自己的信号处理程序并始终使用特殊处理程序?

C++ 有没有办法阻止用户注册/使用自己的信号处理程序并始终使用特殊处理程序?,c++,c,linux,signals,signal-handling,C++,C,Linux,Signals,Signal Handling,我的要求是: 我的工具中有一个信号处理程序,它是在某个特定的时间间隔(我使用的是计时器)之间注册和使用的 现在,此信号处理程序不应允许在该处理程序注册后再注册任何其他处理程序。(但此限制仅适用于较短的持续时间,意味着在该持续时间之后,用户可以自由调用自己的处理程序) 有没有办法做到这一点 sigset_t mask; struct sigaction sa; printf("Establishing handler for signal %d\n", SIG); sa.sa_flags

我的要求是: 我的工具中有一个信号处理程序,它是在某个特定的时间间隔(我使用的是计时器)之间注册和使用的

现在,此信号处理程序不应允许在该处理程序注册后再注册任何其他处理程序。(但此限制仅适用于较短的持续时间,意味着在该持续时间之后,用户可以自由调用自己的处理程序)

有没有办法做到这一点

 sigset_t mask;
 struct sigaction sa;
 printf("Establishing handler for signal %d\n", SIG);
 sa.sa_flags = SA_SIGINFO;
 sa.sa_sigaction = handler; // This handler should override all handlers
 sigaction(SIG, &sa, NULL);
 sev.sigev_notify = SIGEV_SIGNAL;
 sev.sigev_signo = SIGUSR1;
我的工具实际上是用C++编写的,但是概念是如此的接近,因为越来越多的人熟悉它,所以我也用C++来添加C标记。
请随时要求更多澄清(如果您需要)

我想您正在编写一个库。答案是不,不,不,不!只需在文档中写下客户端代码不应该为该信号注册处理程序。如果你不能相信你的库的用户不会破坏东西,那么你应该编写应用程序,而不是库

无论您如何使您的处理程序优先于其他处理程序,如果其他代码执行相同的操作,它都不会工作。这里有一篇非常相关的博客文章,是关于希望创建“最高优先级窗口”(有点像“最高优先级”信号处理程序)的Windows开发人员的

另外,在Linux中,没有好的方法可以在比进程级别更精细的级别上授予不同级别的权限


p.p.S.澄清一下,如果我的代码正在您的进程中运行,那么您将无能为力。你已经输了。我的代码可以访问您的私有成员变量、释放内存、关闭文件和卸载库。(您可以编写内核代码或在虚拟化中运行所有内容,但那将非常糟糕。)

我假设您正在编写一个库。答案是不,不,不,不!只需在文档中写下客户端代码不应该为该信号注册处理程序。如果你不能相信你的库的用户不会破坏东西,那么你应该编写应用程序,而不是库

无论您如何使您的处理程序优先于其他处理程序,如果其他代码执行相同的操作,它都不会工作。这里有一篇非常相关的博客文章,是关于希望创建“最高优先级窗口”(有点像“最高优先级”信号处理程序)的Windows开发人员的

另外,在Linux中,没有好的方法可以在比进程级别更精细的级别上授予不同级别的权限


p.p.S.澄清一下,如果我的代码正在您的进程中运行,那么您将无能为力。你已经输了。我的代码可以访问您的私有成员变量、释放内存、关闭文件和卸载库。(您可以编写内核代码或在虚拟化中运行所有内容,但那将非常糟糕。)

如果处理信号是一个问题,那么就去掉信号!您可以使用select作为一种睡眠方式,在您的操作系统粒度允许的范围内实现最高精度。调用使用空ste(在任何集合中都没有描述符)进行选择,并且有效超时基本上是具有定时下限的阻塞系统调用


如果您不想阻塞,那么您可以将计时器放在它自己的线程中,并使用信号量或互斥或其他任何方式进行同步。

如果处理信号是一个问题,那么就去掉信号!您可以使用select作为一种睡眠方式,在您的操作系统粒度允许的范围内实现最高精度。调用使用空ste(在任何集合中都没有描述符)进行选择,并且有效超时基本上是具有定时下限的阻塞系统调用


如果您不想阻塞,那么您可以将计时器放在它自己的线程中,并使用信号量或互斥量或任何东西进行同步。

这是可以实现的,事实上,我已经通过在实际线程周围编写一个sigaction包装器,并使用
dlsym
RTLD\u NEXT
技术实现了这一点

以下是我的包装器的代码片段:

enter code here
int sigaction(int sig, const struct sigaction *act, struct sigaction *oact)
{

 struct sigaction sa;
 printf("My sigaction called\n");

 if((Timerflag==1)&&(sig==SIGUSR1))
 {
   sa.sa_sigaction=my_handler;
   sa.sa_flags=0;

   return LT_SIGACTION(sig,&sa,NULL);
  }
  else if(Timerflag==0)
    return LT_SIGACTION(sig, act, oact);  
}
最后,我想大家都知道,如何使用dlsym:-)获取libc句柄
不幸的是,没有人能在“stackoverflow”中给我这个想法。

这是可以实现的,事实上,我是通过在实际的sigaction包装器周围编写sigaction包装器,并使用
dlsym
RTLD\u NEXT
技术来实现的

以下是我的包装器的代码片段:

enter code here
int sigaction(int sig, const struct sigaction *act, struct sigaction *oact)
{

 struct sigaction sa;
 printf("My sigaction called\n");

 if((Timerflag==1)&&(sig==SIGUSR1))
 {
   sa.sa_sigaction=my_handler;
   sa.sa_flags=0;

   return LT_SIGACTION(sig,&sa,NULL);
  }
  else if(Timerflag==0)
    return LT_SIGACTION(sig, act, oact);  
}
最后,我想大家都知道,如何使用dlsym:-)获取libc句柄
不幸的是,没有人能在“stackoverflow”中告诉我这个想法。

最简单的答案是不要将信号用于计时器。相反,您可以简单地创建一个POSIX计时器,其中包含
SIGEV_线程
交付(处理程序在新线程中运行,而不是在信号处理程序中运行),或者创建您自己的线程并在其中按所需的间隔执行
nanosleep
。这样做的好处是计时器过期处理程序不仅限于异步信号安全功能,而且您不必担心安装的信号处理程序会发生冲突。

最简单的答案是不为计时器使用信号。相反,您可以简单地创建一个POSIX计时器,其中包含
SIGEV_线程
交付(处理程序在新线程中运行,而不是在信号处理程序中运行),或者创建您自己的线程并在其中按所需的间隔执行
nanosleep
。这样做的好处是计时器过期处理程序不仅限于异步信号安全函数,而且您不必担心安装了冲突的信号处理程序。

@Dietrich:您的猜测是正确的,我正在开发一个测试工具。用户的测试代码链接到我的工具。一旦我的计时器启动,不应允许用户调用其处理程序或寄存器,但他可以自由发送特定信号。计时器过期后,用户可以自由调用或注册其处理程序。没有办法吗?没有办法。当然,除非您想编写内核驱动程序。对不起,这超出了我的开发范围:(@kingsmash