From a26eb1b2b9726e92dd4ec80c367b5d4ac8afeace Mon Sep 17 00:00:00 2001 From: Eric Scharff Date: Sun, 5 Sep 2010 09:07:18 -0600 Subject: [PATCH 01/16] Fix missing flush in PrintStream --- classpath/java/io/PrintStream.java | 1 + 1 file changed, 1 insertion(+) diff --git a/classpath/java/io/PrintStream.java b/classpath/java/io/PrintStream.java index d4aa83eceb..520b676a29 100644 --- a/classpath/java/io/PrintStream.java +++ b/classpath/java/io/PrintStream.java @@ -31,6 +31,7 @@ public class PrintStream extends OutputStream { public synchronized void print(String s) { try { out.write(s.getBytes()); + if (autoFlush) flush(); } catch (IOException e) { } } From 250a77dc13d586fb7bae6a80a695ed6545898645 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Mon, 6 Sep 2010 11:16:27 -0600 Subject: [PATCH 02/16] handle empty strings properly in Pattern.split We were incorrectly returning an empty array when the input was empty, whereas we ought to return an array containing a single empty string. When the pattern to match was empty, we went into a loop to create an infinite list of empty strings, only to crash once we've run out of memory. This commit addresses both problems. --- classpath/java/util/regex/Pattern.java | 21 ++++++++++--- test/Strings.java | 43 ++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 5 deletions(-) diff --git a/classpath/java/util/regex/Pattern.java b/classpath/java/util/regex/Pattern.java index a3ec90c676..2a48591592 100644 --- a/classpath/java/util/regex/Pattern.java +++ b/classpath/java/util/regex/Pattern.java @@ -115,23 +115,34 @@ public class Pattern { List list = new LinkedList(); int index = 0; int trailing = 0; - while (index < input.length() && list.size() < limit) { - int i = indexOf(input, pattern, index); + int patternLength = pattern.length(); + while (index < input.length() && list.size() < limit - 1) { + int i; + if (patternLength == 0) { + if (list.size() == 0) { + i = 0; + } else { + i = index + 1; + } + } else { + i = indexOf(input, pattern, index); + } + if (i >= 0) { - if (i == index) { + if (patternLength != 0 && i == index) { ++ trailing; } else { trailing = 0; } list.add(input.subSequence(index, i)); - index = i + pattern.length(); + index = i + patternLength; } else { break; } } - if (strip && index == input.length()) { + if (strip && index > 0 && index == input.length()) { ++ trailing; } else { trailing = 0; diff --git a/test/Strings.java b/test/Strings.java index 9927ba2983..6b993bcb4f 100644 --- a/test/Strings.java +++ b/test/Strings.java @@ -3,6 +3,24 @@ public class Strings { if (! v) throw new RuntimeException(); } + private static boolean equal(Object a, Object b) { + return a == b || (a != null && a.equals(b)); + } + + private static boolean arraysEqual(Object[] a, Object[] b) { + if (a.length != b.length) { + return false; + } + + for (int i = 0; i < a.length; ++i) { + if (! equal(a[i], b[i])) { + return false; + } + } + + return true; + } + public static void main(String[] args) { expect(new String(new byte[] { 99, 111, 109, 46, 101, 99, 111, 118, 97, 116, 101, 46, 110, 97, 116, 46, 98, 117, @@ -13,6 +31,31 @@ public class Strings { expect(months.split("\u00ae").length == 3); expect(months.replaceAll("\u00ae", ".").equals("Jan.Feb.Mar.")); + expect(arraysEqual + ("xyz".split("", 0), new String[] { "", "x", "y", "z" })); + expect(arraysEqual + ("xyz".split("", 1), new String[] { "xyz" })); + expect(arraysEqual + ("xyz".split("", 2), new String[] { "", "xyz" })); + expect(arraysEqual + ("xyz".split("", 3), new String[] { "", "x", "yz" })); + expect(arraysEqual + ("xyz".split("", 4), new String[] { "", "x", "y", "z" })); + expect(arraysEqual + ("xyz".split("", 5), new String[] { "", "x", "y", "z", "" })); + expect(arraysEqual + ("xyz".split("", 6), new String[] { "", "x", "y", "z", "" })); + expect(arraysEqual + ("xyz".split("", -1), new String[] { "", "x", "y", "z", "" })); + + expect(arraysEqual("".split("xyz", 0), new String[] { "" })); + expect(arraysEqual("".split("xyz", 1), new String[] { "" })); + expect(arraysEqual("".split("xyz", -1), new String[] { "" })); + + expect(arraysEqual("".split("", 0), new String[] { "" })); + expect(arraysEqual("".split("", 1), new String[] { "" })); + expect(arraysEqual("".split("", -1), new String[] { "" })); + expect("foo_foofoo__foo".replaceAll("_", "__") .equals("foo__foofoo____foo")); From fc2c6d5100e2c0ee0ee2242e3a27520365dd50e5 Mon Sep 17 00:00:00 2001 From: Zsombor Gegesy Date: Sun, 15 Aug 2010 13:28:29 +0200 Subject: [PATCH 03/16] implement toLowerCase(Locale) in the default case --- classpath/java/lang/String.java | 40 ++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/classpath/java/lang/String.java b/classpath/java/lang/String.java index 143c60fd72..9362822b65 100644 --- a/classpath/java/lang/String.java +++ b/classpath/java/lang/String.java @@ -236,19 +236,31 @@ public final class String } public String toLowerCase() { - char[] b = new char[length]; - for (int i = 0; i < length; ++i) { - b[i] = Character.toLowerCase(charAt(i)); + for (int j = 0; j < length; ++j) { + char ch = charAt(j); + if (Character.toLowerCase(ch) != ch) { + char[] b = new char[length]; + for (int i = 0; i < length; ++i) { + b[i] = Character.toLowerCase(charAt(i)); + } + return new String(b, 0, length, false); + } } - return new String(b, 0, length, false); + return this; } public String toUpperCase() { - char[] b = new char[length]; - for (int i = 0; i < length; ++i) { - b[i] = Character.toUpperCase(charAt(i)); + for (int j = 0; j < length; ++j) { + char ch = charAt(j); + if (Character.toUpperCase(ch) != ch) { + char[] b = new char[length]; + for (int i = 0; i < length; ++i) { + b[i] = Character.toUpperCase(charAt(i)); + } + return new String(b, 0, length, false); + } } - return new String(b, 0, length, false); + return this; } public int indexOf(int c) { @@ -581,11 +593,19 @@ public final class String } public String toUpperCase(Locale locale) { - throw new UnsupportedOperationException(); + if (locale == Locale.ENGLISH) { + return toUpperCase(); + } else { + throw new UnsupportedOperationException("toUpperCase("+locale+')'); + } } public String toLowerCase(Locale locale) { - throw new UnsupportedOperationException(); + if (locale == Locale.ENGLISH) { + return toLowerCase(); + } else { + throw new UnsupportedOperationException("toLowerCase("+locale+')'); + } } public static String format(Locale locale, String format, Object ... args) { From 5dadac2cb8b7ceb387600d5098007fb635e5a057 Mon Sep 17 00:00:00 2001 From: Zsombor Gegesy Date: Sun, 15 Aug 2010 14:01:33 +0200 Subject: [PATCH 04/16] API additions for compatibility with harmony's java.util package --- classpath/java/io/ObjectInputStream.java | 4 ++ classpath/java/io/ObjectOutputStream.java | 4 ++ classpath/java/util/Arrays.java | 6 +++ classpath/java/util/Collections.java | 21 +++++++++ .../util/ConcurrentModificationException.java | 47 +++++++++++++++++++ classpath/java/util/HashMap.java | 4 +- classpath/java/util/Map.java | 2 +- classpath/java/util/TreeMap.java | 5 +- classpath/java/util/WeakHashMap.java | 4 +- 9 files changed, 93 insertions(+), 4 deletions(-) create mode 100644 classpath/java/util/ConcurrentModificationException.java diff --git a/classpath/java/io/ObjectInputStream.java b/classpath/java/io/ObjectInputStream.java index 001a192a73..8447e10efa 100644 --- a/classpath/java/io/ObjectInputStream.java +++ b/classpath/java/io/ObjectInputStream.java @@ -79,6 +79,10 @@ public class ObjectInputStream extends InputStream { read('d'); return readDoubleToken(); } + + public void defaultReadObject() throws IOException { + throw new UnsupportedOperationException(); + } private void skipSpace() throws IOException { int c; diff --git a/classpath/java/io/ObjectOutputStream.java b/classpath/java/io/ObjectOutputStream.java index 42d080f676..90743a5b32 100644 --- a/classpath/java/io/ObjectOutputStream.java +++ b/classpath/java/io/ObjectOutputStream.java @@ -82,6 +82,10 @@ public class ObjectOutputStream extends OutputStream { out.print(v); } + public void defaultWriteObject() throws IOException { + throw new UnsupportedOperationException(); + } + private void writeObject(Object o, IdentityHashMap map, int nextId) throws IOException diff --git a/classpath/java/util/Arrays.java b/classpath/java/util/Arrays.java index 8206988d90..cf05144d7d 100644 --- a/classpath/java/util/Arrays.java +++ b/classpath/java/util/Arrays.java @@ -148,5 +148,11 @@ public class Arrays { array[i] = value; } } + + public static void fill(T[] array, T value) { + for (int i=0;i (c.iterator()); } + public static Comparator reverseOrder(Comparator cmp) { + return new ReverseComparator(cmp); + } + static class IteratorEnumeration implements Enumeration { private final Iterator it; @@ -379,4 +384,20 @@ public class Collections { it.remove(); } } + + private static final class ReverseComparator implements Comparator { + + Comparator cmp; + + public ReverseComparator(Comparator cmp) { + this.cmp = cmp; + } + + @Override + public int compare(T o1, T o2) { + return - cmp.compare(o1, o2); + } + + } + } diff --git a/classpath/java/util/ConcurrentModificationException.java b/classpath/java/util/ConcurrentModificationException.java new file mode 100644 index 0000000000..28fe2bf7ee --- /dev/null +++ b/classpath/java/util/ConcurrentModificationException.java @@ -0,0 +1,47 @@ +/* Copyright (c) 2010, Avian Contributors + + Permission to use, copy, modify, and/or distribute this software + for any purpose with or without fee is hereby granted, provided + that the above copyright notice and this permission notice appear + in all copies. + + There is NO WARRANTY for this software. See license.txt for + details. */ + +package java.util; + +/** + * @author zsombor + * + */ +public class ConcurrentModificationException extends RuntimeException { + + /** + * @param message + * @param cause + */ + public ConcurrentModificationException(String message, Throwable cause) { + super(message, cause); + } + + /** + * @param message + */ + public ConcurrentModificationException(String message) { + super(message); + } + + /** + * @param cause + */ + public ConcurrentModificationException(Throwable cause) { + super(cause); + } + + /** + * + */ + public ConcurrentModificationException() { + } + +} diff --git a/classpath/java/util/HashMap.java b/classpath/java/util/HashMap.java index c0a8a2474a..0f00f920b2 100644 --- a/classpath/java/util/HashMap.java +++ b/classpath/java/util/HashMap.java @@ -269,8 +269,10 @@ public class HashMap implements Map { return value; } - public void setValue(V value) { + public V setValue(V value) { + V old = this.value; this.value = value; + return old; } public HashMap.Cell next() { diff --git a/classpath/java/util/Map.java b/classpath/java/util/Map.java index 5b58bbb4f9..cd20bbc809 100644 --- a/classpath/java/util/Map.java +++ b/classpath/java/util/Map.java @@ -40,6 +40,6 @@ public interface Map { public V getValue(); - public void setValue(V value); + public V setValue(V value); } } diff --git a/classpath/java/util/TreeMap.java b/classpath/java/util/TreeMap.java index 686e9ffda3..b3141422cd 100644 --- a/classpath/java/util/TreeMap.java +++ b/classpath/java/util/TreeMap.java @@ -112,9 +112,12 @@ public class TreeMap implements Map { return value; } - public void setValue(V value) { + public V setValue(V value) { + V old = this.value; this.value = value; + return old; } + } private class KeySet implements Set { diff --git a/classpath/java/util/WeakHashMap.java b/classpath/java/util/WeakHashMap.java index d8fdbc7968..81365b9816 100644 --- a/classpath/java/util/WeakHashMap.java +++ b/classpath/java/util/WeakHashMap.java @@ -114,8 +114,10 @@ public class WeakHashMap implements Map { return value; } - public void setValue(V value) { + public V setValue(V value) { + V old = this.value; this.value = value; + return old; } public HashMap.Cell next() { From 6985e8150385ccb16e77549c4b1f0726839075e2 Mon Sep 17 00:00:00 2001 From: Zsombor Gegesy Date: Sun, 15 Aug 2010 14:28:09 +0200 Subject: [PATCH 05/16] add Properties.load(Reader) implementation --- classpath/java/util/Properties.java | 45 +++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/classpath/java/util/Properties.java b/classpath/java/util/Properties.java index 749869823b..1ff67dcf16 100644 --- a/classpath/java/util/Properties.java +++ b/classpath/java/util/Properties.java @@ -14,10 +14,15 @@ import java.io.InputStream; import java.io.OutputStream; import java.io.PrintStream; import java.io.IOException; +import java.io.Reader; public class Properties extends Hashtable { public void load(InputStream in) throws IOException { - new Parser().parse(in, this); + new InputStreamParser(in).parse(this); + } + + public void load(Reader reader) throws IOException { + new ReaderParser(reader).parse(this); } public void store(OutputStream out, String comment) throws IOException { @@ -53,7 +58,7 @@ public class Properties extends Hashtable { return keys(); } - private static class Parser { + private abstract static class Parser { private StringBuilder key = null; private StringBuilder value = null; private StringBuilder current = null; @@ -79,13 +84,15 @@ public class Properties extends Hashtable { key = value = current = null; } - private void parse(InputStream in, Map map) + abstract int readCharacter() throws IOException; + + void parse(Map map) throws IOException { boolean escaped = false; int c; - while ((c = in.read()) != -1) { + while ((c = readCharacter()) != -1) { if (c == '\\') { if (escaped) { escaped = false; @@ -98,7 +105,7 @@ public class Properties extends Hashtable { case '#': case '!': if (key == null) { - while ((c = in.read()) != -1 && c != '\n'); + while ((c = readCharacter()) != -1 && c != '\n'); } else { append(c); } @@ -153,4 +160,32 @@ public class Properties extends Hashtable { finishLine(map); } } + + static class InputStreamParser extends Parser { + InputStream in; + + + public InputStreamParser(InputStream in) { + this.in = in; + } + + @Override + int readCharacter() throws IOException { + return in.read(); + } + } + + static class ReaderParser extends Parser { + Reader in; + + public ReaderParser(Reader in) { + this.in = in; + } + + @Override + int readCharacter() throws IOException { + return in.read(); + } + } + } From 7376425b24b3fbc1e37f46129143fdd152a3f8aa Mon Sep 17 00:00:00 2001 From: Zsombor Gegesy Date: Sun, 15 Aug 2010 14:47:45 +0200 Subject: [PATCH 06/16] dummy SecurityManager and related classes added --- classpath/java/lang/SecurityManager.java | 30 +++++++++++++++++++ classpath/java/lang/System.java | 9 ++++++ classpath/java/security/AccessController.java | 6 +++- classpath/java/security/AllPermission.java | 8 ++++- classpath/java/security/BasicPermission.java | 19 ++++++++++++ classpath/java/security/Permission.java | 16 ++++++++++ .../java/security/SecurityPermission.java | 19 ++++++++++++ 7 files changed, 105 insertions(+), 2 deletions(-) create mode 100644 classpath/java/lang/SecurityManager.java create mode 100644 classpath/java/security/BasicPermission.java create mode 100644 classpath/java/security/SecurityPermission.java diff --git a/classpath/java/lang/SecurityManager.java b/classpath/java/lang/SecurityManager.java new file mode 100644 index 0000000000..0b522c5bfb --- /dev/null +++ b/classpath/java/lang/SecurityManager.java @@ -0,0 +1,30 @@ +/* Copyright (c) 2010, Avian Contributors + + Permission to use, copy, modify, and/or distribute this software + for any purpose with or without fee is hereby granted, provided + that the above copyright notice and this permission notice appear + in all copies. + + There is NO WARRANTY for this software. See license.txt for + details. */ + +package java.lang; + +import java.security.AccessController; +import java.security.Permission; +import java.security.SecurityPermission; + +public class SecurityManager { + + public SecurityManager() { + } + + public void checkPermission(Permission perm) { + AccessController.checkPermission(perm); + } + + public void checkSecurityAccess(String target) { + checkPermission(new SecurityPermission(target)); + } + +} diff --git a/classpath/java/lang/System.java b/classpath/java/lang/System.java index ac3ee11b3a..c060493e7c 100644 --- a/classpath/java/lang/System.java +++ b/classpath/java/lang/System.java @@ -22,6 +22,7 @@ import java.util.Properties; public abstract class System { private static Property properties; + private static SecurityManager securityManager; // static { // loadLibrary("natives"); // } @@ -118,6 +119,14 @@ public abstract class System { public static void exit(int code) { Runtime.getRuntime().exit(code); } + + public static SecurityManager getSecurityManager() { + return securityManager; + } + + public static void setSecurityManager(SecurityManager securityManager) { + System.securityManager = securityManager; + } private static class Property { public final String name; diff --git a/classpath/java/security/AccessController.java b/classpath/java/security/AccessController.java index 804dfe70a7..b219e450ae 100644 --- a/classpath/java/security/AccessController.java +++ b/classpath/java/security/AccessController.java @@ -1,4 +1,4 @@ -/* Copyright (c) 2008, Avian Contributors +/* Copyright (c) 2008, 2010 Avian Contributors Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided @@ -21,5 +21,9 @@ public class AccessController { public static Object doPrivileged (PrivilegedAction action) { return action.run(); } + + public static void checkPermission(Permission perm) throws AccessControlException { + + } } diff --git a/classpath/java/security/AllPermission.java b/classpath/java/security/AllPermission.java index 6bc99d53e8..b35004f609 100644 --- a/classpath/java/security/AllPermission.java +++ b/classpath/java/security/AllPermission.java @@ -10,4 +10,10 @@ package java.security; -public class AllPermission extends Permission { } +public class AllPermission extends Permission { + public AllPermission() { + super(""); + } + + +} diff --git a/classpath/java/security/BasicPermission.java b/classpath/java/security/BasicPermission.java new file mode 100644 index 0000000000..756e70139d --- /dev/null +++ b/classpath/java/security/BasicPermission.java @@ -0,0 +1,19 @@ +/* Copyright (c) 2010, Avian Contributors + + Permission to use, copy, modify, and/or distribute this software + for any purpose with or without fee is hereby granted, provided + that the above copyright notice and this permission notice appear + in all copies. + + There is NO WARRANTY for this software. See license.txt for + details. */ + +package java.security; + +public class BasicPermission extends Permission { + + public BasicPermission(String name) { + super(name); + } + +} diff --git a/classpath/java/security/Permission.java b/classpath/java/security/Permission.java index bc6c438e18..528795a127 100644 --- a/classpath/java/security/Permission.java +++ b/classpath/java/security/Permission.java @@ -11,6 +11,22 @@ package java.security; public abstract class Permission { + + protected String name; + + public Permission(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + @Override + public String toString() { + return this.getClass().getSimpleName() + '['+name+']'; + } + public PermissionCollection newPermissionCollection() { return null; } diff --git a/classpath/java/security/SecurityPermission.java b/classpath/java/security/SecurityPermission.java new file mode 100644 index 0000000000..22660f6111 --- /dev/null +++ b/classpath/java/security/SecurityPermission.java @@ -0,0 +1,19 @@ +/* Copyright (c) 2010, Avian Contributors + + Permission to use, copy, modify, and/or distribute this software + for any purpose with or without fee is hereby granted, provided + that the above copyright notice and this permission notice appear + in all copies. + + There is NO WARRANTY for this software. See license.txt for + details. */ + +package java.security; + +public class SecurityPermission extends BasicPermission { + + public SecurityPermission(String name) { + super(name); + } + +} From 6752505cb898c6f6b0276a31bb1b04b45350f678 Mon Sep 17 00:00:00 2001 From: Zsombor Gegesy Date: Sun, 15 Aug 2010 15:06:36 +0200 Subject: [PATCH 07/16] add File.canRead()/File.canWrite() implementation --- classpath/java-io.cpp | 25 +++++++++++++++++++++++++ classpath/java/io/File.java | 12 ++++++++++++ test/FileOutput.java | 1 + 3 files changed, 38 insertions(+) diff --git a/classpath/java-io.cpp b/classpath/java-io.cpp index 134045bdd2..05b54da2c9 100644 --- a/classpath/java-io.cpp +++ b/classpath/java-io.cpp @@ -377,6 +377,31 @@ Java_java_io_File_delete(JNIEnv* e, jclass, jstring path) } } +extern "C" JNIEXPORT jboolean JNICALL +Java_java_io_File_canRead(JNIEnv* e, jclass, jstring path) +{ + string_t chars = getChars(e, path); + if (chars) { + int r = access(chars, R_OK); + releaseChars(e, path, chars); + return (r == 0); + } + return false; +} + +extern "C" JNIEXPORT jboolean JNICALL +Java_java_io_File_canWrite(JNIEnv* e, jclass, jstring path) +{ + string_t chars = getChars(e, path); + if (chars) { + int r = access(chars, W_OK); + releaseChars(e, path, chars); + return (r == 0); + } + return false; +} + + extern "C" JNIEXPORT jboolean JNICALL Java_java_io_File_rename(JNIEnv* e, jclass, jstring old, jstring new_) { diff --git a/classpath/java/io/File.java b/classpath/java/io/File.java index c3fa42932f..86ef77c6a3 100644 --- a/classpath/java/io/File.java +++ b/classpath/java/io/File.java @@ -60,7 +60,19 @@ public class File { public boolean isFile() { return isFile(path); } + + private static native boolean canRead(String path); + + public boolean canRead() { + return canRead(path); + } + private static native boolean canWrite(String path); + + public boolean canWrite() { + return canWrite(path); + } + public String getName() { int index = path.lastIndexOf(FileSeparator); if (index >= 0) { diff --git a/test/FileOutput.java b/test/FileOutput.java index db4273f650..29df89da9a 100644 --- a/test/FileOutput.java +++ b/test/FileOutput.java @@ -1,3 +1,4 @@ +import java.io.File; import java.io.FileOutputStream; import java.io.FileInputStream; import java.io.File; From 522f8ca1a5227d989adf313ee8041d24ff29707b Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Sun, 12 Sep 2010 14:29:27 -0600 Subject: [PATCH 08/16] javadoc grammar correction in Continuations.java --- classpath/avian/Continuations.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classpath/avian/Continuations.java b/classpath/avian/Continuations.java index ecec10b348..42565830d4 100644 --- a/classpath/avian/Continuations.java +++ b/classpath/avian/Continuations.java @@ -128,7 +128,7 @@ public class Continuations { * receiver.receive(Callback), propagate the exception * thrown by that method, return the result passed to the * handleResult(T) method of the continuation, or throw the - * exception passed to the handleException(Throwable) of the + * exception passed to the handleException(Throwable) method of the * continuation. */ public static native T callWithCurrentContinuation From d5b35bea6ee98e31d13755f994513b4d5ef0594f Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Sun, 12 Sep 2010 14:41:01 -0600 Subject: [PATCH 09/16] remove redundant import from FileOutput.java --- test/FileOutput.java | 1 - 1 file changed, 1 deletion(-) diff --git a/test/FileOutput.java b/test/FileOutput.java index 29df89da9a..db4273f650 100644 --- a/test/FileOutput.java +++ b/test/FileOutput.java @@ -1,4 +1,3 @@ -import java.io.File; import java.io.FileOutputStream; import java.io.FileInputStream; import java.io.File; From 74a87a7f4f17f72beb6dda18e6aaf88fdf0ec239 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Sun, 12 Sep 2010 14:46:14 -0600 Subject: [PATCH 10/16] use _waccess on windows to implement File.can{Read|Write} --- classpath/java-io.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/classpath/java-io.cpp b/classpath/java-io.cpp index 05b54da2c9..f134d6dc0c 100644 --- a/classpath/java-io.cpp +++ b/classpath/java-io.cpp @@ -25,6 +25,7 @@ # include # include +# define ACCESS _waccess # define CLOSE _close # define READ _read # define WRITE _write @@ -56,6 +57,7 @@ typedef wchar_t char_t; # include # include "sys/mman.h" +# define ACCESS access # define OPEN open # define CLOSE close # define READ read @@ -382,7 +384,7 @@ Java_java_io_File_canRead(JNIEnv* e, jclass, jstring path) { string_t chars = getChars(e, path); if (chars) { - int r = access(chars, R_OK); + int r = ACCESS(chars, R_OK); releaseChars(e, path, chars); return (r == 0); } @@ -394,7 +396,7 @@ Java_java_io_File_canWrite(JNIEnv* e, jclass, jstring path) { string_t chars = getChars(e, path); if (chars) { - int r = access(chars, W_OK); + int r = ACCESS(chars, W_OK); releaseChars(e, path, chars); return (r == 0); } From ca251dfa1769fc6f31c97f26a34d9cf24bbe2024 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Wed, 13 Oct 2010 13:37:09 -0600 Subject: [PATCH 11/16] print error message on failed dlopen if Verbose is true in posix.cpp --- src/posix.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/posix.cpp b/src/posix.cpp index 0d34e2828a..2f7554698e 100644 --- a/src/posix.cpp +++ b/src/posix.cpp @@ -755,7 +755,9 @@ class MySystem: public System { return 0; } else { -// fprintf(stderr, "dlerror: %s\n", dlerror()); + if (Verbose) { + fprintf(stderr, "dlerror opening %s: %s\n", name, dlerror()); + } return 1; } } From b3accf1b308a04ce11f239ebb20bcca74ea5cc4d Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Wed, 13 Oct 2010 13:38:31 -0600 Subject: [PATCH 12/16] ServerSocketChannel throws IOException, not Exception --- classpath/java/nio/channels/ServerSocketChannel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classpath/java/nio/channels/ServerSocketChannel.java b/classpath/java/nio/channels/ServerSocketChannel.java index c8a691c5c5..61dfe60559 100644 --- a/classpath/java/nio/channels/ServerSocketChannel.java +++ b/classpath/java/nio/channels/ServerSocketChannel.java @@ -40,7 +40,7 @@ public class ServerSocketChannel extends SelectableChannel { channel.close(); } - public SocketChannel accept() throws Exception { + public SocketChannel accept() throws IOException { SocketChannel c = new SocketChannel(); c.socket = doAccept(); c.connected = true; From 081d2d68ce195abc4a1c587f9044cb4767d0fcdb Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Thu, 14 Oct 2010 23:43:35 +0000 Subject: [PATCH 13/16] handle and ignore SIGPIPE on Posix systems We must handle this signal or we'll get the default behavior of exiting the process whenever we get an unexpected network disconnection. --- src/posix.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/posix.cpp b/src/posix.cpp index 2f7554698e..da0397c107 100644 --- a/src/posix.cpp +++ b/src/posix.cpp @@ -65,13 +65,16 @@ const int AltSegFaultSignal = SIGBUS; const int AltSegFaultSignal = InvalidSignal; #endif const unsigned AltSegFaultSignalIndex = 3; +const int PipeSignal = SIGPIPE; +const unsigned PipeSignalIndex = 4; const int signals[] = { VisitSignal, SegFaultSignal, InterruptSignal, - AltSegFaultSignal }; + AltSegFaultSignal, + PipeSignal }; -const unsigned SignalCount = 4; +const unsigned SignalCount = 5; class MySystem; MySystem* system; @@ -530,6 +533,7 @@ class MySystem: public System { system = this; registerHandler(&nullHandler, InterruptSignalIndex); + registerHandler(&nullHandler, PipeSignalIndex); registerHandler(&nullHandler, VisitSignalIndex); expect(this, make(&visitLock) == 0); @@ -786,6 +790,7 @@ class MySystem: public System { registerHandler(0, InterruptSignalIndex); registerHandler(0, VisitSignalIndex); + registerHandler(0, PipeSignalIndex); system = 0; ::free(this); @@ -862,6 +867,10 @@ handleSignal(int signal, siginfo_t* info, void* context) index = InterruptSignalIndex; } break; + case PipeSignal: { + index = PipeSignalIndex; + } break; + default: abort(); } @@ -873,6 +882,7 @@ handleSignal(int signal, siginfo_t* info, void* context) switch (signal) { case VisitSignal: case InterruptSignal: + case PipeSignal: break; default: From cf14a2c22270d6e20d01624ba458f826f7cd356d Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Fri, 15 Oct 2010 23:06:03 +0000 Subject: [PATCH 14/16] add exception for Object.clone() to vm.pro Proguard gets confused about clone() and array classes (see http://sourceforge.net/tracker/index.php?func=detail&aid=2851344&group_id=54750&atid=474704). --- vm.pro | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/vm.pro b/vm.pro index a6a2a54413..c2bd83c3d6 100644 --- a/vm.pro +++ b/vm.pro @@ -97,3 +97,9 @@ -keepnames public class avian.Callback -keepnames public class java.util.concurrent.Callable + +# Proguard gets confused about clone() and array classes (http://sourceforge.net/tracker/index.php?func=detail&aid=2851344&group_id=54750&atid=474704): + +-keepclassmembers class java.lang.Object { + protected java.lang.Object clone(); + } From 5cbfee467ccc80bbff7b8bc35c0a150e3be5c9da Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Fri, 22 Oct 2010 14:39:38 -0600 Subject: [PATCH 15/16] fix Runtime.exec on Posix Due to a silly cut-and-paste error, we were incorrectly passing the stdout and stderr file descriptors back from native code to Java, which prevented reading the output of the child process. --- classpath/java-lang.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/classpath/java-lang.cpp b/classpath/java-lang.cpp index 8303e3e4e1..9331ee099f 100644 --- a/classpath/java-lang.cpp +++ b/classpath/java-lang.cpp @@ -234,7 +234,8 @@ extern "C" JNIEXPORT void JNICALL Java_java_lang_Runtime_exec(JNIEnv* e, jclass, jobjectArray command, jlongArray process) { - char** argv = static_cast(malloc((e->GetArrayLength(command) + 1) * sizeof(char*))); + char** argv = static_cast + (malloc((e->GetArrayLength(command) + 1) * sizeof(char*))); int i; for(i = 0; i < e->GetArrayLength(command); i++){ jstring element = (jstring) e->GetObjectArrayElement(command, i); @@ -255,11 +256,11 @@ Java_java_lang_Runtime_exec(JNIEnv* e, jclass, makePipe(e, out); if(e->ExceptionCheck()) return; jlong outDescriptor = static_cast(out[1]); - e->SetLongArrayRegion(process, 1, 1, &outDescriptor); + e->SetLongArrayRegion(process, 2, 1, &outDescriptor); makePipe(e, err); if(e->ExceptionCheck()) return; jlong errDescriptor = static_cast(err[0]); - e->SetLongArrayRegion(process, 1, 1, &errDescriptor); + e->SetLongArrayRegion(process, 3, 1, &errDescriptor); makePipe(e, msg); if(e->ExceptionCheck()) return; if(fcntl(msg[1], F_SETFD, FD_CLOEXEC) != 0) { From 5ade8d1cf65cf62adc6d8f85072967060f4659fc Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Thu, 28 Oct 2010 20:30:49 -0600 Subject: [PATCH 16/16] use GetSystemTimeAsFileTime instead of _ftime on Windows It seems that _ftime has devolved to only giving 1-second resolution on Windows 7. GetSystemTimeAsFileTime does better, so that's what we'll use. --- classpath/java-lang.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/classpath/java-lang.cpp b/classpath/java-lang.cpp index 9331ee099f..ea37b2f275 100644 --- a/classpath/java-lang.cpp +++ b/classpath/java-lang.cpp @@ -36,9 +36,6 @@ # define isnan _isnan # define isfinite _finite # define strtof strtod -# define FTIME _ftime_s -# else -# define FTIME _ftime # endif #else // not PLATFORM_WINDOWS @@ -469,9 +466,13 @@ extern "C" JNIEXPORT jlong JNICALL Java_java_lang_System_currentTimeMillis(JNIEnv*, jclass) { #ifdef PLATFORM_WINDOWS - _timeb tb; - FTIME(&tb); - return (static_cast(tb.time) * 1000) + static_cast(tb.millitm); + // We used to use _ftime here, but that only gives us 1-second + // resolution on Windows 7. _ftime_s might work better, but MinGW + // doesn't have it as of this writing. So we use this mess instead: + FILETIME time; + GetSystemTimeAsFileTime(&time); + return (((static_cast(time.dwHighDateTime) << 32) + | time.dwLowDateTime) / 10000) - 11644473600000LL; #else timeval tv = { 0, 0 }; gettimeofday(&tv, 0);