Surprisingly, it <i>is</i> possible to do exactly what the author wants. I know because I've done it. However, it <i>is</i> as complicated as the author says it is.<p>The project in question is my `bc` [1].<p>Until version 3.0.0 [2], it used a "yield" architecture: every loop it could enter had a check for a signal. This got tedious, so I decided to make the jump to instant-ish reset.<p>I was lucky in several ways. First, `bc` is a really good program to reset; you just stop it executing, wipe all data away, and ask for more input with a blank slate. Second, it is single-threaded.<p>Nevertheless, it was still really difficult, especially to have no memory leaks.<p>First, I had to learn how to use `sigsetjmp()` and `siglongjmp()`. Yep, that was how I was going to do this. Once I learned, I implemented a stack of `sigjmp_buf`'s. Then, when a signal happens, each individual `sigjmp_buf` is used. This allowed me to properly free memory on the way.<p>In essence, if a function had allocated memory, then it would push a `sigjmp_buf` on the stack, and then when a `siglongjmp()` happened, execution would go to a label where that memory would be freed before continuing the jump series.<p>Then I implemented signal locks. It is safe to `siglongjmp()` out of signal handler, as long as it didn't interrupt code that was non-async-signal-safe. So I used signal locks for that, and when "unlocking" the lock, it would check for a signal and jump. And if the signal handler sees a lock, it just sets a flag and returns.<p>Then I had to go through my codebase and protect every bit of non-async-signal-safe code with locks. It was tedious, but the result is fantastic.<p>Edit: I forgot to add that there is more information at [3] and [4].<p>Nowadays, I'm working on a threaded build system, and when it gets SIGINT, it sends a message to threads to stop as soon as their children are done. If it receives a second, it just exits.<p>So yeah, every application is different, but it <i>is</i> possible.<p>[1]: <a href="https://git.yzena.com/gavin/bc" rel="nofollow">https://git.yzena.com/gavin/bc</a><p>[2]: <a href="https://git.yzena.com/gavin/bc/src/branch/master/NEWS.md#3-0-0" rel="nofollow">https://git.yzena.com/gavin/bc/src/branch/master/NEWS.md#3-0...</a><p>[3]: <a href="https://git.yzena.com/gavin/bc/src/branch/master/manuals/development.md#async-signal-safe-115-signal-handling" rel="nofollow">https://git.yzena.com/gavin/bc/src/branch/master/manuals/dev...</a><p>[4]: <a href="https://git.yzena.com/gavin/bc/src/branch/master/manuals/development.md#user-content-error-handling" rel="nofollow">https://git.yzena.com/gavin/bc/src/branch/master/manuals/dev...</a>