3
$\begingroup$

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?

$\endgroup$
1
  • $\begingroup$ 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 ... $\endgroup$
    – Szabolcs
    Sep 17, 2013 at 19:55

1 Answer 1

8
$\begingroup$

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.

$\endgroup$
2
  • $\begingroup$ 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? $\endgroup$
    – kjo
    May 22, 2016 at 14:49
  • 1
    $\begingroup$ @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. $\endgroup$
    – Szabolcs
    May 22, 2016 at 16:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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