有什么办法可以防止用户注册/使用自己的信号处理程序并始终使用特定的处理程序?

问题描述 投票:0回答:4

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

现在这个信号处理程序应该不允许在这个处理程序注册后注册任何其他处理程序。 (但这个限制只是持续很短的时间,意味着在这段时间之后用户可以自由调用他自己的处理程序)

有没有办法做到这一点?

 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++ 请随时要求更多说明(如果需要)

c++ c linux signals signal-handling
4个回答
9
投票

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

无论你做什么来让你的处理程序优先于其他处理程序,如果其他代码做同样的事情,它就不会起作用。这是一篇非常相关的博客文章,内容涉及想要制作“最顶层窗口”(有点像“最高优先级”信号处理程序)的 Windows 开发人员。

https://devblogs.microsoft.com/oldnewthing/20110310-00/?p=11253

附言在 Linux 中,没有什么好的方法可以在比进程级别更细的级别上赋予不同级别的权限。

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


1
投票

如果处理信号有问题,那就摆脱信号!您可以使用 select 作为一种睡眠方式,无论您的操作系统粒度是否允许,都可以保持精确。使用 null stes(任何集合中没有描述符)和有效超时调用 selects 基本上是一个具有定时下边界的阻塞系统调用。

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


0
投票

最简单的答案是不要为计时器使用信号。您可以改为简单地创建一个具有

SIGEV_THREAD
传递的 POSIX 计时器(处理程序在新线程中而不是信号处理程序中运行)或创建您自己的线程并在其中
nanosleep
所需的时间间隔。这样做的好处是计时器过期处理程序不仅限于异步信号安全功能,而且您不必担心安装的信号处理程序会发生冲突。


-4
投票

这是可以实现的,事实上,我已经通过围绕实际包装器编写一个 sigaction 包装器并使用

dlsym
RTLD_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”中没有人能给我这个想法。

© www.soinside.com 2019 - 2024. All rights reserved.