// natRuntime.cc - Implementation of native side of Runtime class.

/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006  Free Software Foundation

   This file is part of libgcj.

This software is copyrighted work licensed under the terms of the
Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
details.  */

#include <config.h>
#include <platform.h>

#include <stdlib.h>

#include <gcj/cni.h>
#include <jvm.h>
#include <java-props.h>
#include <java-stack.h>
#include <java/lang/Long.h>
#include <java/lang/Runtime.h>
#include <java/lang/UnknownError.h>
#include <java/lang/UnsatisfiedLinkError.h>
#include <gnu/gcj/runtime/FinalizerThread.h>
#include <java/io/File.h>
#include <java/util/TimeZone.h>
#include <java/lang/StringBuffer.h>
#include <java/lang/Process.h>
#include <java/lang/ConcreteProcess.h>
#include <java/lang/ClassLoader.h>

#include <jni.h>

#ifdef HAVE_PWD_H
#include <pwd.h>
#endif
#include <errno.h>

#ifdef HAVE_LOCALE_H
#include <locale.h>
#endif

#ifdef HAVE_LANGINFO_H
#include <langinfo.h>
#endif



#ifdef USE_LTDL
#include <ltdl.h>

/* FIXME: we don't always need this.  The next libtool will let us use
   AC_LTDL_PREOPEN to see if we do.  */
extern const lt_dlsymlist lt_preloaded_symbols[1] = { { 0, 0 } };

struct lookup_data
{
  const char *symname;
  void *result;
};

static int
find_symbol (lt_dlhandle handle, lt_ptr data)
{
  lookup_data *ld = (lookup_data *) data;
  ld->result = lt_dlsym (handle, ld->symname);
  return ld->result != NULL;
}

void *
_Jv_FindSymbolInExecutable (const char *symname)
{
  lookup_data data;
  data.symname = symname;
  data.result = NULL;
  lt_dlforeach (find_symbol, (lt_ptr) &data);
  return data.result;
}

#else

void *
_Jv_FindSymbolInExecutable (const char *)
{
  return NULL;
}

#endif /* USE_LTDL */



void
java::lang::Runtime::runFinalizationForExit ()
{
  if (finalizeOnExit)
    _Jv_RunAllFinalizers ();
}

void
java::lang::Runtime::exitInternal (jint status)
{
  // Make status right for Unix.  This is perhaps strange.
  if (status < 0 || status > 255)
    status = 255;

  ::exit (status);
}

jlong
java::lang::Runtime::freeMemory (void)
{
  return _Jv_GCFreeMemory ();
}

void
java::lang::Runtime::gc (void)
{
  _Jv_RunGC ();
}

#ifdef USE_LTDL
// List of names for JNI_OnLoad.
static const char *onload_names[] = _Jv_platform_onload_names;
#endif

void
java::lang::Runtime::_load (jstring path, jboolean do_search)
{
  JvSynchronize sync (this);
  using namespace java::lang;
#ifdef USE_LTDL
  jint len = _Jv_GetStringUTFLength (path);
  char buf[len + 1 + strlen (_Jv_platform_solib_prefix)
	   + strlen (_Jv_platform_solib_suffix)];
  int offset = 0;
  if (do_search)
    {
      strcpy (buf, _Jv_platform_solib_prefix);
      offset = strlen (_Jv_platform_solib_prefix);
    }
  jsize total = JvGetStringUTFRegion (path, 0, path->length(), &buf[offset]);
  buf[offset + total] = '\0';

  char *lib_name = buf;

  if (do_search)
    {
      ClassLoader *look = _Jv_StackTrace::GetFirstNonSystemClassLoader ();

      if (look != NULL)
	{
	  // Don't include solib prefix in string passed to
	  // findLibrary.
	  jstring name = look->findLibrary(JvNewStringUTF(&buf[offset]));
	  if (name != NULL)
	    {
	      len = _Jv_GetStringUTFLength (name);
	      lib_name = (char *) _Jv_AllocBytes(len + 1);
	      total = JvGetStringUTFRegion (name, 0,
					    name->length(), lib_name);
	      lib_name[total] = '\0';
	      // Don't append suffixes any more; we have the full file
	      // name.
	      do_search = false;
	    }
	}
    }

  lt_dlhandle h;
  // FIXME: make sure path is absolute.
  {
    // Synchronize on java.lang.Class. This is to protect the class chain from
    // concurrent modification by class registration calls which may be run
    // during the dlopen().
    JvSynchronize sync (&java::lang::Class::class$);
    h = do_search ? lt_dlopenext (lib_name) : lt_dlopen (lib_name);
  }
  if (h == NULL)
    {
      const char *msg = lt_dlerror ();
      jstring str = JvNewStringLatin1 (lib_name);
      str = str->concat (JvNewStringLatin1 (": "));
      str = str->concat (JvNewStringLatin1 (msg));
      throw new UnsatisfiedLinkError (str);
    }

  // Search for JNI_OnLoad function.
  void *onload = NULL;
  const char **name = onload_names;
  while (*name != NULL)
    {
      onload = lt_dlsym (h, *name);
      if (onload != NULL)
	break;
      ++name;
    }

  if (onload != NULL)
    {
      JavaVM *vm = _Jv_GetJavaVM ();
      if (vm == NULL)
	{
	  // FIXME: what?
	  return;
	}

      // Push a new frame so that JNI_OnLoad will get the right class
      // loader if it calls FindClass.
      ::java::lang::ClassLoader *loader
	  = _Jv_StackTrace::GetFirstNonSystemClassLoader();
      JNIEnv *env = _Jv_GetJNIEnvNewFrameWithLoader (loader);
      jint vers = ((jint (JNICALL *) (JavaVM *, void *)) onload) (vm, NULL);
      _Jv_JNI_PopSystemFrame (env);
      if (vers != JNI_VERSION_1_1 && vers != JNI_VERSION_1_2
	  && vers != JNI_VERSION_1_4)
	{
	  // FIXME: unload the library.
	  throw new UnsatisfiedLinkError (JvNewStringLatin1 ("unrecognized version from JNI_OnLoad"));
	}
    }
#else
  throw new UnknownError
    (JvNewStringLatin1 (do_search
			? "Runtime.loadLibrary not implemented"
			: "Runtime.load not implemented"));
#endif /* USE_LTDL */
}

jboolean
java::lang::Runtime::loadLibraryInternal (jstring lib)
{
  JvSynchronize sync (this);
  using namespace java::lang;
#ifdef USE_LTDL
  jint len = _Jv_GetStringUTFLength (lib);
  char buf[len + 1];
  jsize total = JvGetStringUTFRegion (lib, 0, lib->length(), buf);
  buf[total] = '\0';
  // FIXME: make sure path is absolute.
  lt_dlhandle h = lt_dlopenext (buf);
  return h != NULL;
#else
  return false;
#endif /* USE_LTDL */
}

void
java::lang::Runtime::init (void)
{
#ifdef USE_LTDL
  lt_dlinit ();
  // Set module load path.
  lt_dlsetsearchpath (_Jv_Module_Load_Path);
  // Make sure self is opened.
  lt_dlopen (NULL);
#endif
}

void
java::lang::Runtime::runFinalization (void)
{
  gnu::gcj::runtime::FinalizerThread::finalizerReady ();
}

jlong
java::lang::Runtime::totalMemory (void)
{
  return _Jv_GCTotalMemory ();
}

jlong
java::lang::Runtime::maxMemory (void)
{
  // We don't have a maximum.  FIXME: we might if we ask the GC for
  // one.
  return Long::MAX_VALUE;
}

void
java::lang::Runtime::traceInstructions (jboolean)
{
  // Do nothing.
}

void
java::lang::Runtime::traceMethodCalls (jboolean)
{
  // Do nothing.
}

java::lang::Process *
java::lang::Runtime::execInternal (jstringArray cmd,
				   jstringArray env,
				   java::io::File *dir)
{
  return new java::lang::ConcreteProcess (cmd, env, dir);
}

jint
java::lang::Runtime::availableProcessors (void)
{
  // FIXME: find the real value.
  return 1;
}

jstring
java::lang::Runtime::nativeGetLibname (jstring pathname, jstring libname)
{
  java::lang::StringBuffer *sb = new java::lang::StringBuffer ();
  sb->append(pathname);
  if (pathname->length() > 0)
    sb->append (_Jv_platform_file_separator);

  sb->append (JvNewStringLatin1 (_Jv_platform_solib_prefix));
  sb->append(libname);
  sb->append (JvNewStringLatin1 (_Jv_platform_solib_suffix));

  return sb->toString();
}
