diff --git a/src/java/com/threerings/util/signal/FreeBSD/Makefile b/src/java/com/threerings/util/signal/FreeBSD/Makefile index 835281f52..1b72264d2 100644 --- a/src/java/com/threerings/util/signal/FreeBSD/Makefile +++ b/src/java/com/threerings/util/signal/FreeBSD/Makefile @@ -14,11 +14,7 @@ MKDIR=mkdir ROOT=../../../../../../.. LIBRARIES_PATH= -ARCH!=uname -p -OS!=uname -s OSINCDIR!=uname -s | tr 'A-Z' 'a-z' -OSDIR=${ARCH}-${OS} -INSTALL_PATH=${ROOT}/dist/lib/${OSDIR} # # Parameter and file definitions @@ -32,15 +28,11 @@ TARGET=libsignal.so all: ${TARGET} -install: ${TARGET} - @${MKDIR} -p ${INSTALL_PATH} - cp ${TARGET} ${INSTALL_PATH} - ${TARGET}: com_threerings_util_signal_SignalManager.c - @echo "Compiling SignalManager.c + @echo "Compiling SignalManager.c" @${CC} ${INCLUDES} -c com_threerings_util_signal_SignalManager.c \ -o com_threerings_util_signal_SignalManager.o - @echo Creating libsignal.so + @echo "Creating libsignal.so" @${CC} -o ${TARGET} com_threerings_util_signal_SignalManager.o \ ${LIBRARIES} ${LIBRARIES_PATH} -shared diff --git a/src/java/com/threerings/util/signal/Linux/Makefile b/src/java/com/threerings/util/signal/Linux/Makefile new file mode 100644 index 000000000..bb07eab94 --- /dev/null +++ b/src/java/com/threerings/util/signal/Linux/Makefile @@ -0,0 +1,40 @@ +# +# $Id: Makefile 3328 2005-02-03 01:16:12Z mdb $ + +# +# Executable definitions + +CC=gcc +RM=rm +CP=cp +MKDIR=mkdir + +# +# Directory definitions + +ROOT=../../../../../../.. +LIBRARIES_PATH= +OSINCDIR:=$(shell uname -s | tr 'A-Z' 'a-z') + +# +# Parameter and file definitions + +INCLUDES=-I.. -I${JAVA_HOME}/include -I${JAVA_HOME}/include/${OSINCDIR} +LIBRARIES= +TARGET=libsignal.so + +# +# Target definitions + +all: ${TARGET} + +${TARGET}: com_threerings_util_signal_SignalManager.c + @echo "Compiling SignalManager.c" + @${CC} ${INCLUDES} -c com_threerings_util_signal_SignalManager.c \ + -o com_threerings_util_signal_SignalManager.o + @echo "Creating libsignal.so" + @${CC} -o ${TARGET} com_threerings_util_signal_SignalManager.o \ + ${LIBRARIES} ${LIBRARIES_PATH} -shared + +clean: + -${RM} -f *.o ${TARGET} diff --git a/src/java/com/threerings/util/signal/Linux/com_threerings_util_signal_SignalManager.c b/src/java/com/threerings/util/signal/Linux/com_threerings_util_signal_SignalManager.c new file mode 100644 index 000000000..a0852ad66 --- /dev/null +++ b/src/java/com/threerings/util/signal/Linux/com_threerings_util_signal_SignalManager.c @@ -0,0 +1,96 @@ +/** + * $Id: com_threerings_util_signal_SignalManager.c 3327 2005-02-03 01:02:58Z mdb $ + */ + +#include +#include +#include +#include + +#include +#include "com_threerings_util_signal_SignalManager.h" + +static int writefd; + +typedef void (*sighandler_t)(int); +static sighandler_t old_handlers[64]; +static sighandler_t handlers[64]; + +static void +signal_handler (int signo) +{ + write(writefd, &signo, sizeof(signo)); + signal(SIGINT, signal_handler); +} + +/** + * Class: com_threerings_util_signal_SignalManager + * Method: activateHandler + * Signature: (I)V + */ +JNIEXPORT void JNICALL +Java_com_threerings_util_signal_SignalManager_activateHandler ( + JNIEnv* env, jclass clazz, jint signo) +{ + old_handlers[signo] = signal(signo, signal_handler); + if (old_handlers[signo] == SIG_ERR) { + fprintf(stderr, "Error setting signal handler (%d): %s\n", + signo, strerror(errno)); + old_handlers[signo] = 0; + } else { + handlers[signo] = signal_handler; + } +} + +/** + * Class: com_threerings_util_signal_SignalManager + * Method: deactivateHandler + * Signature: (I)V + */ +JNIEXPORT void JNICALL +Java_com_threerings_util_signal_SignalManager_deactivateHandler ( + JNIEnv* env, jclass clazz, jint signo) +{ + if (old_handlers[signo] != 0) { + signal(signo, old_handlers[signo]); + old_handlers[signo] = 0; + handlers[signo] = 0; + } +} + +/** + * Class: com_threerings_util_signal_SignalManager + * Method: dispatchSignals + * Signature: ()V + */ +JNIEXPORT void JNICALL +Java_com_threerings_util_signal_SignalManager_dispatchSignals ( + JNIEnv* env, jclass clazz) +{ + int filedes[2], readfd; + jint signo; + jmethodID mid = (*env)->GetStaticMethodID( + env, clazz, "signalReceived", "(I)V"); + + if (pipe(filedes) < 0) { + fprintf(stderr, "Failed to create signal pipe: %s\n", strerror(errno)); + return; + } + readfd = filedes[0]; + writefd = filedes[1]; + + while (1) { + int got = read(readfd, &signo, sizeof(int)); + if (got < 0) { + fprintf(stderr, "Signal pipe read failed: %s\n", strerror(errno)); + } else if (got == 0) { + fprintf(stderr, "Signal pipe read returned zero bytes.\n"); + } else { + if (signo < 0 || signo >= 64 || handlers[signo] == 0) { + fprintf(stderr, "Received bogus signal (%d).\n", signo); + } else { + (*env)->CallStaticVoidMethod(env, clazz, mid, signo); + } + } + } +} diff --git a/src/java/com/threerings/util/signal/Linux/libsignal.so b/src/java/com/threerings/util/signal/Linux/libsignal.so new file mode 100755 index 000000000..769b3dbb5 Binary files /dev/null and b/src/java/com/threerings/util/signal/Linux/libsignal.so differ