The program I have is as follows:
#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);
}
}
}
I want to handle/ignore SIGTERM generated by exit system call. Is it possible? There is no way for me to avoid calling exit since its actually a library call which is trying to exit the program which i want to avoid.
You can certainly catch SIGTERM
. But that's not the problem here. You want to override the exit()
call.
This is not possible in any portable or standard compliant way. The exit()
is one of the functions that's defined to not return to its caller. Typically, this is done using the __attribute__((noreturn))
in gcc and C11 has introduced the macro _Noreturn
for the same purpose.
Attempting to return from such function, like exit()
, is undefined behaviour.
There are few options, I can think of:
gcc -Dexit=not_exit file.c
exit()
. See here for an example. Implementing a hook function may not work at all since this noreturn has existed on most libc implementations before C11's _Noreturn
. Modifying <stdlib.h>
to remove the _Noreturn
(or its equivalent) attribute for the exit()
function might make it work. None of these is guaranteed to work. We are already well into the UB land.
Other option is to an install atexit()
handler, which might be useful if you want to do something before exit()
.
A saner approach would be to modify the library if you to not call exit()
but instead return a error code. In my opinion, either the library is badly designed that it randomly exits on its own or probably there's a good reason that the library exits (due to some unrecoverable error) and your application is not supposed to continue any further, which you are attempting to do.
Looking at the glibc source for exit it looks like it isn't possible. But it might be if you're using another C std library.
You can do stuff at_exit but you can't prevent it.
[edit]
Everything below here is apparently not applicable for exit for the reasons in this question.
If you use gnu ld it might be possible to override __run_exit_handlers
, or exit
for that matter, using the gnu ld --wrap
option but I havn't tried it.
If you can use gnu ld you could do --wrap exit
and then implement __wrap_exit()
in your code. If you want to call exit
after this you can access it through __real_exit()
.
This is a gnu ld feature and I'm not sure how universally available it is.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With