You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by mt...@apache.org on 2010/07/30 08:50:16 UTC
svn commit: r980662 [12/15] - in
/commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3: ./ src/ src/assembly/
src/docs/ src/java/ src/java/org/ src/java/org/apache/
src/java/org/apache/commons/ src/java/org/apache/commons/daemon/
src/java/org/apache/com...
Added: commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/java.c
URL: http://svn.apache.org/viewvc/commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/java.c?rev=980662&view=auto
==============================================================================
--- commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/java.c (added)
+++ commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/java.c Fri Jul 30 06:50:12 2010
@@ -0,0 +1,568 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* @version $Id: java.c 923123 2010-03-15 09:20:00Z mturk $ */
+#include "jsvc.h"
+
+#ifdef OS_CYGWIN
+typedef long long __int64;
+#endif
+#include <jni.h>
+
+#ifdef CHARSET_EBCDIC
+#ifdef OSD_POSIX
+#include <ascii_ebcdic.h>
+#define jsvc_xlate_to_ascii(b) _e2a(b)
+#define jsvc_xlate_from_ascii(b) _a2e(b)
+#endif
+#else
+#define jsvc_xlate_to_ascii(b) /* NOOP */
+#define jsvc_xlate_from_ascii(b) /* NOOP */
+#endif
+
+static JavaVM *jvm = NULL;
+static JNIEnv *env = NULL;
+static jclass cls = NULL;
+
+#define FALSE 0
+#define TRUE !FALSE
+
+static void shutdown(JNIEnv *env, jobject source, jboolean reload)
+{
+ log_debug("Shutdown requested (reload is %d)", reload);
+ if (reload == TRUE)
+ main_reload();
+ else
+ main_shutdown();
+}
+
+static void failed(JNIEnv *env, jobject source, jstring message)
+{
+ if (message) {
+ const char *msg = (*env)->GetStringUTFChars(env, message, NULL);
+ log_error("Failed %s", msg ? msg : "(null)");
+ if (msg)
+ (*env)->ReleaseStringUTFChars(env, message, msg);
+ }
+ else
+ log_error("Failed requested");
+ main_shutdown();
+}
+
+/* Automatically restart when the JVM crashes */
+static void java_abort123(void)
+{
+ exit(123);
+}
+
+char *java_library(arg_data *args, home_data *data)
+{
+ char *libf = NULL;
+
+ /* Did we find ANY virtual machine? */
+ if (data->jnum == 0) {
+ log_error("Cannot find any VM in Java Home %s", data->path);
+ return NULL;
+ }
+
+ /* Select the VM */
+ if (args->name == NULL) {
+ libf = data->jvms[0]->libr;
+ log_debug("Using default JVM in %s", libf);
+ }
+ else {
+ int x;
+ for (x = 0; x < data->jnum; x++) {
+ if (data->jvms[x]->name == NULL)
+ continue;
+ if (strcmp(args->name, data->jvms[x]->name) == 0) {
+ libf = data->jvms[x]->libr;
+ log_debug("Using specific JVM in %s", libf);
+ break;
+ }
+ }
+ if (libf == NULL) {
+ log_error("Invalid JVM name specified %s", args->name);
+ return NULL;
+ }
+ }
+ return libf;
+}
+
+/* Initialize the JVM and its environment, loading libraries and all */
+bool java_init(arg_data *args, home_data *data)
+{
+#ifdef OS_DARWIN
+ dso_handle apph = NULL;
+ char appf[1024];
+ struct stat sb;
+#endif /* ifdef OS_DARWIN */
+ jint(*symb) (JavaVM **, JNIEnv **, JavaVMInitArgs *);
+ JNINativeMethod nativemethods[2];
+ JavaVMOption *opt = NULL;
+ dso_handle libh = NULL;
+ JavaVMInitArgs arg;
+ char *libf = NULL;
+ jint ret;
+ int x;
+ char loaderclass[] = LOADER;
+ char shutdownmethod[] = "shutdown";
+ char shutdownparams[] = "(Z)V";
+ char failedmethod[] = "failed";
+ char failedparams[] = "(Ljava/lang/String;)V";
+
+ /* Decide WHAT virtual machine we need to use */
+ libf = java_library(args, data);
+ if (libf == NULL) {
+ log_error("Cannot locate JVM library file");
+ return false;
+ }
+
+ /* Initialize the DSO library */
+ if (dso_init() != true) {
+ log_error("Cannot initialize the dynamic library loader");
+ return false;
+ }
+
+ /* Load the JVM library */
+#if defined(OSD_POSIX) || defined(HAVE_KAFFEVM)
+#else
+ libh = dso_link(libf);
+ if (libh == NULL) {
+ log_error("Cannot dynamically link to %s", libf);
+ log_error("%s", dso_error());
+ return false;
+ }
+ log_debug("JVM library %s loaded", libf);
+#endif
+
+#ifdef OS_DARWIN
+ /*
+ MacOS/X actually has two libraries, one with the REAL vm, and one for
+ the VM startup.
+ before JVM 1.4.1 The first one (libappshell.dyld) contains CreateVM
+ JVM 1.4.1 through 1.5.* The library name is libjvm_compat.dylib
+ starting with JVM 1.6 on OS X 10.6 the library name is libverify.dylib.
+ */
+ if (replace(appf, 1024, "$JAVA_HOME/../Libraries/libappshell.dylib",
+ "$JAVA_HOME", data->path) != 0) {
+ log_error("Cannot replace values in loader library");
+ return false;
+ }
+ if (stat(appf, &sb)) {
+ if (replace(appf, 1024, "$JAVA_HOME/../Libraries/libjvm_compat.dylib",
+ "$JAVA_HOME", data->path) != 0) {
+ log_error("Cannot replace values in loader library");
+ return false;
+ }
+ }
+ if (stat(appf, &sb)) {
+ if (replace(appf, 1024, "$JAVA_HOME/../Libraries/libverify.dylib",
+ "$JAVA_HOME", data->path) != 0) {
+ log_error("Cannot replace values in loader library");
+ return false;
+ }
+ }
+ apph = dso_link(appf);
+ if (apph == NULL) {
+ log_error("Cannot load required shell library %s", appf);
+ return false;
+ }
+ log_debug("Shell library %s loaded", appf);
+#endif /* ifdef OS_DARWIN */
+#if defined(OSD_POSIX) || defined(HAVE_KAFFEVM)
+ /* BS2000 and kaffe does not allow to call JNI_CreateJavaVM indirectly */
+#else
+ symb = dso_symbol(libh, "JNI_CreateJavaVM");
+ if (symb == NULL) {
+#ifdef OS_DARWIN
+ symb = dso_symbol(apph, "JNI_CreateJavaVM");
+ if (symb == NULL) {
+#endif /* ifdef OS_DARWIN */
+ log_error("Cannot find JVM library entry point");
+ return false;
+#ifdef OS_DARWIN
+ }
+#endif /* ifdef OS_DARWIN */
+ }
+ log_debug("JVM library entry point found (0x%08X)", symb);
+#endif
+
+ /* Prepare the VM initialization arguments */
+
+ /*
+ * Mac OS X Java will load JVM 1.3.1 instead of 1.4.2 if JNI_VERSION_1_2
+ * is specified. So use JNI_VERSION_1_4 if we can.
+ */
+#if defined(JNI_VERSION_1_4)
+ arg.version = JNI_VERSION_1_4;
+#else
+ arg.version = JNI_VERSION_1_2;
+#endif
+#if defined(OSD_POSIX) || defined(HAVE_KAFFEVM)
+
+#if defined(HAVE_KAFFEVM)
+ memset(&arg, 0, sizeof(arg));
+ arg.version = JNI_VERSION_1_4;
+#endif
+
+ if (JNI_GetDefaultJavaVMInitArgs(&arg) < 0) {
+ log_error("Cannot init default JVM default args");
+ return false;
+ }
+#endif
+ arg.ignoreUnrecognized = FALSE;
+ arg.nOptions = args->onum;
+ arg.nOptions++; /* Add abort code */
+ opt = (JavaVMOption *) malloc(arg.nOptions * sizeof(JavaVMOption));
+ for (x = 0; x < args->onum; x++) {
+ opt[x].optionString = strdup(args->opts[x]);
+ jsvc_xlate_to_ascii(opt[x].optionString);
+ opt[x].extraInfo = NULL;
+ }
+ opt[x].optionString = strdup("abort");
+ jsvc_xlate_to_ascii(opt[x].optionString);
+ opt[x].extraInfo = java_abort123;
+ arg.options = opt;
+
+ /* Do some debugging */
+ if (log_debug_flag == true) {
+ log_debug("+-- DUMPING JAVA VM CREATION ARGUMENTS -----------------");
+ log_debug("| Version: %#08x", arg.version);
+ log_debug("| Ignore Unrecognized Arguments: %s",
+ arg.ignoreUnrecognized == TRUE ? "True" : "False");
+ log_debug("| Extra options: %d", arg.nOptions);
+
+ for (x = 0; x < args->onum; x++) {
+ jsvc_xlate_from_ascii(opt[x].optionString);
+ log_debug("| \"%s\" (0x%08x)", opt[x].optionString,
+ opt[x].extraInfo);
+ jsvc_xlate_to_ascii(opt[x].optionString);
+ }
+ log_debug("+-------------------------------------------------------");
+ }
+
+ /* And finally create the Java VM */
+#if defined(OSD_POSIX) || defined(HAVE_KAFFEVM)
+ ret = JNI_CreateJavaVM(&jvm, &env, &arg);
+#else
+ ret = (*symb) (&jvm, &env, &arg);
+#endif
+ if (ret < 0) {
+ log_error("Cannot create Java VM");
+ return false;
+ }
+ log_debug("Java VM created successfully");
+
+ jsvc_xlate_to_ascii(loaderclass);
+ cls = (*env)->FindClass(env, loaderclass);
+ jsvc_xlate_from_ascii(loaderclass);
+ if (cls == NULL) {
+ log_error("Cannot find daemon loader %s", loaderclass);
+ return false;
+ }
+ log_debug("Class %s found", loaderclass);
+
+#if defined(HAVE_SABLEVM)
+ log_debug("sableVM doesn't support RegisterNatives");
+#else
+ jsvc_xlate_to_ascii(shutdownmethod);
+ nativemethods[0].name = shutdownmethod;
+ jsvc_xlate_to_ascii(shutdownparams);
+ nativemethods[0].signature = shutdownparams;
+ nativemethods[0].fnPtr = shutdown;
+ jsvc_xlate_to_ascii(failedmethod);
+ nativemethods[1].name = failedmethod;
+ jsvc_xlate_to_ascii(failedparams);
+ nativemethods[1].signature = failedparams;
+ nativemethods[1].fnPtr = failed;
+
+ if ((*env)->RegisterNatives(env, cls, nativemethods, 2) != 0) {
+ log_error("Cannot register native methods");
+ return false;
+ }
+ log_debug("Native methods registered");
+#endif
+
+ return true;
+}
+
+/* Destroy the Java VM */
+bool JVM_destroy(int exit)
+{
+ jclass system = NULL;
+ jmethodID method;
+ char System[] = "java/lang/System";
+ char exitclass[] = "exit";
+ char exitparams[] = "(I)V";
+
+ jsvc_xlate_to_ascii(System);
+ system = (*env)->FindClass(env, System);
+ jsvc_xlate_from_ascii(System);
+ if (system == NULL) {
+ log_error("Cannot find class %s", System);
+ return false;
+ }
+
+ jsvc_xlate_to_ascii(exitclass);
+ jsvc_xlate_to_ascii(exitparams);
+ method = (*env)->GetStaticMethodID(env, system, exitclass, exitparams);
+ if (method == NULL) {
+ log_error("Cannot find \"System.exit(int)\" entry point");
+ return false;
+ }
+
+ log_debug("Calling System.exit(%d)", exit);
+ (*env)->CallStaticVoidMethod(env, system, method, (jint) exit);
+
+ /* We shouldn't get here, but just in case... */
+ log_debug("Destroying the Java VM");
+ if ((*jvm)->DestroyJavaVM(jvm) != 0)
+ return false;
+ log_debug("Java VM destroyed");
+ return true;
+}
+
+/* Call the load method in our DaemonLoader class */
+bool java_load(arg_data *args)
+{
+ jclass stringClass = NULL;
+ jstring className = NULL;
+ jstring currentArgument = NULL;
+ jobjectArray stringArray = NULL;
+ jmethodID method = NULL;
+ jboolean ret = FALSE;
+ int x;
+ char lang[] = "java/lang/String";
+ char load[] = "load";
+ char loadparams[] = "(Ljava/lang/String;[Ljava/lang/String;)Z";
+
+ jsvc_xlate_to_ascii(args->clas);
+ className = (*env)->NewStringUTF(env, args->clas);
+ jsvc_xlate_from_ascii(args->clas);
+ if (className == NULL) {
+ log_error("Cannot create string for class name");
+ return false;
+ }
+
+ jsvc_xlate_to_ascii(lang);
+ stringClass = (*env)->FindClass(env, lang);
+ jsvc_xlate_from_ascii(lang);
+ if (stringClass == NULL) {
+ log_error("Cannot find class java/lang/String");
+ return false;
+ }
+
+ stringArray = (*env)->NewObjectArray(env, args->anum, stringClass, NULL);
+ if (stringArray == NULL) {
+ log_error("Cannot create arguments array");
+ return false;
+ }
+
+ for (x = 0; x < args->anum; x++) {
+ jsvc_xlate_to_ascii(args->args[x]);
+ currentArgument = (*env)->NewStringUTF(env, args->args[x]);
+ jsvc_xlate_from_ascii(args->args[x]);
+ if (currentArgument == NULL) {
+ log_error("Cannot create string for argument %s", args->args[x]);
+ return false;
+ }
+ (*env)->SetObjectArrayElement(env, stringArray, x, currentArgument);
+ }
+
+ jsvc_xlate_to_ascii(load);
+ jsvc_xlate_to_ascii(loadparams);
+ method = (*env)->GetStaticMethodID(env, cls, load, loadparams);
+ if (method == NULL) {
+ log_error("Cannot find Daemon Loader \"load\" entry point");
+ return false;
+ }
+
+ log_debug("Daemon loading...");
+ ret = (*env)->CallStaticBooleanMethod(env, cls, method, className,
+ stringArray);
+ if (ret == FALSE) {
+ log_error("Cannot load daemon");
+ return false;
+ }
+
+ log_debug("Daemon loaded successfully");
+ return true;
+}
+
+/* Call the start method in our daemon loader */
+bool java_start(void)
+{
+ jmethodID method;
+ jboolean ret;
+ char start[] = "start";
+ char startparams[] = "()Z";
+
+ jsvc_xlate_to_ascii(start);
+ jsvc_xlate_to_ascii(startparams);
+ method = (*env)->GetStaticMethodID(env, cls, start, startparams);
+ if (method == NULL) {
+ log_error("Cannot find Daemon Loader \"start\" entry point");
+ return false;
+ }
+
+ ret = (*env)->CallStaticBooleanMethod(env, cls, method);
+ if (ret == FALSE) {
+ log_error("Cannot start daemon");
+ return false;
+ }
+
+ log_debug("Daemon started successfully");
+ return true;
+}
+
+/*
+ * call the java sleep to prevent problems with threads
+ */
+void java_sleep(int wait)
+{
+ jclass clsThread;
+ jmethodID method;
+ char jsleep[] = "sleep";
+ char jsleepparams[] = "(J)V";
+ char jthread[] = "java/lang/Thread";
+
+ jsvc_xlate_to_ascii(jsleep);
+ jsvc_xlate_to_ascii(jsleepparams);
+ jsvc_xlate_to_ascii(jthread);
+
+ clsThread = (*env)->FindClass(env, jthread);
+ if (clsThread == NULL) {
+ log_error("Cannot find java/lang/Thread class");
+ return;
+ }
+ method = (*env)->GetStaticMethodID(env, clsThread, jsleep, jsleepparams);
+ if (method == NULL) {
+ log_error("Cannot found the sleep entry point");
+ return;
+ }
+
+ (*env)->CallStaticVoidMethod(env, clsThread, method, (jlong) wait * 1000);
+}
+
+/* Call the stop method in our daemon loader */
+bool java_stop(void)
+{
+ jmethodID method;
+ jboolean ret;
+ char stop[] = "stop";
+ char stopparams[] = "()Z";
+
+ jsvc_xlate_to_ascii(stop);
+ jsvc_xlate_to_ascii(stopparams);
+ method = (*env)->GetStaticMethodID(env, cls, stop, stopparams);
+ if (method == NULL) {
+ log_error("Cannot found Daemon Loader \"stop\" entry point");
+ return false;
+ }
+
+ ret = (*env)->CallStaticBooleanMethod(env, cls, method);
+ if (ret == FALSE) {
+ log_error("Cannot stop daemon");
+ return false;
+ }
+
+ log_debug("Daemon stopped successfully");
+ return true;
+}
+
+/* Call the version method in our daemon loader */
+bool java_version(void)
+{
+ jmethodID method;
+ char version[] = "version";
+ char versionparams[] = "()Z";
+
+ jsvc_xlate_to_ascii(version);
+ jsvc_xlate_to_ascii(versionparams);
+ method = (*env)->GetStaticMethodID(env, cls, version, versionparams);
+ if (method == NULL) {
+ log_error("Cannot found Daemon Loader \"version\" entry point");
+ return false;
+ }
+
+ (*env)->CallStaticVoidMethod(env, cls, method);
+ return true;
+}
+
+/* Call the check method in our DaemonLoader class */
+bool java_check(arg_data *args)
+{
+ jstring className = NULL;
+ jmethodID method = NULL;
+ jboolean ret = FALSE;
+ char check[] = "check";
+ char checkparams[] = "(Ljava/lang/String;)Z";
+
+ log_debug("Checking daemon");
+
+ jsvc_xlate_to_ascii(args->clas);
+ className = (*env)->NewStringUTF(env, args->clas);
+ jsvc_xlate_from_ascii(args->clas);
+ if (className == NULL) {
+ log_error("Cannot create string for class name");
+ return false;
+ }
+
+ jsvc_xlate_to_ascii(check);
+ jsvc_xlate_to_ascii(checkparams);
+ method = (*env)->GetStaticMethodID(env, cls, check, checkparams);
+ if (method == NULL) {
+ log_error("Cannot found Daemon Loader \"check\" entry point");
+ return false;
+ }
+
+ ret = (*env)->CallStaticBooleanMethod(env, cls, method, className);
+ if (ret == FALSE) {
+ log_error("An error was detected checking the %s daemon", args->clas);
+ return false;
+ }
+
+ log_debug("Daemon checked successfully");
+ return true;
+}
+
+/* Call the destroy method in our daemon loader */
+bool java_destroy(void)
+{
+ jmethodID method;
+ jboolean ret;
+ char destroy[] = "destroy";
+ char destroyparams[] = "()Z";
+
+ jsvc_xlate_to_ascii(destroy);
+ jsvc_xlate_to_ascii(destroyparams);
+ method = (*env)->GetStaticMethodID(env, cls, destroy, destroyparams);
+ if (method == NULL) {
+ log_error("Cannot found Daemon Loader \"destroy\" entry point");
+ return false;
+ }
+
+ ret = (*env)->CallStaticBooleanMethod(env, cls, method);
+ if (ret == FALSE) {
+ log_error("Cannot destroy daemon");
+ return false;
+ }
+
+ log_debug("Daemon destroyed successfully");
+ return true;
+}
+
Propchange: commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/java.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/java.h
URL: http://svn.apache.org/viewvc/commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/java.h?rev=980662&view=auto
==============================================================================
--- commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/java.h (added)
+++ commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/java.h Fri Jul 30 06:50:12 2010
@@ -0,0 +1,34 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* @version $Id: java.h 921765 2010-03-11 10:03:32Z mturk $ */
+#ifndef __JSVC_JAVA_H__
+#define __JSVC_JAVA_H__
+
+#define LOADER "org/apache/commons/daemon/support/DaemonLoader"
+
+char *java_library(arg_data *args, home_data *data);
+bool java_init(arg_data *args, home_data *data);
+bool java_destroy(void);
+bool java_load(arg_data *args);
+bool java_start(void);
+bool java_stop(void);
+bool java_version(void);
+bool java_check(arg_data *args);
+bool JVM_destroy(int exit);
+
+#endif /* __JSVC_JAVA_H__ */
+
Propchange: commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/java.h
------------------------------------------------------------------------------
svn:eol-style = native
Added: commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/jsvc-unix.c
URL: http://svn.apache.org/viewvc/commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/jsvc-unix.c?rev=980662&view=auto
==============================================================================
--- commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/jsvc-unix.c (added)
+++ commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/jsvc-unix.c Fri Jul 30 06:50:12 2010
@@ -0,0 +1,978 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* @version $Id: jsvc-unix.c 980512 2010-07-29 17:10:17Z mturk $ */
+#include "jsvc.h"
+
+#include <signal.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <pwd.h>
+#include <grp.h>
+#ifdef OS_LINUX
+#include <sys/prctl.h>
+#include <sys/syscall.h>
+#define _LINUX_FS_H
+#include <linux/capability.h>
+#ifdef HAVE_LIBCAP
+#include <sys/capability.h>
+#endif
+#endif
+#include <time.h>
+
+#ifdef OS_CYGWIN
+#include <sys/fcntl.h>
+#define F_ULOCK 0 /* Unlock a previously locked region */
+#define F_LOCK 1 /* Lock a region for exclusive use */
+#endif
+
+extern char **environ;
+
+static mode_t envmask; /* mask to create the files */
+
+pid_t controlled = 0; /* the child process pid */
+static bool stopping = false;
+static bool doreload = false;
+static void (*handler_int) (int) = NULL;
+static void (*handler_hup) (int) = NULL;
+static void (*handler_trm) (int) = NULL;
+
+#ifdef OS_CYGWIN
+/*
+ * File locking routine
+ */
+static int lockf(int fildes, int function, off_t size)
+{
+ struct flock buf;
+
+ switch (function) {
+ case F_LOCK:
+ buf.l_type = F_WRLCK;
+ break;
+ case F_ULOCK:
+ buf.l_type = F_UNLCK;
+ break;
+ default:
+ return -1;
+ }
+ buf.l_whence = 0;
+ buf.l_start = 0;
+ buf.l_len = size;
+
+ return fcntl(fildes, F_SETLK, &buf);
+}
+
+#endif
+
+static void handler(int sig)
+{
+ switch (sig) {
+ case SIGTERM:
+ log_debug("Caught SIGTERM: Scheduling a shutdown");
+ if (stopping == true) {
+ log_error("Shutdown or reload already scheduled");
+ }
+ else {
+ stopping = true;
+ }
+ break;
+ case SIGINT:
+ log_debug("Caught SIGINT: Scheduling a shutdown");
+ if (stopping == true) {
+ log_error("Shutdown or reload already scheduled");
+ }
+ else {
+ stopping = true;
+ }
+ break;
+ case SIGHUP:
+ log_debug("Caught SIGHUP: Scheduling a reload");
+ if (stopping == true) {
+ log_error("Shutdown or reload already scheduled");
+ }
+ else {
+ stopping = true;
+ doreload = true;
+ }
+ break;
+ default:
+ log_debug("Caught unknown signal %d", sig);
+ break;
+ }
+}
+
+/* user and group */
+static int set_user_group(char *user, int uid, int gid)
+{
+ if (user != NULL) {
+ if (setgid(gid) != 0) {
+ log_error("Cannot set group id for user '%s'", user);
+ return -1;
+ }
+ if (initgroups(user, gid) != 0) {
+ if (getuid() != uid) {
+ log_error("Cannot set supplement group list for user '%s'",
+ user);
+ return -1;
+ }
+ else
+ log_debug("Cannot set supplement group list for user '%s'",
+ user);
+ }
+ if (getuid() == uid) {
+ log_debug("No need to change user to '%s'!", user);
+ return 0;
+ }
+ if (setuid(uid) != 0) {
+ log_error("Cannot set user id for user '%s'", user);
+ return -1;
+ }
+ log_debug("user changed to '%s'", user);
+ }
+ return 0;
+}
+
+/* Set linux capability, user and group */
+#ifdef OS_LINUX
+#ifdef HAVE_LIBCAP
+static cap_value_t caps_std[] = {
+ CAP_NET_BIND_SERVICE,
+ CAP_SETUID,
+ CAP_SETGID,
+ CAP_DAC_READ_SEARCH,
+ CAP_DAC_OVERRIDE
+};
+
+static cap_value_t caps_min[] = {
+ CAP_NET_BIND_SERVICE,
+ CAP_DAC_READ_SEARCH,
+ CAP_DAC_OVERRIDE
+};
+
+#define CAPS 1
+#define CAPSMIN 2
+
+static int set_caps(int cap_type)
+{
+ cap_t c;
+ int ncap;
+ cap_value_t *caps;
+
+ if (cap_type == CAPS) {
+ ncap = sizeof(caps_std)/sizeof(cap_value_t);
+ caps = caps_std;
+ }
+ else {
+ ncap = sizeof(caps_min)/sizeof(cap_value_t);
+ caps = caps_min;
+ }
+ c = cap_init();
+ cap_clear(c);
+ cap_set_flag(c, CAP_EFFECTIVE, ncap, caps, CAP_SET);
+ cap_set_flag(c, CAP_INHERITABLE, ncap, caps, CAP_SET);
+ cap_set_flag(c, CAP_PERMITTED, ncap, caps, CAP_SET);
+ if (cap_set_proc(c) != 0) {
+ log_error("failed setting %s capabilities.",
+ cap_type == CAPS ? "default" : "min");
+ return -1;
+ }
+ cap_free(c);
+ if (cap_type == CAPS)
+ log_debug("increased capability set.");
+ else
+ log_debug("decreased capability set to min required.");
+ return 0;
+}
+
+#else /* !HAVE_LIBCAP */
+/* CAPSALL is to allow to read/write at any location */
+#define CAPSALL (1 << CAP_NET_BIND_SERVICE) + \
+ (1 << CAP_SETUID) + \
+ (1 << CAP_SETGID) + \
+ (1 << CAP_DAC_READ_SEARCH) + \
+ (1 << CAP_DAC_OVERRIDE)
+
+#define CAPSMAX (1 << CAP_NET_BIND_SERVICE) + \
+ (1 << CAP_DAC_READ_SEARCH) + \
+ (1 << CAP_DAC_OVERRIDE)
+
+/* That a more reasonable configuration */
+#define CAPS (1 << CAP_NET_BIND_SERVICE) + \
+ (1 << CAP_DAC_READ_SEARCH) + \
+ (1 << CAP_SETUID) + \
+ (1 << CAP_SETGID)
+
+/* probably the only one Java could use */
+#define CAPSMIN (1 << CAP_NET_BIND_SERVICE) + \
+ (1 << CAP_DAC_READ_SEARCH)
+
+#define LEGACY_CAP_VERSION 0x19980330
+static int set_caps(int caps)
+{
+ struct __user_cap_header_struct caphead;
+ struct __user_cap_data_struct cap;
+
+ memset(&caphead, 0, sizeof caphead);
+ caphead.version = LEGACY_CAP_VERSION;
+ caphead.pid = 0;
+ memset(&cap, 0, sizeof cap);
+ cap.effective = caps;
+ cap.permitted = caps;
+ cap.inheritable = caps;
+ if (syscall(__NR_capset, &caphead, &cap) < 0) {
+ log_error("set_caps: failed to set capabilities");
+ log_error("check that your kernel supports capabilities");
+ return -1;
+ }
+ return 0;
+}
+#endif
+
+static int linuxset_user_group(char *user, int uid, int gid)
+{
+ int caps_set = 0;
+ /* set capabilities enough for binding port 80 setuid/getuid */
+ if (getuid() == 0) {
+ if (set_caps(CAPS) != 0) {
+ if (getuid() != uid) {
+ log_error("set_caps(CAPS) failed");
+ return -1;
+ }
+ log_debug("set_caps(CAPS) failed");
+ }
+ /* make sure they are kept after setuid */
+ if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) < 0) {
+ log_error("prctl failed in linuxset_user_group");
+ return -1;
+ }
+ caps_set = 1;
+ }
+
+ /* set setuid/getuid */
+ if (set_user_group(user, uid, gid) != 0) {
+ log_error("set_user_group failed in linuxset_user_group");
+ return -1;
+ }
+
+ if (caps_set) {
+ /* set capability to binding port 80 read conf */
+ if (set_caps(CAPSMIN) != 0) {
+ if (getuid() != uid) {
+ log_error("set_caps(CAPSMIN) failed");
+ return -1;
+ }
+ log_debug("set_caps(CAPSMIN) failed");
+ }
+ }
+
+ return 0;
+}
+#endif
+
+
+static bool checkuser(char *user, uid_t * uid, gid_t * gid)
+{
+ struct passwd *pwds = NULL;
+ int status = 0;
+ pid_t pid = 0;
+
+ /* Do we actually _have_ to switch user? */
+ if (user == NULL)
+ return true;
+
+ pwds = getpwnam(user);
+ if (pwds == NULL) {
+ log_error("Invalid user name '%s' specified", user);
+ return false;
+ }
+
+ *uid = pwds->pw_uid;
+ *gid = pwds->pw_gid;
+
+ /* Validate the user name in another process */
+ pid = fork();
+ if (pid == -1) {
+ log_error("Cannot validate user name");
+ return false;
+ }
+
+ /* If we're in the child process, let's validate */
+ if (pid == 0) {
+ if (set_user_group(user, *uid, *gid) != 0)
+ exit(1);
+ /* If we got here we switched user/group */
+ exit(0);
+ }
+
+ while (waitpid(pid, &status, 0) != pid) {
+ /* Just wait */
+ }
+
+ /* The child must have exited cleanly */
+ if (WIFEXITED(status)) {
+ status = WEXITSTATUS(status);
+
+ /* If the child got out with 0 the user is ok */
+ if (status == 0) {
+ log_debug("User '%s' validated", user);
+ return true;
+ }
+ }
+
+ log_error("Error validating user '%s'", user);
+ return false;
+}
+
+#ifdef OS_CYGWIN
+static void cygwincontroller(void)
+{
+ raise(SIGTERM);
+}
+#endif
+static void controller(int sig)
+{
+ switch (sig) {
+ case SIGTERM:
+ case SIGINT:
+ case SIGHUP:
+ log_debug("Forwarding signal %d to process %d", sig, controlled);
+ kill(controlled, sig);
+ signal(sig, controller);
+ break;
+ default:
+ log_debug("Caught unknown signal %d", sig);
+ break;
+ }
+}
+
+/*
+ * Return the address of the current signal handler and set the new one.
+ */
+static void *signal_set(int sig, void *newHandler)
+{
+ void *hand;
+
+ hand = signal(sig, newHandler);
+#ifdef SIG_ERR
+ if (hand == SIG_ERR)
+ hand = NULL;
+#endif
+ if (hand == handler || hand == controller)
+ hand = NULL;
+ return (hand);
+}
+
+/*
+ * Check pid and if still running
+ */
+
+static int check_pid(arg_data *args)
+{
+ int fd;
+ FILE *pidf;
+ char buff[80];
+ pid_t pidn = getpid();
+ int i, pid;
+
+ fd = open(args->pidf, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
+ if (fd < 0) {
+ log_error("Cannot open PID file %s, PID is %d", args->pidf, pidn);
+ return -1;
+ }
+ else {
+ lockf(fd, F_LOCK, 0);
+ i = read(fd, buff, sizeof(buff));
+ if (i > 0) {
+ buff[i] = '\0';
+ pid = atoi(buff);
+ if (kill(pid, 0) == 0) {
+ log_error("Still running according to PID file %s, PID is %d",
+ args->pidf, pid);
+ lockf(fd, F_ULOCK, 0);
+ close(fd);
+ return 122;
+ }
+ }
+
+ /* skip writing the pid file if version or check */
+ if (args->vers != true && args->chck != true) {
+ lseek(fd, SEEK_SET, 0);
+ pidf = fdopen(fd, "r+");
+ fprintf(pidf, "%d\n", (int)getpid());
+ fflush(pidf);
+ lockf(fd, F_ULOCK, 0);
+ fclose(pidf);
+ close(fd);
+ }
+ else {
+ lockf(fd, F_ULOCK, 0);
+ close(fd);
+ }
+ }
+ return 0;
+}
+
+/*
+ * read the pid from the pidfile
+ */
+static int get_pidf(arg_data *args)
+{
+ int fd;
+ int i;
+ char buff[80];
+
+ fd = open(args->pidf, O_RDONLY, 0);
+ log_debug("get_pidf: %d in %s", fd, args->pidf);
+ if (fd < 0) {
+ /* something has gone wrong the JVM has stopped */
+ return -1;
+ }
+ lockf(fd, F_LOCK, 0);
+ i = read(fd, buff, sizeof(buff));
+ lockf(fd, F_ULOCK, 0);
+ close(fd);
+ if (i > 0) {
+ buff[i] = '\0';
+ i = atoi(buff);
+ log_debug("get_pidf: pid %d", i);
+ if (kill(i, 0) == 0)
+ return i;
+ }
+ return -1;
+}
+
+/*
+ * Check temporatory file created by controller
+ * /tmp/pid.jsvc_up
+ * Notes:
+ * we fork several times
+ * 1 - to be a daemon before the setsid(), the child is the controler process.
+ * 2 - to start the JVM in the child process. (whose pid is stored in pidfile).
+ */
+static int check_tmp_file(arg_data *args)
+{
+ int pid;
+ char buff[80];
+ int fd;
+
+ pid = get_pidf(args);
+ if (pid < 0)
+ return -1;
+ sprintf(buff, "/tmp/%d.jsvc_up", pid);
+ log_debug("check_tmp_file: %s", buff);
+ fd = open(buff, O_RDONLY);
+ if (fd == -1)
+ return -1;
+ close(fd);
+ return 0;
+}
+
+static void create_tmp_file(arg_data *args)
+{
+ char buff[80];
+ int fd;
+
+ sprintf(buff, "/tmp/%d.jsvc_up", (int)getpid());
+ log_debug("create_tmp_file: %s", buff);
+ fd = open(buff, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
+ if (fd != -1)
+ close(fd);
+}
+
+static void remove_tmp_file(arg_data *args)
+{
+ char buff[80];
+
+ sprintf(buff, "/tmp/%d.jsvc_up", (int)getpid());
+ log_debug("remove_tmp_file: %s", buff);
+ unlink(buff);
+}
+
+/*
+ * wait until jsvc create the I am ready file
+ * pid is the controller and args->pidf the JVM itself.
+ */
+static int wait_child(arg_data *args, int pid)
+{
+ int count = 10;
+ bool havejvm = false;
+ int fd;
+ char buff[80];
+ int i, status, waittime;
+
+ log_debug("wait_child %d", pid);
+ waittime = args->wait / 10;
+ if (waittime > 10) {
+ count = waittime;
+ waittime = 10;
+ }
+ while (count > 0) {
+ sleep(1);
+ /* check if the controler is still running */
+ if (waitpid(pid, &status, WNOHANG) == pid) {
+ if (WIFEXITED(status))
+ return (WEXITSTATUS(status));
+ else
+ return 1;
+ }
+
+ /* check if the pid file process exists */
+ fd = open(args->pidf, O_RDONLY);
+ if (fd < 0 && havejvm) {
+ /* something has gone wrong the JVM has stopped */
+ return 1;
+ }
+ lockf(fd, F_LOCK, 0);
+ i = read(fd, buff, sizeof(buff));
+ lockf(fd, F_ULOCK, 0);
+ close(fd);
+ if (i > 0) {
+ buff[i] = '\0';
+ i = atoi(buff);
+ if (kill(i, 0) == 0) {
+ /* the JVM process has started */
+ havejvm = true;
+ if (check_tmp_file(args) == 0) {
+ /* the JVM is started */
+ if (waitpid(pid, &status, WNOHANG) == pid) {
+ if (WIFEXITED(status))
+ return (WEXITSTATUS(status));
+ else
+ return 1;
+ }
+ return 0; /* ready JVM started */
+ }
+ }
+ }
+ sleep(waittime);
+ count--;
+ }
+ /* It takes more than the wait time to start,
+ * something must be wrong
+ */
+ return 1;
+}
+
+/*
+ * stop the running jsvc
+ */
+static int stop_child(arg_data *args)
+{
+ int pid = get_pidf(args);
+ int count = 10;
+
+ if (pid > 0) {
+ /* kill the process and wait until the pidfile has been
+ * removed by the controler
+ */
+ kill(pid, SIGTERM);
+ while (count > 0) {
+ sleep(6);
+ pid = get_pidf(args);
+ if (pid <= 0) {
+ /* JVM has stopped */
+ return 0;
+ }
+ count--;
+ }
+ }
+ return -1;
+}
+
+/*
+ * child process logic.
+ */
+
+static int child(arg_data *args, home_data *data, uid_t uid, gid_t gid)
+{
+ int ret = 0;
+
+ /* check the pid file */
+ ret = check_pid(args);
+ if (args->vers != true && args->chck != true) {
+ if (ret == 122)
+ return ret;
+ if (ret < 0)
+ return ret;
+ }
+
+ /* create a new process group to prevent kill 0 killing the monitor process */
+#if defined(OS_FREEBSD) || defined(OS_DARWIN)
+ setpgid(0, 0);
+#else
+ setpgrp();
+#endif
+
+#ifdef OS_LINUX
+ /* setuid()/setgid() only apply the current thread so we must do it now */
+ if (linuxset_user_group(args->user, uid, gid) != 0)
+ return 4;
+#endif
+ /* Initialize the Java VM */
+ if (java_init(args, data) != true) {
+ log_debug("java_init failed");
+ return 1;
+ }
+ else
+ log_debug("java_init done");
+
+ /* Check wether we need to dump the VM version */
+ if (args->vers == true) {
+ if (java_version() != true) {
+ return -1;
+ }
+ else
+ return 0;
+ }
+ /* Check wether we need to dump the VM version */
+ else if (args->vershow == true) {
+ if (java_version() != true) {
+ return 7;
+ }
+ }
+
+ /* Do we have to do a "check-only" initialization? */
+ if (args->chck == true) {
+ if (java_check(args) != true)
+ return 2;
+ printf("Service \"%s\" checked successfully\n", args->clas);
+ return 0;
+ }
+
+ /* Load the service */
+ if (java_load(args) != true) {
+ log_debug("java_load failed");
+ return 3;
+ }
+ else
+ log_debug("java_load done");
+
+ /* Downgrade user */
+#ifdef OS_LINUX
+ if (set_caps(0) != 0) {
+ log_debug("set_caps (0) failed");
+ return 4;
+ }
+#else
+ if (set_user_group(args->user, uid, gid) != 0)
+ return 4;
+#endif
+
+ /* Start the service */
+ umask(envmask);
+ if (java_start() != true) {
+ log_debug("java_start failed");
+ return 5;
+ }
+ else
+ log_debug("java_start done");
+
+ /* Install signal handlers */
+ handler_hup = signal_set(SIGHUP, handler);
+ handler_trm = signal_set(SIGTERM, handler);
+ handler_int = signal_set(SIGINT, handler);
+ controlled = getpid();
+
+ log_debug("Waiting for a signal to be delivered");
+ create_tmp_file(args);
+ while (!stopping) {
+#if defined(OSD_POSIX) || defined(HAVE_KAFFEVM)
+ java_sleep(60);
+ /* pause(); */
+#else
+ /* pause() is not threadsafe */
+ sleep(60);
+#endif
+ }
+ remove_tmp_file(args);
+ log_debug("Shutdown or reload requested: exiting");
+
+ /* Stop the service */
+ if (java_stop() != true)
+ return 6;
+
+ if (doreload == true)
+ ret = 123;
+ else
+ ret = 0;
+
+ /* Destroy the service */
+ java_destroy();
+
+ /* Destroy the Java VM */
+ if (JVM_destroy(ret) != true)
+ return 7;
+
+ return ret;
+}
+
+/*
+ * freopen close the file first and then open the new file
+ * that is not very good if we are try to trace the output
+ * note the code assumes that the errors are configuration errors.
+ */
+static FILE *loc_freopen(char *outfile, char *mode, FILE * stream)
+{
+ FILE *ftest;
+
+ ftest = fopen(outfile, mode);
+ if (ftest == NULL) {
+ fprintf(stderr, "Unable to redirect to %s\n", outfile);
+ return stream;
+ }
+ fclose(ftest);
+ return freopen(outfile, mode, stream);
+}
+
+/**
+ * Redirect stdin, stdout, stderr.
+ */
+static void set_output(char *outfile, char *errfile, bool redirectstdin)
+{
+ if (redirectstdin == true) {
+ freopen("/dev/null", "r", stdin);
+ }
+
+ log_debug("redirecting stdout to %s and stderr to %s", outfile, errfile);
+
+ /* make sure the debug goes out */
+ if (log_debug_flag == true && strcmp(errfile, "/dev/null") == 0)
+ return;
+
+ /* Handle malicious case here */
+ if (strcmp(outfile, "&2") == 0 && strcmp(errfile, "&1") == 0) {
+ outfile = "/dev/null";
+ }
+ if (strcmp(outfile, "&2") != 0) {
+ loc_freopen(outfile, "a", stdout);
+ }
+
+ if (strcmp(errfile, "&1") != 0) {
+ loc_freopen(errfile, "a", stderr);
+ }
+ else {
+ close(2);
+ dup(1);
+ }
+ if (strcmp(outfile, "&2") == 0) {
+ close(1);
+ dup(2);
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ arg_data *args = NULL;
+ home_data *data = NULL;
+ int status = 0;
+ pid_t pid = 0;
+ uid_t uid = 0;
+ gid_t gid = 0;
+ time_t laststart;
+
+ /* Parse command line arguments */
+ args = arguments(argc, argv);
+ if (args == NULL)
+ return 1;
+
+ /* Stop running jsvc if required */
+ if (args->stop == true)
+ return (stop_child(args));
+
+ /* Let's check if we can switch user/group IDs */
+ if (checkuser(args->user, &uid, &gid) == false)
+ return 1;
+
+ /* Retrieve JAVA_HOME layout */
+ data = home(args->home);
+ if (data == NULL)
+ return 1;
+
+ /* Check for help */
+ if (args->help == true) {
+ help(data);
+ return 0;
+ }
+
+#ifdef OS_LINUX
+ /* On some UNIX operating systems, we need to REPLACE this current
+ process image with another one (thru execve) to allow the correct
+ loading of VMs (notably this is for Linux). Set, replace, and go. */
+ if (strcmp(argv[0], args->procname) != 0) {
+ char *oldpath = getenv("LD_LIBRARY_PATH");
+ char *libf = java_library(args, data);
+ char *filename;
+ char buf[2048];
+ int ret;
+ char *tmp = NULL;
+ char *p1 = NULL;
+ char *p2 = NULL;
+
+ /*
+ * There is no need to change LD_LIBRARY_PATH
+ * if we were not able to find a path to libjvm.so
+ * (additionaly a strdup(NULL) cores dump on my machine).
+ */
+ if (libf != NULL) {
+ p1 = strdup(libf);
+ tmp = strrchr(p1, '/');
+ if (tmp != NULL)
+ tmp[0] = '\0';
+
+ p2 = strdup(p1);
+ tmp = strrchr(p2, '/');
+ if (tmp != NULL)
+ tmp[0] = '\0';
+
+ if (oldpath == NULL)
+ snprintf(buf, 2048, "%s:%s", p1, p2);
+ else
+ snprintf(buf, 2048, "%s:%s:%s", oldpath, p1, p2);
+
+ tmp = strdup(buf);
+ setenv("LD_LIBRARY_PATH", tmp, 1);
+
+ log_debug("Invoking w/ LD_LIBRARY_PATH=%s",
+ getenv("LD_LIBRARY_PATH"));
+ }
+
+ /* execve needs a full path */
+ ret = readlink("/proc/self/exe", buf, sizeof(buf) - 1);
+ if (ret <= 0)
+ strcpy(buf, argv[0]);
+ else
+ buf[ret] = '\0';
+
+ filename = buf;
+
+ argv[0] = args->procname;
+ execve(filename, argv, environ);
+ log_error("Cannot execute JSVC executor process (%s)", filename);
+ return 1;
+ }
+ log_debug("Running w/ LD_LIBRARY_PATH=%s", getenv("LD_LIBRARY_PATH"));
+#endif /* ifdef OS_LINUX */
+
+ /* If we have to detach, let's do it now */
+ if (args->dtch == true) {
+ pid = fork();
+ if (pid == -1) {
+ log_error("Cannot detach from parent process");
+ return 1;
+ }
+ /* If we're in the parent process */
+ if (pid != 0) {
+ if (args->wait >= 10)
+ return wait_child(args, pid);
+ else
+ return 0;
+ }
+#ifndef NO_SETSID
+ setsid();
+#endif
+ }
+
+ envmask = umask(0077);
+ set_output(args->outfile, args->errfile, args->redirectstdin);
+
+ /* We have to fork: this process will become the controller and the other
+ will be the child */
+ while ((pid = fork()) != -1) {
+ /* We forked (again), if this is the child, we go on normally */
+ if (pid == 0)
+ exit(child(args, data, uid, gid));
+ laststart = time(NULL);
+
+ /* We are in the controller, we have to forward all interesting signals
+ to the child, and wait for it to die */
+ controlled = pid;
+#ifdef OS_CYGWIN
+ SetTerm(cygwincontroller);
+#endif
+ signal(SIGHUP, controller);
+ signal(SIGTERM, controller);
+ signal(SIGINT, controller);
+
+ while (waitpid(pid, &status, 0) != pid) {
+ /* Waith for process */
+ }
+
+ /* The child must have exited cleanly */
+ if (WIFEXITED(status)) {
+ status = WEXITSTATUS(status);
+
+ /* Delete the pid file */
+ if (args->vers != true && args->chck != true && status != 122)
+ unlink(args->pidf);
+
+ /* If the child got out with 123 he wants to be restarted */
+ /* See java_abort123 (we use this return code to restart when the JVM aborts) */
+ if (status == 123) {
+ log_debug("Reloading service");
+ /* prevent looping */
+ if (laststart + 60 > time(NULL)) {
+ log_debug("Waiting 60 s to prevent looping");
+ sleep(60);
+ }
+ continue;
+ }
+ /* If the child got out with 0 he is shutting down */
+ if (status == 0) {
+ log_debug("Service shut down");
+ return 0;
+ }
+ /* Otherwise we don't rerun it */
+ log_error("Service exit with a return value of %d", status);
+ return 1;
+
+ }
+ else {
+ if (WIFSIGNALED(status)) {
+ log_error("Service killed by signal %d", WTERMSIG(status));
+ /* prevent looping */
+ if (laststart + 60 > time(NULL)) {
+ log_debug("Waiting 60 s to prevent looping");
+ sleep(60);
+ }
+ continue;
+ }
+ log_error("Service did not exit cleanly", status);
+ return 1;
+ }
+ }
+
+ /* Got out of the loop? A fork() failed then. */
+ log_error("Cannot decouple controller/child processes");
+ return 1;
+
+}
+
+void main_reload(void)
+{
+ log_debug("Killing self with HUP signal");
+ kill(controlled, SIGHUP);
+}
+
+void main_shutdown(void)
+{
+ log_debug("Killing self with TERM signal");
+ kill(controlled, SIGTERM);
+}
+
Propchange: commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/jsvc-unix.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/jsvc.h
URL: http://svn.apache.org/viewvc/commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/jsvc.h?rev=980662&view=auto
==============================================================================
--- commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/jsvc.h (added)
+++ commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/jsvc.h Fri Jul 30 06:50:12 2010
@@ -0,0 +1,55 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* @version $Id: jsvc.h 921756 2010-03-11 09:38:58Z mturk $ */
+#ifndef __JSVC_H__
+#define __JSVC_H__
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+/* Definitions for booleans */
+#ifdef OS_DARWIN
+#include <stdbool.h>
+#else
+typedef enum {
+ false,
+ true
+} bool;
+#endif
+
+#include "version.h"
+#include "debug.h"
+#include "arguments.h"
+#include "home.h"
+#include "location.h"
+#include "replace.h"
+#include "dso.h"
+#include "java.h"
+#include "help.h"
+#include "signals.h"
+#include "locks.h"
+
+int main(int argc, char *argv[]);
+void main_reload(void);
+void main_shutdown(void);
+
+#endif /* ifndef __JSVC_H__ */
+
Propchange: commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/jsvc.h
------------------------------------------------------------------------------
svn:eol-style = native
Added: commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/location.c
URL: http://svn.apache.org/viewvc/commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/location.c?rev=980662&view=auto
==============================================================================
--- commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/location.c (added)
+++ commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/location.c Fri Jul 30 06:50:12 2010
@@ -0,0 +1,151 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* @version $Id: location.c 921765 2010-03-11 10:03:32Z mturk $ */
+#include "jsvc.h"
+
+/* Locations of various JVM files. We have to deal with all this madness since
+ * we're not distributed togheter (yet!) with an official VM distribution. All
+ * this CRAP needs improvement, and based on the observation of default
+ * distributions of VMs and OSes. If it doesn't work for you, please report
+ * your VM layout (ls -laR) and system details (build/config.guess) so that we
+ * can improve the search algorithms.
+ */
+
+/* If JAVA_HOME is not defined we search this list of paths (OS-dependant)
+ * to find the default location of the JVM.
+ */
+char *location_home[] = {
+#if defined(OS_DARWIN)
+ "/System/Library/Frameworks/JavaVM.framework/Home",
+ "/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home/",
+#elif defined(OS_LINUX) || defined(OS_SOLARIS) || defined(OS_BSD)
+ "/usr/java",
+ "/usr/local/java",
+#elif defined(OS_CYGWIN)
+ "/cygdrive/c/WINNT/system32/java",
+#elif defined(OS_SYSV)
+ "/opt/java",
+ "/opt/java/jdk13",
+#elif defined(OS_TRU64)
+ "/usr/opt/java142",
+ "/usr/opt/java13",
+#elif defined(OS_HPUX)
+ "/opt/java1.4",
+ "/opt/java1.3",
+#endif
+ NULL,
+};
+
+/* The jvm.cfg file defines the VMs available for invocation. So far, on all
+ * all systems I've seen it's in $JAVA_HOME/lib. If this file is not found,
+ * then the "default" VMs (from location_jvm_default) is searched, otherwise,
+ * we're going to look thru the "configured" VMs (from lod_cfgvm) lying
+ * somewhere around JAVA_HOME. (Only two, I'm happy)
+ */
+char *location_jvm_cfg[] = {
+ "$JAVA_HOME/jre/lib/jvm.cfg", /* JDK */
+ "$JAVA_HOME/lib/jvm.cfg", /* JRE */
+ "$JAVA_HOME/jre/lib/" CPU "/jvm.cfg", /* JDK */
+ "$JAVA_HOME/lib/" CPU "/jvm.cfg", /* JRE */
+ NULL,
+};
+
+/* This is the list of "defaults" VM (searched when jvm.cfg is not found, as
+ * in the case of most JDKs 1.2.2
+ */
+char *location_jvm_default[] = {
+#if defined(OS_DARWIN)
+ "$JAVA_HOME/../Libraries/libjvm.dylib",
+#elif defined(OS_CYGWIN)
+ "$JAVA_HOME/jre/bin/classic/jvm.dll", /* Sun JDK 1.3 */
+ "$JAVA_HOME/jre/bin/client/jvm.dll", /* Sun JDK 1.4 */
+#elif defined(OS_LINUX) || defined(OS_SOLARIS) || defined(OS_BSD) || defined(OS_SYSV) || defined(OS_FREEBSD) || defined(OS_TRU64)
+#if defined(HAVE_SABLEVM)
+ "$JAVA_HOME/lib/libsablevm.so", /* sableVM */
+#endif
+#if defined(HAVE_KAFFEVM)
+ "$JAVA_HOME/jre/lib/" CPU "/libkaffevm.so", /* kaffe */
+#endif
+ "$JAVA_HOME/jre/lib/" CPU "/classic/libjvm.so", /* Sun JDK 1.2 */
+ "$JAVA_HOME/jre/lib/" CPU "/client/libjvm.so", /* Sun JDK 1.3 */
+ "$JAVA_HOME/jre/lib/" CPU "/libjvm.so", /* Sun JDK */
+ "$JAVA_HOME/lib/" CPU "/classic/libjvm.so", /* Sun JRE 1.2 */
+ "$JAVA_HOME/lib/" CPU "/client/libjvm.so", /* Sun JRE 1.3 */
+ "$JAVA_HOME/lib/" CPU "/libjvm.so", /* Sun JRE */
+ "$JAVA_HOME/jre/bin/" CPU "/classic/libjvm.so", /* IBM JDK 1.3 */
+ "$JAVA_HOME/jre/bin/" CPU "/libjvm.so", /* IBM JDK */
+ "$JAVA_HOME/bin/" CPU "/classic/libjvm.so", /* IBM JRE 1.3 */
+ "$JAVA_HOME/bin/" CPU "/libjvm.so", /* IBM JRE */
+ /* Those are "weirdos: if we got here, we're probably in troubles and
+ * we're not going to find anything, but hope never dies...
+ */
+ "$JAVA_HOME/jre/lib/" CPU "/classic/green_threads/libjvm.so",
+#if defined(OSD_POSIX)
+ "$JAVA_HOME/lib/s390/client/green_threads/libjvm.so",
+ "$JAVA_HOME/lib/sparc/client/green_threads/libjvm.so",
+#endif
+ "$JAVA_HOME/jre/lib/classic/libjvm.so",
+ "$JAVA_HOME/jre/lib/client/libjvm.so",
+ "$JAVA_HOME/jre/lib/libjvm.so",
+ "$JAVA_HOME/lib/classic/libjvm.so",
+ "$JAVA_HOME/lib/client/libjvm.so",
+ "$JAVA_HOME/lib/libjvm.so",
+ "$JAVA_HOME/jre/bin/classic/libjvm.so",
+ "$JAVA_HOME/jre/bin/client/libjvm.so",
+ "$JAVA_HOME/jre/bin/libjvm.so",
+ "$JAVA_HOME/bin/classic/libjvm.so",
+ "$JAVA_HOME/bin/client/libjvm.so",
+ "$JAVA_HOME/bin/libjvm.so",
+ "$JAVA_HOME/jre/lib/" CPU "/fast64/libjvm.so",
+ "$JAVA_HOME/jre/lib/" CPU "/fast32/libjvm.so",
+ "$JAVA_HOME/lib/" CPU "/fast64/libjvm.so",
+ "$JAVA_HOME/lib/" CPU "/fast32/libjvm.so",
+#elif defined(OS_HPUX)
+ "$JAVA_HOME/jre/lib/" CPU "/server/libjvm.sl",
+ "$JAVA_HOME/jre/lib/" CPU "/client/libjvm.sl",
+ "$JAVA_HOME/jre/lib/" CPU "/hotspot/libjvm.sl",
+ "$JAVA_HOME/jre/lib/" CPU "/classic/libjvm.sl",
+#endif
+ "/usr/lib/libgcj.so.7", /* gcc java libraries */
+ "/usr/lib/libgcj.so.6",
+ NULL,
+};
+
+/* This is the list of "configured" VM (searched when jvm.cfg is found, as
+ * in the case of most JDKs 1.3 (not IBM, for example), way easier than
+ * before, and lovely, indeed...
+ */
+char *location_jvm_configured[] = {
+#if defined(OS_DARWIN)
+ "$JAVA_HOME/../Libraries/lib$VM_NAME.dylib",
+#elif defined(OS_CYGWIN)
+ "$JAVA_HOME/jre/bin/$VM_NAME/jvm.dll", /* Sun JDK 1.3 */
+#elif defined(OS_LINUX) || defined(OS_SOLARIS) || defined(OS_BSD) || defined(OS_FREEBSD) || defined(OS_TRU64)
+ "$JAVA_HOME/jre/lib/" CPU "/$VM_NAME/libjvm.so", /* Sun JDK 1.3 */
+ "$JAVA_HOME/lib/" CPU "/$VM_NAME/libjvm.so", /* Sun JRE 1.3 */
+#elif defined(OS_HPUX)
+ "$JAVA_HOME/jre/lib/" CPU "/$VM_NAME/libjvm.sl",
+ "$JAVA_HOME/lib/" CPU "/$VM_NAME/libjvm.sl",
+#elif defined(OS_SYSV)
+ "$JAVA_HOME/jre/lib/" CPU "/$VM_NAME/dce_threads/libjvm.so",
+ "$JAVA_HOME/jre/lib/" CPU "/$VM_NAME/green_threads/libjvm.so",
+ "$JAVA_HOME/lib/" CPU "/$VM_NAME/dce_threads/libjvm.so",
+ "$JAVA_HOME/lib/" CPU "/$VM_NAME/green_threads/libjvm.so",
+#endif
+ NULL,
+};
+
Propchange: commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/location.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/location.h
URL: http://svn.apache.org/viewvc/commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/location.h?rev=980662&view=auto
==============================================================================
--- commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/location.h (added)
+++ commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/location.h Fri Jul 30 06:50:12 2010
@@ -0,0 +1,29 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* @version $Id: location.h 921765 2010-03-11 10:03:32Z mturk $ */
+#ifndef __JSVC_LOCATION_H__
+#define __JSVC_LOCATION_H__
+
+#include "jsvc.h"
+
+extern char *location_home[];
+extern char *location_jvm_cfg[];
+extern char *location_jvm_default[];
+extern char *location_jvm_configured[];
+
+#endif /* __JSVC_LOCATION_H__ */
+
Propchange: commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/location.h
------------------------------------------------------------------------------
svn:eol-style = native
Added: commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/locks.c
URL: http://svn.apache.org/viewvc/commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/locks.c?rev=980662&view=auto
==============================================================================
--- commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/locks.c (added)
+++ commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/locks.c Fri Jul 30 06:50:12 2010
@@ -0,0 +1,51 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* @version $Id: java.c 909069 2010-02-11 16:43:36Z mturk $ */
+
+/*
+ * as Cygwin does not support lockf, jsvc uses fcntl to emulate it.
+ */
+#ifdef OS_CYGWIN
+#include "jsvc.h"
+#include <sys/fcntl.h>
+
+/*
+ * File locking routine
+ */
+int lockf(int fildes, int function, off_t size)
+{
+ struct flock buf;
+
+ switch (function) {
+ case F_LOCK:
+ buf.l_type = F_WRLCK;
+ break;
+ case F_ULOCK:
+ buf.l_type = F_UNLCK;
+ break;
+ default:
+ return -1;
+ }
+ buf.l_whence = 0;
+ buf.l_start = 0;
+ buf.l_len = size;
+
+ return fcntl(fildes, F_SETLK, &buf);
+}
+
+#endif
+
Propchange: commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/locks.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/locks.h
URL: http://svn.apache.org/viewvc/commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/locks.h?rev=980662&view=auto
==============================================================================
--- commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/locks.h (added)
+++ commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/locks.h Fri Jul 30 06:50:12 2010
@@ -0,0 +1,40 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* @version $Id$ */
+#ifndef __JSVC_LOCKS_H__
+#define __JSVC_LOCKS_H__
+
+/*
+ * as Cygwin does not support locks, jsvc use NT API to emulate them.
+ */
+#ifdef OS_CYGWIN
+
+#define F_ULOCK 0 /* Unlock a previously locked region */
+#define F_LOCK 1 /* Lock a region for exclusive use */
+
+/*
+ * allow a file to be locked
+ * @param fildes an open file descriptor
+ * @param function a control value that specifies the action to be taken
+ * @param size number of bytes to lock
+ * @return Zero on success, a value less than 0 if an error was encountered
+ */
+int lockf(int fildes, int function, off_t size);
+
+#endif
+#endif /* __JSVC_LOCKS_H__ */
+
Propchange: commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/locks.h
------------------------------------------------------------------------------
svn:eol-style = native
Added: commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/replace.c
URL: http://svn.apache.org/viewvc/commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/replace.c?rev=980662&view=auto
==============================================================================
--- commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/replace.c (added)
+++ commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/replace.c Fri Jul 30 06:50:12 2010
@@ -0,0 +1,121 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* @version $Id: replace.c 921765 2010-03-11 10:03:32Z mturk $ */
+#include "jsvc.h"
+
+/* Replace all occurrences of a string in another */
+int replace(char *new, int len, char *old, char *mch, char *rpl)
+{
+ char *tmp;
+ int count;
+ int shift;
+ int nlen;
+ int olen;
+ int mlen;
+ int rlen;
+ int x;
+
+ /* The new buffer is NULL, fail */
+ if (new == NULL)
+ return -1;
+ /* The length of the buffer is less than zero, fail */
+ if (len < 0)
+ return -2;
+ /* The old buffer is NULL, fail */
+ if (old == NULL)
+ return -3;
+
+ /* The string to be matched is NULL or empty, simply copy */
+ if ((mch == NULL) || (strlen(mch) == 0)) {
+ olen = strlen(old);
+ if (len <= olen)
+ return (olen + 1);
+ strcpy(new, old);
+ return 0;
+ }
+
+ /* The string to be replaced is NULL, assume it's an empty string */
+ if (rpl == NULL)
+ rpl = "";
+
+ /* Evaluate some lengths */
+ olen = strlen(old);
+ mlen = strlen(mch);
+ rlen = strlen(rpl);
+
+ /* Calculate how many times the mch string appears in old */
+ tmp = old;
+ count = 0;
+ while ((tmp = strstr(tmp, mch)) != NULL) {
+ count++;
+ tmp += mlen;
+ }
+
+ /* We have no matches, simply copy */
+ if (count == 0) {
+ olen = strlen(old);
+ if (len <= olen)
+ return (olen + 1);
+ strcpy(new, old);
+ return 0;
+ }
+
+ /* Calculate how big the buffer must be to hold the translation
+ * and of how many bytes we need to shift the data
+ */
+ shift = rlen - mlen;
+ nlen = olen + (shift * count);
+ /* printf("Count=%d Shift= %d OLen=%d NLen=%d\n",count,shift,olen,nlen); */
+
+ /* Check if we have enough size in the buffer */
+ if (nlen >= len)
+ return (nlen + 1);
+
+ /* Copy over the old buffer in the new one (save memory) */
+ strcpy(new, old);
+
+ /* Start replacing */
+ tmp = new;
+ while ((tmp = strstr(tmp, mch)) != NULL) {
+ /* If shift is > 0 we need to move data from right to left */
+ if (shift > 0) {
+ for (x = (strlen(tmp) + shift); x > shift; x--) {
+ /*
+ printf("src %c(%d) dst %c(%d)\n",
+ tmp[x-shift],tmp[x-shift],tmp[x],tmp[x]);
+ */
+ tmp[x] = tmp[x - shift];
+ }
+ /* If shift is < 0 we need to move data from left to right */
+ }
+ else if (shift < 0) {
+ for (x = mlen; x < strlen(tmp) - shift; x++) {
+ /*
+ printf("src %c(%d) dst %c(%d)\n",
+ tmp[x],tmp[x],tmp[x+shift],tmp[x+shift]);
+ */
+ tmp[x + shift] = tmp[x];
+ }
+ }
+ /* If shift is = 0 we don't have to shift data */
+ strncpy(tmp, rpl, rlen);
+ tmp += rlen;
+ /* printf("\"%s\"\n",tmp); */
+ }
+ return 0;
+}
+
Propchange: commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/replace.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/replace.h
URL: http://svn.apache.org/viewvc/commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/replace.h?rev=980662&view=auto
==============================================================================
--- commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/replace.h (added)
+++ commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/replace.h Fri Jul 30 06:50:12 2010
@@ -0,0 +1,39 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* @version $Id: replace.h 921765 2010-03-11 10:03:32Z mturk $ */
+#ifndef __JSVC_REPLACE_H__
+#define __JSVC_REPLACE_H__
+
+/**
+ * Replace all occurrences of mch in old with the new string rpl, and
+ * stores the result in new, provided that its length (specified in len)
+ * is enough.
+ *
+ * @param new The buffer where the result of the replace operation will be
+ * stored into.
+ * @param len The length of the previous buffer.
+ * @param old The string where occurrences of mtch must be searched.
+ * @param mch The characters to match in old (and to be replaced)
+ * @param rpl The characters that will be replaced in place of mch.
+ * @return Zero on success, a value less than 0 if an error was encountered
+ * or a value greater than zero (indicating the required storage size
+ * for new) if the buffer was too short to hold the new string.
+ */
+int replace(char *new, int len, char *old, char *mch, char *rpl);
+
+#endif /* ifndef __JSVC_REPLACE_H__ */
+
Propchange: commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/replace.h
------------------------------------------------------------------------------
svn:eol-style = native
Added: commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/signals.c
URL: http://svn.apache.org/viewvc/commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/signals.c?rev=980662&view=auto
==============================================================================
--- commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/signals.c (added)
+++ commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/signals.c Fri Jul 30 06:50:12 2010
@@ -0,0 +1,103 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* @version $Id: signals.c 921765 2010-03-11 10:03:32Z mturk $ */
+
+/*
+ * as Windows does not support signal, jsvc uses events to emulate them.
+ * The supported signal is SIGTERM.
+ * The kills.c contains the kill logic.
+ */
+#ifdef OS_CYGWIN
+#include <windows.h>
+#include <stdio.h>
+static void (*HandleTerm) (void) = NULL; /* address of the handler routine. */
+
+/*
+ * Event handling routine
+ */
+void v_difthf(LPVOID par)
+{
+ HANDLE hevint; /* make a local copy because the parameter is shared! */
+
+ hevint = (HANDLE) par;
+
+ for (;;) {
+ if (WaitForSingleObject(hevint, INFINITE) == WAIT_FAILED) {
+ /* something have gone wrong. */
+ return; /* may be something more is needed. */
+ }
+
+ /* call the interrupt handler. */
+ if (HandleTerm == NULL)
+ return;
+ HandleTerm();
+ }
+}
+
+/*
+ * set a routine handler for the signal
+ * note that it cannot be used to change the signal handler
+ */
+int SetTerm(void (*func) (void))
+{
+ char Name[256];
+ HANDLE hevint, hthread;
+ DWORD ThreadId;
+ SECURITY_ATTRIBUTES sa;
+ SECURITY_DESCRIPTOR sd;
+
+ sprintf(Name, "TERM%ld", GetCurrentProcessId());
+
+ /*
+ * event cannot be inherited.
+ * the event is reseted to nonsignaled after the waiting thread is released.
+ * the start state is resetted.
+ */
+
+ /* Initialize the new security descriptor. */
+ InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
+
+ /* Add a NULL descriptor ACL to the security descriptor. */
+ SetSecurityDescriptorDacl(&sd, TRUE, (PACL) NULL, FALSE);
+
+ sa.nLength = sizeof(sa);
+ sa.lpSecurityDescriptor = &sd;
+ sa.bInheritHandle = TRUE;
+
+
+ /* It works also with NULL instead &sa!! */
+ hevint = CreateEvent(&sa, FALSE, FALSE, Name);
+
+ HandleTerm = func;
+
+ if (hevint == NULL)
+ return -1; /* failed */
+
+ /* create the thread to wait for event */
+ hthread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) v_difthf,
+ (LPVOID) hevint, 0, &ThreadId);
+ if (hthread == NULL) {
+ /* failed remove the event */
+ CloseHandle(hevint); /* windows will remove it. */
+ return -1;
+ }
+
+ CloseHandle(hthread); /* not needed */
+ return 0;
+}
+#endif
+
Propchange: commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/signals.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/signals.h
URL: http://svn.apache.org/viewvc/commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/signals.h?rev=980662&view=auto
==============================================================================
--- commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/signals.h (added)
+++ commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/signals.h Fri Jul 30 06:50:12 2010
@@ -0,0 +1,34 @@
+/*
+ Copyright 2001-2004 The Apache Software Foundation.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+/* @version $Id$ */
+#ifndef __JSVC_SIGNALS_H__
+#define __JSVC_SIGNALS_H__
+
+/*
+ * as Windows does not support signal, jsvc use event to emulate them.
+ * The supported signal is SIGTERM.
+ */
+#ifdef OS_CYGWIN
+/*
+ * set a routine handler for the signal
+ * note that it cannot be used to change the signal handler
+ * @param func The function to call on termination
+ * @return Zero on success, a value less than 0 if an error was encountered
+ */
+int SetTerm(void (*func) (void));
+
+#endif
+#endif /* ifndef __JSVC_SIGNALS_H__ */
Propchange: commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/signals.h
------------------------------------------------------------------------------
svn:eol-style = native
Added: commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/version.h
URL: http://svn.apache.org/viewvc/commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/version.h?rev=980662&view=auto
==============================================================================
--- commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/version.h (added)
+++ commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/version.h Fri Jul 30 06:50:12 2010
@@ -0,0 +1,63 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __VERSION_H__
+#define __VERSION_H__
+
+/**
+ * Major API changes that could cause compatibility problems for older
+ * programs such as structure size changes. No binary compatibility is
+ * possible across a change in the major version.
+ */
+#define JSVC_MAJOR_VERSION 1
+
+/**
+ * Minor API changes that do not cause binary compatibility problems.
+ * Should be reset to 0 when upgrading JSVC_MAJOR_VERSION
+ */
+#define JSVC_MINOR_VERSION 0
+
+/** patch level */
+#define JSVC_PATCH_VERSION 3
+
+/**
+ * This symbol is defined for internal, "development" copies of JSVC.
+ * This symbol will be #undef'd for releases.
+ */
+#define JSVC_IS_DEV_VERSION 0
+
+/** Properly quote a value as a string in the C preprocessor */
+#define JSVC_STRINGIFY(n) JSVC_STRINGIFY_HELPER(n)
+/** Helper macro for JSVC_STRINGIFY */
+#define JSVC_STRINGIFY_HELPER(n) #n
+
+
+/** The formatted string of APU's version */
+#define JSVC_VERSION_STRING \
+ JSVC_STRINGIFY(JSVC_MAJOR_VERSION) "." \
+ JSVC_STRINGIFY(JSVC_MINOR_VERSION) "." \
+ JSVC_STRINGIFY(JSVC_PATCH_VERSION) \
+ JSVC_IS_DEV_STRING
+
+/** Internal: string form of the "is dev" flag */
+#if JSVC_IS_DEV_VERSION
+#define JSVC_IS_DEV_STRING "-dev"
+#else
+#define JSVC_IS_DEV_STRING ""
+#endif
+
+#endif /* __VERSION_H__ */
+
Propchange: commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/native/version.h
------------------------------------------------------------------------------
svn:eol-style = native
Added: commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/support/apfunctions.m4
URL: http://svn.apache.org/viewvc/commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/support/apfunctions.m4?rev=980662&view=auto
==============================================================================
--- commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/support/apfunctions.m4 (added)
+++ commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/support/apfunctions.m4 Fri Jul 30 06:50:12 2010
@@ -0,0 +1,40 @@
+dnl
+dnl Licensed to the Apache Software Foundation (ASF) under one or more
+dnl contributor license agreements. See the NOTICE file distributed with
+dnl this work for additional information regarding copyright ownership.
+dnl The ASF licenses this file to You under the Apache License, Version 2.0
+dnl (the "License"); you may not use this file except in compliance with
+dnl the License. You may obtain a copy of the License at
+dnl
+dnl http://www.apache.org/licenses/LICENSE-2.0
+dnl
+dnl Unless required by applicable law or agreed to in writing, software
+dnl distributed under the License is distributed on an "AS IS" BASIS,
+dnl WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+dnl See the License for the specific language governing permissions and
+dnl limitations under the License.
+dnl
+
+dnl -------------------------------------------------------------------------
+dnl Author Pier Fumagalli <ma...@eng.sun.com>
+dnl Version $Id: apfunctions.m4 480469 2006-11-29 08:22:04Z bayard $
+dnl -------------------------------------------------------------------------
+
+AC_DEFUN(AP_MSG_HEADER,[
+ printf "*** %s ***\n" "$1" 1>&2
+ AC_PROVIDE([$0])
+])
+
+AC_DEFUN(AP_CANONICAL_HOST_CHECK,[
+ AC_MSG_CHECKING([cached host system type])
+ if { test x"${ac_cv_host_system_type+set}" = x"set" &&
+ test x"$ac_cv_host_system_type" != x"$host" ; }
+ then
+ AC_MSG_RESULT([$ac_cv_host_system_type])
+ AC_MSG_ERROR([remove the \"$cache_file\" file and re-run configure])
+ else
+ AC_MSG_RESULT(ok)
+ ac_cv_host_system_type="$host"
+ fi
+ AC_PROVIDE([$0])
+])
Propchange: commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/support/apfunctions.m4
------------------------------------------------------------------------------
svn:eol-style = native
Added: commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/support/apjava.m4
URL: http://svn.apache.org/viewvc/commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/support/apjava.m4?rev=980662&view=auto
==============================================================================
--- commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/support/apjava.m4 (added)
+++ commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/support/apjava.m4 Fri Jul 30 06:50:12 2010
@@ -0,0 +1,142 @@
+dnl
+dnl Licensed to the Apache Software Foundation (ASF) under one or more
+dnl contributor license agreements. See the NOTICE file distributed with
+dnl this work for additional information regarding copyright ownership.
+dnl The ASF licenses this file to You under the Apache License, Version 2.0
+dnl (the "License"); you may not use this file except in compliance with
+dnl the License. You may obtain a copy of the License at
+dnl
+dnl http://www.apache.org/licenses/LICENSE-2.0
+dnl
+dnl Unless required by applicable law or agreed to in writing, software
+dnl distributed under the License is distributed on an "AS IS" BASIS,
+dnl WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+dnl See the License for the specific language governing permissions and
+dnl limitations under the License.
+dnl
+
+dnl -------------------------------------------------------------------------
+dnl Author Pier Fumagalli <ma...@eng.sun.com>
+dnl Version $Id: apjava.m4 480469 2006-11-29 08:22:04Z bayard $
+dnl -------------------------------------------------------------------------
+
+AC_DEFUN([AP_PROG_JAVAC_WORKS],[
+ AC_CACHE_CHECK([wether the Java compiler ($JAVAC) works],ap_cv_prog_javac_works,[
+ echo "public class Test {}" > Test.java
+ $JAVAC $JAVACFLAGS Test.java > /dev/null 2>&1
+ if test $? -eq 0
+ then
+ rm -f Test.java Test.class
+ ap_cv_prog_javac_works=yes
+ else
+ rm -f Test.java Test.class
+ AC_MSG_RESULT(no)
+ AC_MSG_ERROR([installation or configuration problem: javac cannot compile])
+ fi
+ ])
+])
+
+dnl Check for JAVA compilers.
+AC_DEFUN([AP_PROG_JAVAC],[
+ if test "$SABLEVM" != "NONE"
+ then
+ AC_PATH_PROG(JAVACSABLE,javac-sablevm,NONE,$JAVA_HOME/bin)
+ else
+ JAVACSABLE="NONE"
+ fi
+ if test "$JAVACSABLE" = "NONE"
+ then
+ XPATH="$JAVA_HOME/bin:$JAVA_HOME/Commands:$PATH"
+ AC_PATH_PROG(JAVAC,javac,NONE,$XPATH)
+ else
+ AC_PATH_PROG(JAVAC,javac-sablevm,NONE,$JAVA_HOME/bin)
+ fi
+ AC_MSG_RESULT([$JAVAC])
+ if test "$JAVAC" = "NONE"
+ then
+ AC_MSG_ERROR([javac not found])
+ fi
+ AP_PROG_JAVAC_WORKS()
+ AC_PROVIDE([$0])
+ AC_SUBST(JAVAC)
+ AC_SUBST(JAVACFLAGS)
+])
+
+dnl Check for jar archivers.
+AC_DEFUN([AP_PROG_JAR],[
+ if test "$SABLEVM" != "NONE"
+ then
+ AC_PATH_PROG(JARSABLE,jar-sablevm,NONE,$JAVA_HOME/bin)
+ else
+ JARSABLE="NONE"
+ fi
+ if test "$JARSABLE" = "NONE"
+ then
+ XPATH="$JAVA_HOME/bin:$JAVA_HOME/Commands:$PATH"
+ AC_PATH_PROG(JAR,jar,NONE,$XPATH)
+ else
+ AC_PATH_PROG(JAR,jar-sablevm,NONE,$JAVA_HOME/bin)
+ fi
+ if test "$JAR" = "NONE"
+ then
+ AC_MSG_ERROR([jar not found])
+ fi
+ AC_PROVIDE([$0])
+ AC_SUBST(JAR)
+])
+
+AC_DEFUN([AP_JAVA],[
+ AC_ARG_WITH(java,[ --with-java=DIR Specify the location of your JDK installation],[
+ AC_MSG_CHECKING([JAVA_HOME])
+ if test -d "$withval"
+ then
+ JAVA_HOME="$withval"
+ AC_MSG_RESULT([$JAVA_HOME])
+ else
+ AC_MSG_RESULT([failed])
+ AC_MSG_ERROR([$withval is not a directory])
+ fi
+ AC_SUBST(JAVA_HOME)
+ ])
+ if test x"$JAVA_HOME" = x
+ then
+ AC_MSG_ERROR([Java Home not defined. Rerun with --with-java=[...] parameter])
+ fi
+])
+
+dnl check if the JVM in JAVA_HOME is sableVM
+dnl $JAVA_HOME/bin/sablevm and /opt/java/lib/sablevm/bin are tested.
+AC_DEFUN([AP_SABLEVM],[
+ if test x"$JAVA_HOME" != x
+ then
+ AC_PATH_PROG(SABLEVM,sablevm,NONE,$JAVA_HOME/bin)
+ if test "$SABLEVM" = "NONE"
+ then
+ dnl java may be SableVM.
+ if $JAVA_HOME/bin/java -version 2> /dev/null | grep SableVM > /dev/null
+ then
+ SABLEVM=$JAVA_HOME/bin/java
+ fi
+ fi
+ if test "$SABLEVM" != "NONE"
+ then
+ AC_MSG_RESULT([Using sableVM: $SABLEVM])
+ CFLAGS="$CFLAGS -DHAVE_SABLEVM"
+ fi
+ fi
+])
+
+dnl check if the JVM in JAVA_HOME is kaffe
+dnl $JAVA_HOME/bin/kaffe is tested.
+AC_DEFUN([AP_KAFFE],[
+ if test x"$JAVA_HOME" != x
+ then
+ AC_PATH_PROG(KAFFEVM,kaffe,NONE,$JAVA_HOME/bin)
+ if test "$KAFFEVM" != "NONE"
+ then
+ AC_MSG_RESULT([Using kaffe: $KAFFEVM])
+ CFLAGS="$CFLAGS -DHAVE_KAFFEVM"
+ LDFLAGS="$LDFLAGS -Wl,-rpath $JAVA_HOME/jre/lib/$HOST_CPU -L $JAVA_HOME/jre/lib/$HOST_CPU -lkaffevm"
+ fi
+ fi
+])
Propchange: commons/proper/daemon/tags/COMMONS_DAEMON_1_0_3_RC3/src/native/unix/support/apjava.m4
------------------------------------------------------------------------------
svn:eol-style = native