commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mt...@apache.org
Subject 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...
Date Fri, 30 Jul 2010 06:50:16 GMT
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 <mailto:pier.fumagalli@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 <mailto:pier.fumagalli@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



Mime
View raw message