我的程序如下:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
int main()
{
struct sigaction new_sa;
struct sigaction old_sa;
sigfillset(&new_sa.sa_mask);
new_sa.sa_handler = SIG_IGN;
new_sa.sa_flags = 0;
int input;
if (sigaction(SIGTERM, &new_sa, &old_sa) == 0 && old_sa.sa_handler != SIG_IGN) {
new_sa.sa_handler = NULL;
sigaction(SIGTERM, &new_sa, 0);
}
printf("Pgm is running\n");
while (1) {
printf("Enter input\n");
scanf("%d", &input);
if (!input) {
/* I actually call a libraries API which calls exit()
* Just calling exit here for simpilicity */
exit(1);
}
}
}
我想处理/忽略退出系统调用生成的SIGTERM。可能吗? 我没办法避免调用exit,因为它实际上是一个试图退出我想要避免的程序的库调用。
答案 0 :(得分:2)
查看glibc source退出,看起来似乎不可能。但是,如果您正在使用另一个C std库,那可能就是这样。
你可以做at_exit的东西,但是你无法阻止它。
<强> [编辑] 强>
由于this question中的原因,此处的所有内容显然不适用于退出。
如果您使用gnu ld,则可以使用gnu ld __run_exit_handlers
选项覆盖exit
或--wrap
,但我还没有尝试过。
如果您可以使用gnu ld,则可以执行--wrap exit
,然后在代码中实施__wrap_exit()
。如果您想在此之后致电exit
,可以通过__real_exit()
访问它。
这是一个gnu ld功能,我不确定它有多普遍可用。
答案 1 :(得分:2)
你当然可以抓住.top-info {
background: url("http://i.stack.imgur.com/prA95.jpg") no-repeat left 15px;
height: 40rem;
background-size: contain;
border-top: 10px solid transparent;
border-image: url("http://i.stack.imgur.com/SUUpP.png") 30 stretch;
-webkit-border-image: url("http://i.stack.imgur.com/SUUpP.png") 30 stretch;
}
。但这不是问题所在。您想覆盖SIGTERM
来电。
这在任何便携式或标准兼容方式下都是不可能的。 exit()
是不定义的函数之一返回其调用方。通常,这是使用gcc中的exit()
完成的,而C11为了相同的目的引入了宏__attribute__((noreturn))
。
尝试从此类函数返回,如_Noreturn
,undefined behaviour。
我能想到的选择很少:
exit()
gcc -Dexit=not_exit file.c
编写一个钩子函数。有关示例,请参阅here。实现钩子函数可能根本不起作用,因为这个 noreturn 在C11&#39; exit()
之前的大多数libc实现中都存在。 修改_Noreturn
以删除<stdlib.h>
功能的_Noreturn
(或其等效)属性可能会使其正常工作。这些都不能保证有效。我们已经进入了UB的土地。
其他选项是安装exit()
处理程序,如果您想在atexit()
之前执行某些操作,这可能很有用。
如果您不调用exit()
而是返回错误代码,那么更安全的方法是修改库。在我看来,要么库设计得很糟糕,它会随机随意退出,或者可能是库存退出的一个很好的理由(由于一些不可恢复的错误)并且你的应用程序不应该继续下去,你正试图这样做。
答案 2 :(得分:0)
可能是在fork
的子进程中运行库调用。这不会阻止对exit
的调用,但如果您想自己处理错误,则可能是一种解决方法。
按照教程Fork, Exec and Process control。如果调用成功,我使用管道发送库调用的结果。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(){
int pipefd[2];
pipe(pipefd); //Create pipe for communication
pid_t pid = fork();
if (pid == 0){ //Child process
close(pipefd[0]); // close the read-end of the pipe,
printf("Run library here\n");
// exit(3); if failed
int val=4; //Result of library call send to parent
write(pipefd[1], &val, sizeof(val));
close(pipefd[1]); // close the write-end of the pipe
exit(EXIT_SUCCESS);
}
else if (pid < 0){
printf("Failed to fork\n");
}
else{//Parent process
close(pipefd[1]);
printf("Parent process\n");
int status=0;
int pid=wait(&status);
printf("The pid %d finished with status %d\n",pid,status);
if (status==EXIT_SUCCESS){//The library call was successful
int val=2;
read(pipefd[0],&val,sizeof(int)); //Read data from pipe and do something with it
printf("Value %d received\n",val);
}
close(pipefd[0]);
}
return 0;
}