1 // natSystem.cc - Native code implementing System class.
3 /* Copyright (C) 1998, 1999 Cygnus Solutions
5 This file is part of libgcj.
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
13 #ifdef HAVE_GETPWUID_R
14 #define _POSIX_PTHREAD_SEMANTICS
28 #ifdef HAVE_SYS_TIME_H
38 #include <sys/utsname.h>
43 #include <java/lang/System.h>
44 #include <java/lang/Class.h>
45 #include <java/lang/ArrayStoreException.h>
46 #include <java/lang/ArrayIndexOutOfBoundsException.h>
47 #include <java/lang/NullPointerException.h>
48 #include <java/util/Properties.h>
49 #include <java/io/PrintStream.h>
50 #include <java/io/InputStream.h>
52 #define SystemClass _CL_Q34java4lang6System
53 extern java::lang::Class SystemClass;
58 extern "C" unsigned long long _clock (void);
62 java::lang::System::setErr (java::io::PrintStream *newErr)
65 // This violates `final' semantics. Oh well.
70 java::lang::System::setIn (java::io::InputStream *newIn)
73 // This violates `final' semantics. Oh well.
78 java::lang::System::setOut (java::io::PrintStream *newOut)
81 // This violates `final' semantics. Oh well.
86 java::lang::System::arraycopy (jobject src, jint src_offset,
87 jobject dst, jint dst_offset,
91 _Jv_Throw (new NullPointerException);
93 jclass src_c = src->getClass();
94 jclass dst_c = dst->getClass();
95 jclass src_comp = src_c->getComponentType();
96 jclass dst_comp = dst_c->getComponentType();
98 if (! src_c->isArray() || ! dst_c->isArray()
99 || src_comp->isPrimitive() != dst_comp->isPrimitive()
100 || (src_comp->isPrimitive() && src_comp != dst_comp))
101 _Jv_Throw (new ArrayStoreException);
103 __JArray *src_a = (__JArray *) src;
104 __JArray *dst_a = (__JArray *) dst;
105 if (src_offset < 0 || dst_offset < 0 || count < 0
106 || src_offset + count > src_a->length
107 || dst_offset + count > dst_a->length)
108 _Jv_Throw (new ArrayIndexOutOfBoundsException);
111 if ((src == dst && src_offset == dst_offset)
115 // If both are primitive, we can optimize trivially. If DST
116 // components are always assignable from SRC components, then we
117 // will never need to raise an error, and thus can do the
118 // optimization. If source and destinations are the same, then we
119 // know that the assignability premise always holds.
120 const bool prim = src_comp->isPrimitive();
121 if (prim || dst_comp->isAssignableFrom(src_comp) || src == dst)
123 const size_t size = (prim ? src_comp->size()
124 : sizeof elements((jobjectArray)src)[0]);
126 // In an ideal world we would do this via a virtual function in
127 // __JArray. However, we can't have virtual functions in
128 // __JArray due to the need to copy an array's virtual table in
129 // _Jv_FindArrayClass.
130 // We can't just pick a single subtype of __JArray to use due to
131 // alignment concerns.
132 char *src_elts = NULL;
134 src_elts = (char *) elements ((jobjectArray) src);
135 else if (src_comp == JvPrimClass (byte))
136 src_elts = (char *) elements ((jbyteArray) src);
137 else if (src_comp == JvPrimClass (short))
138 src_elts = (char *) elements ((jshortArray) src);
139 else if (src_comp == JvPrimClass (int))
140 src_elts = (char *) elements ((jintArray) src);
141 else if (src_comp == JvPrimClass (long))
142 src_elts = (char *) elements ((jlongArray) src);
143 else if (src_comp == JvPrimClass (boolean))
144 src_elts = (char *) elements ((jbooleanArray) src);
145 else if (src_comp == JvPrimClass (char))
146 src_elts = (char *) elements ((jcharArray) src);
147 else if (src_comp == JvPrimClass (float))
148 src_elts = (char *) elements ((jfloatArray) src);
149 else if (src_comp == JvPrimClass (double))
150 src_elts = (char *) elements ((jdoubleArray) src);
151 src_elts += size * src_offset;
153 char *dst_elts = NULL;
155 dst_elts = (char *) elements ((jobjectArray) dst);
156 else if (dst_comp == JvPrimClass (byte))
157 dst_elts = (char *) elements ((jbyteArray) dst);
158 else if (dst_comp == JvPrimClass (short))
159 dst_elts = (char *) elements ((jshortArray) dst);
160 else if (dst_comp == JvPrimClass (int))
161 dst_elts = (char *) elements ((jintArray) dst);
162 else if (dst_comp == JvPrimClass (long))
163 dst_elts = (char *) elements ((jlongArray) dst);
164 else if (dst_comp == JvPrimClass (boolean))
165 dst_elts = (char *) elements ((jbooleanArray) dst);
166 else if (dst_comp == JvPrimClass (char))
167 dst_elts = (char *) elements ((jcharArray) dst);
168 else if (dst_comp == JvPrimClass (float))
169 dst_elts = (char *) elements ((jfloatArray) dst);
170 else if (dst_comp == JvPrimClass (double))
171 dst_elts = (char *) elements ((jdoubleArray) dst);
172 dst_elts += size * dst_offset;
174 // We don't bother trying memcpy. It can't be worth the cost of
176 memmove ((void *) dst_elts, (void *) src_elts, count * size);
180 jobject *src_elts = elements ((jobjectArray) src_a) + src_offset;
181 jobject *dst_elts = elements ((jobjectArray) dst_a) + dst_offset;
183 for (int i = 0; i < count; ++i)
186 && ! dst_comp->isAssignableFrom((*src_elts)->getClass()))
187 _Jv_Throw (new ArrayStoreException);
188 *dst_elts++ = *src_elts++;
194 java::lang::System::currentTimeMillis (void)
198 #if defined (HAVE_GETTIMEOFDAY)
200 gettimeofday (&tv, NULL);
201 r = (jlong) tv.tv_sec * 1000 + tv.tv_usec / 1000;
202 #elif defined (HAVE_TIME)
203 r = time (NULL) * 1000;
204 #elif defined (HAVE_FTIME)
207 r = t.time * 1000 + t.millitm;
211 // In the absence of any function, time remains forever fixed.
219 java::lang::System::identityHashCode (jobject obj)
221 return _Jv_HashCode (obj);
224 #ifndef DEFAULT_FILE_ENCODING
225 #define DEFAULT_FILE_ENCODING "8859_1"
227 static char *default_file_encoding = DEFAULT_FILE_ENCODING;
230 java::lang::System::init_properties (void)
233 // We only need to synchronize around this gatekeeper.
234 JvSynchronize sync (&SystemClass);
240 properties = new java::util::Properties ();
241 // A convenience define.
242 #define SET(Prop,Val) \
243 properties->put(JvNewStringLatin1 (Prop), JvNewStringLatin1 (Val))
244 SET ("java.version", VERSION);
245 SET ("java.vendor", "Cygnus Solutions");
246 SET ("java.vendor.url", "http://sourceware.cygnus.com/java/");
247 SET ("java.class.version", GCJVERSION);
248 // FIXME: how to set these given location-independence?
249 // SET ("java.home", "FIXME");
250 // SET ("java.class.path", "FIXME");
251 SET ("file.encoding", default_file_encoding);
254 SET ("file.separator", "\\");
255 SET ("path.separator", ";");
256 SET ("line.separator", "\r\n");
259 SET ("file.separator", "/");
260 SET ("path.separator", ":");
261 SET ("line.separator", "\n");
268 SET ("os.name", u.sysname);
269 SET ("os.arch", u.machine);
270 SET ("os.version", u.release);
274 SET ("os.name", "unknown");
275 SET ("os.arch", "unknown");
276 SET ("os.version", "unknown");
278 #endif /* HAVE_UNAME */
281 uid_t user_id = getuid ();
282 struct passwd *pwd_entry;
284 #ifdef HAVE_GETPWUID_R
287 char *buf_r = (char *) _Jv_AllocBytes (len_r);
289 while (buf_r != NULL)
291 int r = getpwuid_r (user_id, &pwd_r, buf_r, len_r, &pwd_entry);
294 else if (r != ERANGE)
300 buf_r = (char *) _Jv_AllocBytes (len_r);
303 pwd_entry = getpwuid (user_id);
304 #endif /* HAVE_GETPWUID_R */
306 if (pwd_entry != NULL)
308 SET ("user.name", pwd_entry->pw_name);
309 SET ("user.home", pwd_entry->pw_dir);
311 #endif /* HAVE_PWD_H */
314 /* Use getcwd to set "user.dir". */
316 char *buffer = (char *) malloc (buflen);
317 while (buffer != NULL)
319 if (getcwd (buffer, buflen) != NULL)
321 SET ("user.dir", buffer);
327 buffer = (char *) realloc (buffer, buflen);