linux - [Solved-5 Solutions] How to avoid using printf in a signal handler ? - ubuntu - red hat - debian - linux server - linux pc
Linux - Problem :
How to avoid using printf in a signal handler ?
Linux - Solution 1:
- You can use some flag variable, set that flag inside signal handler, and based on that flag call printf() function in main() or other part of program during normal operation.
- It is not safe to call all functions, such as printf, from within a signal handler.
- A useful technique is to use a signal handler to set a flag and then check that flag from the main program and print a message if required.
- Notice in example below, signal handler ding() set a flag alarm_fired to 1 as SIGALRM caught and in main function alarm_fired value is examined to conditionally call printf correctly.
static int alarm_fired = 0;
void ding(int sig) // can be called asynchronously
{
alarm_fired = 1; // set flag
}
int main()
{
pid_t pid;
printf("alarm application starting\n");
pid = fork();
switch(pid) {
case -1:
/* Failure */
perror("fork failed");
exit(1);
case 0:
/* child */
sleep(5);
kill(getppid(), SIGALRM);
exit(0);
}
/* if we get here we are the parent process */
printf("waiting for alarm to go off\n");
(void) signal(SIGALRM, ding);
pause();
if (alarm_fired) // check flag to call printf
printf("Ding!\n");
printf("done\n");
exit(0);
}
click below button to copy the code. By - Linux tutorial - team
Linux - Solution 2:
- Don't use printf() in signal handlers.
- At least on POSIX conforming systems, you can use write(STDOUT_FILENO, ...) instead of printf(). Formatting may not be easy however: Print int from signal handler using write or async-safe functions
Linux - Solution 3:
- For debugging purposes, I wrote a tool which verifies that you are in fact only calling functions on the async-signal-safe list, and prints a warning message for each unsafe function called within a signal context. While it doesn't solve the problem of wanting to call non async-safe functions from a signal context, it at least helps you find cases where you have done so accidentally.
- By overloading signal/sigaction, then temporarily hijacking the PLT entries of unsafe functions; this causes calls to unsafe functions to be redirected to a wrapper.
Linux - Solution 4:
It is especially useful in programs which have a select loop is to write a single byte down a pipe on receipt of a signal and then handle the signal in the select loop.
static int sigPipe[2];
static void gotSig ( int num ) { write(sigPipe[1], "!", 1); }
int main ( void ) {
pipe(sigPipe);
/* use sigaction to point signal(s) at gotSig() */
FD_SET(sigPipe[0], &readFDs);
for (;;) {
n = select(nFDs, &readFDs, ...);
if (FD_ISSET(sigPipe[0], &readFDs)) {
read(sigPipe[0], ch, 1);
/* do something about the signal here */
}
/* ... the rest of your select loop */
}
}
click below button to copy the code. By - Linux tutorial - team
Linux - Solution 5:
- You can use printf in signal handlers if you are using the pthread library.
- Note that in order to get a clearer picture of printf output, you should run your application in a console (on linux use ctl+alt+f1 to start console 1), rather than a pseudo-tty created by the GUI.