# How to catch an interrupt (Control-C) in a script?

If a user hits Control-C when a script is running, they get an Interrupt> prompt, where they have to type exit or quit to return to the shell. I'd like to have the interpreter exit immediately when Control-C is hit. To this end, I'd like to catch the interrupt and run Exit. Is there a way to do this? Or is there a better option?

-
I don't have time to try this, but theoretically you can write your own handler for the Ctrl-C event and set it using a LibraryLink routine. Yes, this is a nasty hack ... – Szabolcs Sep 17 '13 at 19:55

Here's an ugly hack that works, based directly on this answer. This doesn't work on Windows.

First create a LibraryLink function that can set an alternate signal handler:

<< CCompilerDriver

handlerlib = "
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>

#include \"WolframLibrary.h\"

// you may want to specialize this for SIGINT only
void my_handler(int s){
printf(\"Caught signal %d\\n\",s);
exit(1);
}

DLLEXPORT mint WolframLibrary_getVersion(){
return WolframLibraryVersion;
}

DLLEXPORT int WolframLibrary_initialize( WolframLibraryData libData) {
return 0;
}

DLLEXPORT void WolframLibrary_uninitialize( WolframLibraryData libData) {
return;
}

DLLEXPORT void setHandler(WolframLibraryData libData, mint Argc, MArgument *Args, MArgument Res) {
struct sigaction sigIntHandler;

sigIntHandler.sa_handler = my_handler;
sigIntHandler.sa_flags = 0;

sigaction(SIGINT, &sigIntHandler, NULL);

return LIBRARY_NO_ERROR;
}
";

CreateLibrary[handlerlib, "handlerlib"]


Once the library is compiled, you can use it in any Mathematica session on the same machine.

So just put this at the beginning of your script:

LibraryFunctionLoad["handlerlib", "setHandler", {}, "Void"][]


Now Ctrl-C will kill the script immediately.

You could suggest to support that this be the default behaviour when Mathematica is invoked using the -script option.

-
Thanks for this. I need something similar. One question I have about your code: how come the third argument to LibraryFunctionLoad is {}, and not the list of argument types for setHandler? – kjo May 22 at 14:49
@kjo Because setHandler takes zero arguments. Take a look at the LibraryLink tutorial. On the C side, every LibraryLink function has the same signature. Then you manually read all arguments, as needed. setHandler` doesn't read any arguments. Just look at the examples which do take arguments and everything will be clear. – Szabolcs May 22 at 16:15