Quote:
Originally Posted by fneves
What I wonder is whether it was possible to make a break and go into this program and save a file. The problem is that I'm not getting through the files as argument in the interrupt SIGINT. How do I do it?
|
You're close, but slightly off-track.
First, there are functions you shouldn't use in a signal handler. See
man 7 signal and specifically the section on
Async-signal-safe functions. Signal handlers are not intended to do any significant work. You shouldn't attempt to do any cleanup there; it won't work the way you intend to.
Years ago there was an FTP file server that did exactly what you try to do here. Because of certain interactions between signal handling and operations done in the normal course of the FTP server program, all you needed to do was to hit Ctrl+C at the exact right moment, and you'd get superuser access rights. It stumped a lot of people at first, but eventually the exact sequence was tracked down. It was an important lesson and a reminder for many.
Think about the word
break. It's much safer if your signal handler just puts up a flag indicating the user wants to make a break. Sure, you need to think about how to break out of each task your program does, but that's life: there is no magic bullet. You'll most likely notice that the mindset helps you write better code, though. The first thing to typically emerge as a side effect is much more robust error handling; with just a few lines of code more you can handle all sorts of unexpected errors gracefully. I find it much better than just crapping out and leaving the user to wonder what the hell just happened.
There is one common pitfall, though. There is a special integer type,
sig_atomic_t, which is guaranteed to work as a signal flag. It has a limited range, only 0 to 127, if you write portable code; its size and range varies from platform to platform (but all include at least the range 0 to 127).
If you define your flag as a global variable of type
volatile sig_atomic_t, you can safely access it whenever and wherever you want, and your compiler understands its value may change unexpectedly. All other types are not guaranteed to be atomic; if your main program happens to be reading it while your signal handler modifies them, the main program may read garbage instead. And if both modify them at the same time, the value stored may be garbage. (Although character types
char and
unsigned char are normally atomic, there may be unexpected interactions on certain platforms if your main program is modifying them or something within the same native word while the signal handler is trying to modify the value.)
And the compiler is allowed to remember and even postpone modifying the value of any non-
volatile variable until the next write access -- for example, to just after the heavy, long-running work loop you might have.
In a nutshell:
sig_atomic_t is the only type of variable your signal handler may safely read and modify; but your main program is not guaranteed to notice any changes in them. For the main program to be guaranteed to notice, you need to use
volatile sig_atomic_t type.
On x86 and other platforms the actual rules are much more relaxed, but I wouldn't rely on them, especially if you want the code to work on all Linux variants.
Hope this helps you,
Nominal Animal