Fix signal handler
The functions "fprintf" and "erase" do not belong to the list of async-signal-safe functions. I guess that a different program design will be needed for your function "engine_safe_exit".
You're right, it makes sense - it will improve security by avoiding unpredictable behavior. I will work on it.
The thing is I gotta make sure ncurses finishes just right even on the case of an interruption. Otherwise the prompt becomes real ugly.
But most programs I know don't deal with this, forcing me to do a call to reset on the shell. I'll do a research on more software with ncurses.
Are you willing to dedicate another thread for receiving of notifications by the function "sigwaitinfo" or "select"?
Another fix would be to simply queue output to be printed and then print it later in your event loop. Or perhaps, just record that a signal was received, and then act on it when you reenter the loop.
Then you can use any signal handler you want, as long as you don't fork().
I like @kaniini 's idea. I don't think I have time to implement thread handling for signals, although that seems the best way, from a security point of view.
But are there any shortcomings for not dealing with the signal immediately? I mean, if the user sends an interrupt, he would still need to wait for another event cycle to finish the program. Could bad things happen in the meantime?
Sorry 'bout that, I'm not very skilled with signals - and that is a nice opportunity to learn.
There really isn't any shortcomings to this approach. I would only use a dedicated thread for handling signals if your program is multi-threaded, but I don't see why an ncurses tetris clone would use threads.
In a single-threaded program, this approach is completely valid.