diff options
author | mharmsen <mharmsen@c9f7a03b-bd48-0410-a16d-cbbf54688b0b> | 2011-10-04 01:17:41 +0000 |
---|---|---|
committer | mharmsen <mharmsen@c9f7a03b-bd48-0410-a16d-cbbf54688b0b> | 2011-10-04 01:17:41 +0000 |
commit | a4682ceae6774956461edd03b2485bbacea445f4 (patch) | |
tree | 94c475a125441da63101738220ce3972cf37db61 /pki/base/osutil/src/com/netscape/osutil/Signal.c | |
parent | 0c775428675d2cb1be9551f84e6b741ca813f77e (diff) | |
download | pki-a4682ceae6774956461edd03b2485bbacea445f4.tar.gz pki-a4682ceae6774956461edd03b2485bbacea445f4.tar.xz pki-a4682ceae6774956461edd03b2485bbacea445f4.zip |
Bugzilla Bug #688225 - (dogtagIPAv2.1) TRACKER: of the Dogtag fixes for freeIPA 2.1IPA_v2_RHEL_6_2_20111003
git-svn-id: svn+ssh://svn.fedorahosted.org/svn/pki/tags/IPA_v2_RHEL_6_2_20111003@2252 c9f7a03b-bd48-0410-a16d-cbbf54688b0b
Diffstat (limited to 'pki/base/osutil/src/com/netscape/osutil/Signal.c')
-rw-r--r-- | pki/base/osutil/src/com/netscape/osutil/Signal.c | 272 |
1 files changed, 272 insertions, 0 deletions
diff --git a/pki/base/osutil/src/com/netscape/osutil/Signal.c b/pki/base/osutil/src/com/netscape/osutil/Signal.c new file mode 100644 index 000000000..64bd28089 --- /dev/null +++ b/pki/base/osutil/src/com/netscape/osutil/Signal.c @@ -0,0 +1,272 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2007 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- +#include <jni.h> +#include "com_netscape_osutil_Signal.h" +#include "unixdefs.h" +#include <signal.h> +#include <errno.h> + +#ifndef MAXSIG +#define MAXSIG 33 +#endif + +/* + * These are declared as syncronized funtions in the Java code, + * so this isn't needed. + */ +#define ENTER_MONITOR /* (*env)->MonitorEnter(obj) */ +#define EXIT_MONITOR /* (*env)->MonitorExit(obj) */ + +typedef struct { + jobject listener; + JavaVM *vm; + int watched; + int count; + struct sigaction oact; +} SigWatch; + +/* Good thing there's only one signal handler per processes */ +static SigWatch sig_watch[MAXSIG]; + +static void +sig_count(int signo) +{ + JNIEnv *env = NULL; + jobject listener = NULL; + jclass listenerClass = NULL; + jmethodID methodId = NULL; + jint status; + JavaVM *vm; + void *penv; + + sig_watch[signo-1].count++; + listener = sig_watch[signo-1].listener; + vm = sig_watch[signo-1].vm; + + status = (*vm)->AttachCurrentThread(vm, &penv, NULL); + if (status != 0) { + printf("XXX bad attaching\n"); + } + env = (JNIEnv *)penv; + listenerClass = (*env)->GetObjectClass(env, listener); + if (listenerClass == NULL) { + printf("XXX null listener\n"); + } + methodId = (*env)->GetMethodID(env, listenerClass, + "process", "()V"); + if (methodId == NULL) { + printf("XXX null process\n"); + } + (*env)->CallVoidMethod(env, listener, methodId); +} + +/* + * Check for a valid signal number. Throw IllegalArgumentException if so. + * This really shouldn't happen since the Java code protects us. + */ +static int +valid_signo(JNIEnv *env, int signo) +{ + jclass illExc; + + if (signo <= MAXSIG && signo > 0) + return 1; + + illExc = (*env)->FindClass(env, "java/lang/IllegalArgumentException"); + if (illExc == 0) /* Unable to find the new exception class, give up. */ + return 0; + (*env)->ThrowNew(env, illExc, "bad signal number"); + return 0; +} + +/** + * Associates callback with signal. This obsoletes all + * the functions below. + */ +JNIEXPORT void JNICALL +Java_com_netscape_osutil_Signal_addSignalListener(JNIEnv *env, + jclass cls, jint signo, jobject listener) +{ + struct sigaction act; + SigWatch *sw; + JavaVM *vmBuf[1]; +#if 0 + jsize nVMs; +#endif + + + if (!valid_signo(env, signo)) + return; + + sw = &sig_watch[signo-1]; + + if (sw->watched) { + EXIT_MONITOR + return; /* Already being watched */ + } + + sw->watched = 1; + sw->listener = (*env)->NewGlobalRef(env, listener); +#if 0 + /* IBM JRE1.5 does not like this, and I dont think we + are using this file anyway. So I've commented this out */ + JNI_GetCreatedJavaVMs(vmBuf, 1, &nVMs); +#endif + sw->vm = vmBuf[0]; + + sw->count = 0; + act.sa_flags = SA_RESTART; + sigemptyset(&act.sa_mask); + act.sa_handler = sig_count; + sigaction(signo, &act, &sw->oact); + + EXIT_MONITOR +} + +/* + * Class: com_netscape_osutil_Signal + * Method: watch + * Signature: (I)V + * + * Add a signal handler to count the number of signals recieved. + * + */ +JNIEXPORT void JNICALL +Java_com_netscape_osutil_Signal_watch(JNIEnv *env, jclass cls, + jint signo) +{ + struct sigaction act; + SigWatch *sw; + + if (!valid_signo(env, signo)) + return; + + sw = &sig_watch[signo-1]; + + if (sw->watched) { + EXIT_MONITOR + return; /* Already being watched */ + } + + sw->watched = 1; + sw->listener = NULL; + sw->vm = NULL; + + sw->count = 0; + act.sa_flags = SA_RESTART; + sigemptyset(&act.sa_mask); + act.sa_handler = sig_count; + sigaction(signo, &act, &sw->oact); + + EXIT_MONITOR + +} + + +/* + * Class: com_netscape_certsrv_unix_Signal + * Method: release + * Signature: (I)V + * + * Restore whatever signal handler was present before the watch call. + */ +JNIEXPORT void JNICALL +Java_com_netscape_osutil_Signal_release(JNIEnv *env, jclass cls, + jint signo) +{ + SigWatch *sw; + + if (!valid_signo(env, signo)) + return; + + sw = &sig_watch[signo-1]; + + ENTER_MONITOR + + if (!sw->watched) { + EXIT_MONITOR + return; /* not being watched */ + } + + sw->watched = 0; + sw->count = 0; + sigaction(signo, &sw->oact, NULL); + + EXIT_MONITOR +} + +/* + * Class: com_netscape_certsrv_unix_Signal + * Method: caught + * Signature: (I)I + * + * Return the number of signals caught. Resets the count to 0 + */ +JNIEXPORT jint JNICALL +Java_com_netscape_osutil_Signal_caught(JNIEnv *env, jclass cls, + jint signo) +{ + int count; + SigWatch *sw; + + if (!valid_signo(env, signo)) + return 0; + + sw = &sig_watch[signo-1]; + + if (!sw->watched) { + return 0; /* not being watched */ + } + + /* + * The usefulness of multiple threads using this interface + * is questionable. This just guarantees some consistency + */ + ENTER_MONITOR + count = sw->count; + sw->count = 0; + EXIT_MONITOR + + return count; +} + +/* + * Class: com_netscape_certsrv_unix_Signal + * Method: send + * Signature: (II)I + * + * Send a signal to a process + */ +JNIEXPORT void JNICALL +Java_com_netscape_osutil_Signal_send(JNIEnv *env, jclass cls, jint pid, + jint signo) +{ + valid_signo(env, signo); + if (kill(pid, signo) != 0) { + switch (errno) { + case EINVAL: + unix_throw_exception(env, ILLARG, "invalid signal"); + break; + case EPERM: + unix_throw_exception(env, SECURITY, "permission denied"); + break; + } + } +} + + |