aboutsummaryrefslogtreecommitdiff
path: root/libjava/java/lang/natSystem.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/java/lang/natSystem.cc')
-rw-r--r--libjava/java/lang/natSystem.cc259
1 files changed, 259 insertions, 0 deletions
diff --git a/libjava/java/lang/natSystem.cc b/libjava/java/lang/natSystem.cc
new file mode 100644
index 0000000..5f613d5
--- /dev/null
+++ b/libjava/java/lang/natSystem.cc
@@ -0,0 +1,259 @@
+// natSystem.cc - Native code implementing System class.
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ 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>
+
+#ifdef HAVE_GETPWUID_R
+#define _POSIX_PTHREAD_SEMANTICS
+#ifndef _REENTRANT
+#define _REENTRANT
+#endif
+#endif
+
+#include <string.h>
+#include <time.h>
+#include <stdlib.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+#include <errno.h>
+
+#include <cni.h>
+#include <jvm.h>
+#include <java/lang/System.h>
+#include <java/lang/Class.h>
+#include <java/lang/ArrayStoreException.h>
+#include <java/lang/ArrayIndexOutOfBoundsException.h>
+#include <java/lang/NullPointerException.h>
+#include <java/util/Properties.h>
+#include <java/io/PrintStream.h>
+#include <java/io/InputStream.h>
+
+
+
+#if defined (ECOS)
+extern "C" unsigned long long _clock (void);
+#endif
+
+void
+java::lang::System::setErr (java::io::PrintStream *newErr)
+{
+ checkSetIO ();
+ // This violates `final' semantics. Oh well.
+ err = newErr;
+}
+
+void
+java::lang::System::setIn (java::io::InputStream *newIn)
+{
+ checkSetIO ();
+ // This violates `final' semantics. Oh well.
+ in = newIn;
+}
+
+void
+java::lang::System::setOut (java::io::PrintStream *newOut)
+{
+ checkSetIO ();
+ // This violates `final' semantics. Oh well.
+ out = newOut;
+}
+
+void
+java::lang::System::arraycopy (jobject src, jint src_offset,
+ jobject dst, jint dst_offset,
+ jint count)
+{
+ if (! src || ! dst)
+ _Jv_Throw (new NullPointerException);
+
+ jclass src_c = src->getClass();
+ jclass dst_c = dst->getClass();
+ jclass src_comp = src_c->getComponentType();
+ jclass dst_comp = dst_c->getComponentType();
+
+ if (! src_c->isArray() || ! dst_c->isArray()
+ || src_comp->isPrimitive() != dst_comp->isPrimitive()
+ || (src_comp->isPrimitive() && src_comp != dst_comp))
+ _Jv_Throw (new ArrayStoreException);
+
+ __JArray *src_a = (__JArray *) src;
+ __JArray *dst_a = (__JArray *) dst;
+ if (src_offset < 0 || dst_offset < 0 || count < 0
+ || src_offset + count > src_a->length
+ || dst_offset + count > dst_a->length)
+ _Jv_Throw (new ArrayIndexOutOfBoundsException);
+
+ // Do-nothing cases.
+ if ((src == dst && src_offset == dst_offset)
+ || ! count)
+ return;
+
+ // If both are primitive, we can optimize trivially. If DST
+ // components are always assignable from SRC components, then we
+ // will never need to raise an error, and thus can do the
+ // optimization. If source and destinations are the same, then we
+ // know that the assignability premise always holds.
+ const bool prim = src_comp->isPrimitive();
+ if (prim || dst_comp->isAssignableFrom(src_comp) || src == dst)
+ {
+ const size_t size = prim ? src_comp->size()
+ : sizeof elements((jobjectArray)src)[0];
+
+ // We need a particular type to get the pointer to the data. So
+ // we choose bytes.
+ char *src_elts = (((char *) elements ((jbyteArray) src))
+ + src_offset * size);
+ char *dst_elts = (((char *) elements ((jbyteArray) dst))
+ + dst_offset * size);
+ // We don't bother trying memcpy. It can't be worth the cost of
+ // the check.
+ memmove ((void *) dst_elts, (void *) src_elts, count * size);
+ }
+ else
+ {
+ jobject *src_elts = elements ((jobjectArray) src_a) + src_offset;
+ jobject *dst_elts = elements ((jobjectArray) dst_a) + dst_offset;
+
+ for (int i = 0; i < count; ++i)
+ {
+ if (*src_elts
+ && ! dst_comp->isAssignableFrom((*src_elts)->getClass()))
+ _Jv_Throw (new ArrayStoreException);
+ *dst_elts++ = *src_elts++;
+ }
+ }
+}
+
+jlong
+java::lang::System::currentTimeMillis (void)
+{
+ jlong r;
+
+#if defined (HAVE_GETTIMEOFDAY)
+ struct timeval tv;
+ gettimeofday (&tv, NULL);
+ r = (jlong) tv.tv_sec * 1000 + tv.tv_usec / 1000;
+#elif defined (HAVE_TIME)
+ r = time (NULL) * 1000;
+#elif defined (HAVE_FTIME)
+ struct timeb t;
+ ftime (&t);
+ r = t.time * 1000 + t.millitm;
+#elif defined (ECOS)
+ r = _clock();
+#else
+ // In the absence of any function, time remains forever fixed.
+ r = 23;
+#endif
+
+ return r;
+}
+
+jint
+java::lang::System::identityHashCode (jobject obj)
+{
+ return _Jv_HashCode (obj);
+}
+
+void
+java::lang::System::init_properties (void)
+{
+ if (prop_init)
+ return;
+ prop_init = true;
+
+ properties = new java::util::Properties ();
+ // A convenience define.
+#define SET(Prop,Val) \
+ properties->put(JvNewStringLatin1 (Prop), JvNewStringLatin1 (Val))
+ SET ("java.version", "FIXME");
+ SET ("java.vendor", "Cygnus Solutions");
+ SET ("java.vendor.url", "http://www.cygnus.com/");
+ // SET ("java.home", "FIXME");
+ // SET ("java.class.version", "FIXME");
+ // SET ("java.class.path", "FIXME");
+ SET ("os.name", "FIXME");
+ SET ("os.arch", "FIXME");
+ SET ("os.version", "FIXME");
+ SET ("file.encoding", "8859_1"); // FIXME
+#ifdef WIN32
+ SET ("file.separator", "\\");
+ SET ("path.separator", ";");
+ SET ("line.separator", "\r\n");
+#else
+ // Unix.
+ SET ("file.separator", "/");
+ SET ("path.separator", ":");
+ SET ("line.separator", "\n");
+#endif
+
+#ifdef HAVE_PWD_H
+ uid_t user_id = getuid ();
+ struct passwd *pwd_entry;
+
+#ifdef HAVE_GETPWUID_R
+ struct passwd pwd_r;
+ size_t len_r = 200;
+ char *buf_r = (char *) _Jv_AllocBytes (len_r);
+
+ while (buf_r != NULL)
+ {
+ int r = getpwuid_r (user_id, &pwd_r, buf_r, len_r, &pwd_entry);
+ if (r == 0)
+ break;
+ else if (r != ERANGE)
+ {
+ pwd_entry = NULL;
+ break;
+ }
+ len_r *= 2;
+ buf_r = (char *) _Jv_AllocBytes (len_r);
+ }
+#else
+ struct passwd *pwd_entry = getpwuid (user_id);
+#endif /* HAVE_GETPWUID_R */
+
+ if (pwd_entry != NULL)
+ {
+ SET ("user.name", pwd_entry->pw_name);
+ SET ("user.home", pwd_entry->pw_dir);
+ }
+#endif /* HAVE_PWD_H */
+
+#ifdef HAVE_UNISTD_H
+ /* Use getcwd to set "user.dir". */
+ int buflen = 250;
+ char *buffer = (char *) malloc (buflen);
+ while (buffer != NULL)
+ {
+ if (getcwd (buffer, buflen) != NULL)
+ {
+ SET ("user.dir", buffer);
+ break;
+ }
+ if (errno != ERANGE)
+ break;
+ buflen = 2 * buflen;
+ buffer = (char *) realloc (buffer, buflen);
+ }
+ if (buffer != NULL)
+ free (buffer);
+#endif
+}