Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[Example] Catching SIGINT in a Java application under UNIX

558 views
Skip to first unread message

Mark Gritter

unread,
Nov 25, 1997, 3:00:00 AM11/25/97
to

The following example shows how to catch SIGINT (Ctrl-C) in a Java
application. As I (and others) have discovered, calling Java methods
directly from a signal handler tends to crash the JVM. The following
code shows one method of working around this, which should be adaptable
to catching other UNIX signals.

I've only tried it on Solaris, using the Sun JVM with green threads.
I'm rather surprised that it works, since I didn't use a non-blocking
read.

/* CatchSignal.java -- compile and run through javah! */
public class CatchSignal implements Runnable {
static {
System.loadLibrary("CatchSignal");
}

public native static void setControlCHandler();

public static void callback() {
System.err.println("Control-C hit!");
}

public void run() {
setControlCHandler(); // never returns
}

public static void main(String[] args) {
Thread t = new Thread(new CatchSignal());
t.setDaemon(true); // allow program to end even though
// signal-handling thread doesn't
t.setPriority(Thread.MAX_PRIORITY); // ensure signals are handled promptly
t.start();

// Do some lengthy computation...
int i;
for (i = 0; i < 5000000; i++) {
if (i % 100000 == 0) System.out.print(i / 100000 + " ");
}
System.out.println("");
}
}

/* CatchSignal.c -- compile as shared library libCatchSignal.so */
/* See the java tutorial for details on compiling native code libraries. */
#include "CatchSignal.h"
#include <signal.h>
#include <unistd.h>

int pipefd;

void ctrl_c_handler() {
int foo = SIGINT;
write(pipefd, &foo, sizeof(int));
signal(SIGINT, ctrl_c_handler);
}

JNIEXPORT void JNICALL
Java_CatchSignal_setControlCHandler (JNIEnv *env, jclass cls) {
int filedes[2], sigfd, s;
jmethodID mid = (*env)->GetStaticMethodID(env, cls, "callback", "()V");

pipe(filedes);
pipefd = filedes[0];
sigfd = filedes[1];

signal(SIGINT, ctrl_c_handler);

while (1) {
read(sigfd, &s, sizeof(int));
(*env)->CallStaticVoidMethod(env, cls, mid);
}
}

--
Mark Gritter <mgri...@cs.stanford.edu> http://www.stanford.edu/~mgritter/
/* "Perhaps there is no regularity to be discerned." */
/* "Oh, you and your constant rumblings about chaos! I'll hear */
/* none of that, thank you." -- The Tortise and Achilles */

0 new messages