Mathematica Stack Exchange is a question and answer site for users of Mathematica. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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?

share|improve this question
    
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
up vote 6 down vote accepted

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;
     sigemptyset(&sigIntHandler.sa_mask);
     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.

share|improve this answer
    
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
1  
@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

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.