I have a function that is the handler of the SIGINT signal in my C program, that when is executed should simply execute the following commands:
void sigint_handler(int sig)
{
system("cat output.txt");
exit(0);
}
The problem is that the "cat" command doesn't seems to do anything. If I try to do something else instead of "cat", like "echo something" it works fine, so I believe the problem is with the "cat" and not with the system() function. The file "output.txt" is in the same directory of the C program, and if I try to execute cat on that file through another C script it works. Also if I try to execute that command from shell it works.
I've checked the return from the system("cat output.txt")
and it's 0. So what can the problem be?
EDIT: The file output.txt is also open as a FILE stream (using fopen()
) in the program, by another thread, could that be an issue maybe?
You should know that signal handlers can only safely call a restricted set of async-signal-safe functions. Neither system()
nor exit()
are on the list. Calling them is likely to trigger undefined behavior, which can lead to unpredictable results.
I see, but I don't understand why his version is working while mine is not. I declare the signal handler in the same way, but my program can't execute that "cat" command, while in his version it does.
I second Charles Duffy's reply:
Sometimes things that aren't guaranteed still work despite not being guaranteed as an accident of environment or configuration. That doesn't make the code that just happens to work correct; good code relies only on documented, guaranteed semantics.
A common workaround for this is to move your signal handling code to the main program, and have the main program periodically check a global variable. From the signal handler all would do is set the global variable and return. This technique will let you do whatever you like, albeit in a somewhat convoluted way.
volatile sig_atomic_t sigint_received = 0;
void sigint_handler(int sig)
{
sigint_received = 1;
}
// main program loop
for (;;) {
// do stuff
...
// check for interruption
if (sigint_received) {
system("cat output.txt");
exit(0);
}
}