After many, many hours of searching the face of the Internet, I have found the answer.
Linux has the notion of a process group.
The TTY driver has a notion of Foreground Process Group.
When you press Ctrl+CCtrl+C, the TTY sends SIGINT
SIGINTto every process in the Foreground Process Group. (See also this blog entry.)
This is why both the compiled binary and the script that launches it both get clobbered. In fact I only want the main application to receive this signal, not the startup scripts.
The solution is now obvious: We need to put the application in a new process group, and make it the Foreground Process Group for this TTY. Apparently the command to do that is
setsid -c <applcation> And that is all. Now when the user presses Ctrl+CCtrl+C, SIGINT will be sent to the application (and any children it may have) and nobody else. Which is what I wanted.
setsidby itself puts the application in a new process group (indeed, an entire new "session", which is apparently a group of process groups).Adding the
-cflag makes this new process group become the "foreground" process group for the current TTY. (I.e., it gets SIGINTSIGINTwhen you press Ctrl+C.Ctrl+C)
I've seen a lot of conflicting information about when Bash does or does not run processes in a new process group. (In particular, it appears to be different for "interactive" and "non-interactive" shells.) I've seen suggestions that you can maybe get this to work with clever pipe trickery... I don't know. But the approach above seems to work for me.