【发布时间】:2020-10-29 16:29:18
【问题描述】:
主题说明了一切。
在我完成清理工作后,我希望能够针对某些信号使用默认的 OS 信号处理程序。
例如如果收到 SIGINT,我想在我的自定义清理例程之后终止程序,并希望为此使用标准 OS 例程,而不是 callind _exit() 或其他任何东西。
我想我可以在用 sigaction() 覆盖之前以某种方式获得对原始信号处理程序的引用,但我不知道该怎么做。
这是我目前的代码:
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
volatile sig_atomic_t sigterm_flag = 0;
volatile sig_atomic_t sighup_flag = 0;
volatile sig_atomic_t sig_default_flag = 0;
void sigact(int signum, siginfo_t *siginfo, void *ucontext)
{
switch(signum)
{
case SIGTERM:
sigterm_flag = 1;
break;
case SIGHUP:
sighup_flag = 1;
break;
default:
sig_default_flag = 1;
break;
}
}
int main(void)
{
struct sigaction sa;
sa.sa_sigaction = sigact;
sa.sa_flags = SA_SIGINFO;
sigaction(SIGTERM, &sa, NULL);
sigaction(SIGHUP, &sa, NULL);
sigaction(SIGINT, &sa, NULL);
while (1) {
if (sigterm_flag == 1) {
sigterm_flag = 0;
printf("SIGTERM caught.\n");
}
if (sighup_flag == 1) {
sighup_flag = 0;
printf("SIGHUP caught.\n");
}
if (sig_default_flag == 1) {
sig_default_flag = 0;
printf("Other signal caught.\n");
}
sleep(1);
}
return 0;
}
编辑:
根据tuxlike 在回答https://stackoverflow.com/a/64595945/8359654 中的建议解决了挑战
这是最终代码:
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
volatile sig_atomic_t sigterm_flag = 0;
volatile sig_atomic_t sighup_flag = 0;
volatile sig_atomic_t sigint_flag = 0;
volatile sig_atomic_t sig_default_flag = 0;
void sigact(int signum, siginfo_t *siginfo, void *ucontext)
{
switch(signum)
{
case SIGTERM:
sigterm_flag = 1;
break;
case SIGHUP:
sighup_flag = 1;
break;
case SIGINT:
sigint_flag = 1;
break;
default:
sig_default_flag = 1;
break;
}
}
int main(int argc, char *argv[])
{
struct sigaction sa;
struct sigaction sa_default;
sigemptyset(&sa.sa_mask);
sa.sa_sigaction = sigact;
sa.sa_flags = SA_SIGINFO;
sigemptyset(&sa_default.sa_mask);
sa_default.sa_handler = SIG_DFL;
sa_default.sa_flags = 0;
sigaction(SIGTERM, &sa, NULL);
sigaction(SIGHUP, &sa, NULL);
sigaction(SIGINT, &sa, NULL);
printf("Started %s as PID %ld\n", argv[0], (long int)getpid());
while (1) {
if (sigterm_flag == 1) {
sigterm_flag = 0;
printf("SIGTERM caught.\n");
}
if (sighup_flag == 1) {
sighup_flag = 0;
printf("SIGHUP caught.\n");
}
if (sigint_flag == 1) {
sigint_flag = 0;
printf("\nSIGINT caught.\n");
sigaction(SIGINT, &sa_default, NULL);
raise(SIGINT);
}
if (sig_default_flag == 1) {
sig_default_flag = 0;
printf("Other signal caught.\n");
}
sleep(1);
}
return 0;
}
【问题讨论】:
-
Tuxlike 的答案是正确的,我删除了我的。