456c0b60ad
2001-03-12 Bryce McKinlay <bryce@albatross.co.nz> * java/lang/Runtime.java (_exit): Declare new package-private native. * java/lang/natRuntime.cc (_exit): Implemented. Same as exit() but without a security manager check. (exit): Call _exit after security check. * prims.cc (JvRunMain): Call Runtime._exit to shutdown the runtime "naturally". * java/lang/System.java (setSecurityManager): If a security manager is already in place, call checkPermission. * java/lang/ThreadGroup.java (uncaughtException): If printStackTrace() throws an exception, try to deal with it gracefully. * java/lang/ExceptionInInitializerError.java (printStackTrace): Only try to print the subordinate stack trace if "exception" is set. Print our class name first. From-SVN: r40401
253 lines
7.4 KiB
Java
253 lines
7.4 KiB
Java
// System.java - System-specific info.
|
|
|
|
/* Copyright (C) 1998, 1999, 2000, 2001 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. */
|
|
|
|
package java.lang;
|
|
|
|
import java.io.FileDescriptor;
|
|
import java.io.FileInputStream;
|
|
import java.io.FileOutputStream;
|
|
import java.io.FilterInputStream;
|
|
import java.io.InputStream;
|
|
import java.io.PrintStream;
|
|
import java.io.BufferedInputStream;
|
|
import java.io.BufferedOutputStream;
|
|
import java.util.Properties;
|
|
import java.util.PropertyPermission;
|
|
import java.util.TimeZone;
|
|
|
|
/**
|
|
* @author Tom Tromey <tromey@cygnus.com>
|
|
* @date August 27, 1998
|
|
*/
|
|
|
|
/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
|
|
* "The Java Language Specification", ISBN 0-201-63451-1
|
|
* plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
|
|
* Status: 1.1. Some 1.2 methods missing. Properties code not fully
|
|
* implemented.
|
|
*/
|
|
|
|
public final class System
|
|
{
|
|
public static native void arraycopy (Object src, int srcOffset,
|
|
Object dst, int dstOffset,
|
|
int count);
|
|
|
|
public static native long currentTimeMillis ();
|
|
|
|
// FIXME: When merging with Classpath, remember to remove the call to
|
|
// getDefaultTimeZoneId from java.util.Timezone.
|
|
private static native String getSystemTimeZone ();
|
|
|
|
// Get the System Timezone as reported by the OS. It should be in
|
|
// the form PST8PDT so we'll need to parse it and check that it's valid.
|
|
// The result is used to set the user.timezone property in init_properties.
|
|
// FIXME: Using the code from Classpath for generating the System
|
|
// Timezone IMO is suboptimal because it ignores whether the rules for
|
|
// DST match up.
|
|
private static String getDefaultTimeZoneId ()
|
|
{
|
|
String sysTimeZoneId = getSystemTimeZone ();
|
|
|
|
// Check if this is a valid timezone. Make sure the IDs match
|
|
// since getTimeZone returns GMT if no match is found.
|
|
TimeZone tz = TimeZone.getTimeZone (sysTimeZoneId);
|
|
if (tz.getID ().equals (sysTimeZoneId))
|
|
return sysTimeZoneId;
|
|
|
|
// Check if the base part of sysTimeZoneId is a valid timezone that
|
|
// matches with daylight usage and rawOffset. Make sure the IDs match
|
|
// since getTimeZone returns GMT if no match is found.
|
|
// First find start of GMT offset info and any Daylight zone name.
|
|
int startGMToffset = 0;
|
|
int sysTimeZoneIdLength = sysTimeZoneId.length();
|
|
for (int i = 0; i < sysTimeZoneIdLength && startGMToffset == 0; i++)
|
|
{
|
|
if (Character.isDigit (sysTimeZoneId.charAt (i)))
|
|
startGMToffset = i;
|
|
}
|
|
|
|
int startDaylightZoneName = 0;
|
|
boolean usesDaylight = false;
|
|
for (int i = sysTimeZoneIdLength - 1;
|
|
i >= 0 && !Character.isDigit (sysTimeZoneId.charAt (i)); --i)
|
|
{
|
|
startDaylightZoneName = i;
|
|
}
|
|
if (startDaylightZoneName > 0)
|
|
usesDaylight = true;
|
|
|
|
int GMToffset = Integer.parseInt (startDaylightZoneName == 0 ?
|
|
sysTimeZoneId.substring (startGMToffset) :
|
|
sysTimeZoneId.substring (startGMToffset, startDaylightZoneName));
|
|
|
|
// Offset could be in hours or seconds. Convert to millis.
|
|
if (GMToffset < 24)
|
|
GMToffset *= 60 * 60;
|
|
GMToffset *= -1000;
|
|
|
|
String tzBasename = sysTimeZoneId.substring (0, startGMToffset);
|
|
tz = TimeZone.getTimeZone (tzBasename);
|
|
if (tz.getID ().equals (tzBasename) && tz.getRawOffset () == GMToffset)
|
|
{
|
|
boolean tzUsesDaylight = tz.useDaylightTime ();
|
|
if (usesDaylight && tzUsesDaylight || !usesDaylight && !tzUsesDaylight)
|
|
return tzBasename;
|
|
}
|
|
|
|
// If no match, see if a valid timezone has the same attributes as this
|
|
// and then use it instead.
|
|
String[] IDs = TimeZone.getAvailableIDs (GMToffset);
|
|
for (int i = 0; i < IDs.length; ++i)
|
|
{
|
|
// FIXME: The daylight savings rules may not match the rules
|
|
// for the desired zone.
|
|
boolean IDusesDaylight =
|
|
TimeZone.getTimeZone (IDs[i]).useDaylightTime ();
|
|
if (usesDaylight && IDusesDaylight || !usesDaylight && !IDusesDaylight)
|
|
return IDs[i];
|
|
}
|
|
|
|
// If all else fails, return null.
|
|
return null;
|
|
}
|
|
|
|
public static void exit (int status)
|
|
{
|
|
Runtime.getRuntime().exit(status);
|
|
}
|
|
|
|
public static void gc ()
|
|
{
|
|
Runtime.getRuntime().gc();
|
|
}
|
|
|
|
// Marked deprecated in 1.1. We implement what the JCL book says.
|
|
public static String getenv (String name)
|
|
{
|
|
throw new Error ();
|
|
}
|
|
|
|
private static native void init_properties ();
|
|
|
|
public static Properties getProperties ()
|
|
{
|
|
if (secman != null)
|
|
secman.checkPropertiesAccess();
|
|
if (properties == null)
|
|
init_properties ();
|
|
return properties;
|
|
}
|
|
|
|
public static String getProperty (String property)
|
|
{
|
|
if (secman != null)
|
|
secman.checkPropertyAccess(property);
|
|
if (properties == null)
|
|
init_properties ();
|
|
return properties.getProperty(property);
|
|
}
|
|
|
|
public static String getProperty (String property, String defval)
|
|
{
|
|
if (secman != null)
|
|
secman.checkPropertyAccess(property, defval);
|
|
if (properties == null)
|
|
init_properties ();
|
|
return properties.getProperty(property, defval);
|
|
}
|
|
|
|
public static SecurityManager getSecurityManager ()
|
|
{
|
|
return secman;
|
|
}
|
|
|
|
public static native int identityHashCode (Object obj);
|
|
|
|
public static void load (String pathname)
|
|
{
|
|
Runtime.getRuntime().load(pathname);
|
|
}
|
|
|
|
public static void loadLibrary (String libname)
|
|
{
|
|
Runtime.getRuntime().loadLibrary(libname);
|
|
}
|
|
|
|
public static void runFinalization ()
|
|
{
|
|
Runtime.getRuntime().runFinalization();
|
|
}
|
|
|
|
// Marked as deprecated in 1.2.
|
|
public static void runFinalizersOnExit (boolean run)
|
|
{
|
|
Runtime.getRuntime().runFinalizersOnExit(run);
|
|
}
|
|
|
|
private static void checkSetIO ()
|
|
{
|
|
// In 1.1, we are supposed to call checkExec, but the argument is
|
|
// not specified. In 1.2, we are supposed to use checkPermission,
|
|
// which doesn't exist in 1.1.
|
|
if (secman != null)
|
|
secman.checkExec("");
|
|
}
|
|
|
|
public static native void setErr (PrintStream newErr);
|
|
public static native void setIn (InputStream newIn);
|
|
public static native void setOut (PrintStream newOut);
|
|
|
|
public static void setProperties (Properties props)
|
|
{
|
|
if (secman != null)
|
|
secman.checkPropertiesAccess();
|
|
synchronized (System.class)
|
|
{
|
|
properties = props;
|
|
}
|
|
}
|
|
|
|
public static String setProperty (String key, String value)
|
|
{
|
|
if (secman != null)
|
|
secman.checkPermission (new PropertyPermission (key, "write"));
|
|
if (properties == null)
|
|
init_properties ();
|
|
return (String) properties.setProperty (key, value);
|
|
}
|
|
|
|
// TODO 1.2.
|
|
// public static String mapLibraryName (String libname);
|
|
|
|
public static void setSecurityManager (SecurityManager s)
|
|
{
|
|
if (secman != null)
|
|
secman.checkPermission(new RuntimePermission("setSecurityManager"));
|
|
secman = s;
|
|
}
|
|
|
|
// Public data.
|
|
public static final InputStream in = new BufferedInputStream (new FileInputStream (FileDescriptor.in));
|
|
|
|
public static final PrintStream out = new PrintStream (new BufferedOutputStream (new FileOutputStream (FileDescriptor.out)), true);
|
|
|
|
public static final PrintStream err = new PrintStream (new BufferedOutputStream (new FileOutputStream (FileDescriptor.err)), true);
|
|
|
|
// Don't allow System objects to be made.
|
|
private System ()
|
|
{
|
|
}
|
|
|
|
// Private data.
|
|
private static SecurityManager secman = null;
|
|
private static Properties properties = null;
|
|
}
|