c - Why signal handling is malfunctioning? -
i have signal handling snippet somehow malfunctioning on mac , virtual linux box @ koding.com on office linux pc working..can please tell me why..
#include <stdio.h> #include <signal.h> #include <unistd.h> void my_isr(int n){ printf("hello world"); signal(sigint, sig_dfl); } int main(){ signal(sigint, my_isr); printf("pid = %d\n", getpid()); while(1); return 0; }
when pressing ctrl+c not printing hello world
on first time re-modifying sigint
signal action & hence exiting program when press ctrl+c second time. can explain me why?
you not allowed call every function in signal handler.
read signal(7). only async signal safe functions can called (directly or indirectly) from signal handler, , printf
not such function. if want reliably "print" inside signal handler (which don't recommend), can use low-level write(2) syscall (it async signal safe).
so you've got undefined behavior. this explains why bad.
the recommended way set volatile sigatomic_t
flag in signal handler, , test outside of (e.g. in while
loop...). , forgot call fflush(3). might more lucky ending printf
format string \n
since stdout
line-buffered!
of course, changing printf
inside signal handler still ub, \n
, appear work.
here conforming version of program....
#include <signal.h> #include <unistd.h> #include <stdio.h> volatile sig_atomic_t got_signal; void my_sigint_handler (int signum) { if (signum == sigint) // true! got_signal = 1; #define interrupt_message "interrupted!\n" write(stdout_fileno, interrupt_message, strlen(interrupt_message)); }; int main(int argc, char**argv) { struct sigaction act_int; memset (&act_int, 0, sizeof(act_int)); act_int.sa_handler = my_sigint_handler; if (sigaction(sigint, &act_int, null)) { perror("sigaction"); exit(exit_failure); }; printf ("start %s pid %d\n", argv[0], (int)getpid()); while (!got_signal) { }; printf ("ended %s after signal\n", argv[0]); return 0; }
a useful (and permissible) trick write(2) single byte -inside signal handler- on pipe(7) self (you set pipe using pipe(2) @ program initialization), , in event loop poll(2) read end of pipe.
Comments
Post a Comment