diff options
author | no-author <no-author@gcc.gnu.org> | 2003-04-06 03:36:42 +0000 |
---|---|---|
committer | no-author <no-author@gcc.gnu.org> | 2003-04-06 03:36:42 +0000 |
commit | f92817764e0fe40c5418a4d3efd0f9ccdb381190 (patch) | |
tree | 79d831d69421ac4fd2f305edcc61482686bc06ea /libjava | |
parent | bf93592a83866cbdd8f6b31b9358ceb3c034a8dd (diff) |
This commit was manufactured by cvs2svn to create branch
'tree-ssa-20020619-branch'.
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/tree-ssa-20020619-branch@65293 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libjava')
49 files changed, 7764 insertions, 0 deletions
diff --git a/libjava/gnu/javax/rmi/CORBA/DelegateFactory.java b/libjava/gnu/javax/rmi/CORBA/DelegateFactory.java new file mode 100644 index 00000000000..c98549b4059 --- /dev/null +++ b/libjava/gnu/javax/rmi/CORBA/DelegateFactory.java @@ -0,0 +1,74 @@ +/* DelegateFactory.java -- + Copyright (C) 2002 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.javax.rmi.CORBA; + +import java.util.HashMap; +import javax.rmi.CORBA.Util; + +public class DelegateFactory +{ + private static HashMap cache = new HashMap(4); + + public static synchronized Object getInstance(String type) + throws GetDelegateInstanceException + { + Object r = cache.get(type); + if (r != null) + return r; + String dcname = System.getProperty("javax.rmi.CORBA." + type + "Class"); + if (dcname == null) + { + //throw new DelegateException + // ("no javax.rmi.CORBA.XXXClass property sepcified."); + dcname = "gnu.javax.rmi.CORBA." + type + "DelegateImpl"; + } + try + { + Class dclass = Class.forName(dcname); + r = dclass.newInstance(); + cache.put(type, r); + return r; + } + catch(Exception e) + { + throw new GetDelegateInstanceException + ("Exception when trying to get delegate instance:" + dcname, e); + } + } +} diff --git a/libjava/gnu/javax/rmi/CORBA/GetDelegateInstanceException.java b/libjava/gnu/javax/rmi/CORBA/GetDelegateInstanceException.java new file mode 100644 index 00000000000..27b84f12239 --- /dev/null +++ b/libjava/gnu/javax/rmi/CORBA/GetDelegateInstanceException.java @@ -0,0 +1,58 @@ +/* GetDelegateInstanceException.java -- + Copyright (C) 2002 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.javax.rmi.CORBA; + +import java.io.PrintStream; +import java.io.PrintWriter; + +public class GetDelegateInstanceException + extends Exception +{ + private Throwable next; + + public GetDelegateInstanceException(String msg) + { + super(msg); + } + + public GetDelegateInstanceException(String msg, Throwable next) + { + super(msg, next); + } +} diff --git a/libjava/gnu/javax/rmi/CORBA/PortableRemoteObjectDelegateImpl.java b/libjava/gnu/javax/rmi/CORBA/PortableRemoteObjectDelegateImpl.java new file mode 100644 index 00000000000..973c4c4f89f --- /dev/null +++ b/libjava/gnu/javax/rmi/CORBA/PortableRemoteObjectDelegateImpl.java @@ -0,0 +1,133 @@ +/* PortableRemoteObjectDelegateImpl.java -- + Copyright (C) 2002 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.javax.rmi.CORBA; + +import java.rmi.*; +import java.rmi.server.*; +import gnu.javax.rmi.*; +import javax.rmi.CORBA.*; + +public class PortableRemoteObjectDelegateImpl + implements PortableRemoteObjectDelegate +{ + + public PortableRemoteObjectDelegateImpl() + { + } + + public void connect(Remote remote, Remote remote1) + throws RemoteException + { + throw new Error("Not implemented for PortableRemoteObjectDelegateImpl"); + } + + public void exportObject(Remote obj) + throws RemoteException + { + PortableServer.exportObject(obj); + } + + public Object narrow(Object narrowFrom, Class narrowTo) + throws ClassCastException + { + if (narrowTo == null) + throw new ClassCastException("Can't narrow to null class"); + if (narrowFrom == null) + return null; + + Class fromClass = narrowFrom.getClass(); + Object result = null; + + try + { + if (narrowTo.isAssignableFrom(fromClass)) + result = narrowFrom; + else + { + System.out.println("We still haven't implement this case: narrow " + + narrowFrom + " of type " + fromClass + " to " + + narrowTo); + Class[] cs = fromClass.getInterfaces(); + for (int i = 0; i < cs.length; i++) + System.out.println(cs[i]); + Exception e1 = new Exception(); + try + { + throw e1; + } + catch(Exception ee) + { + ee.printStackTrace(); + } + System.exit(2); + //throw new Error("We still haven't implement this case: narrow " + // + narrowFrom + " of type " + fromClass + " to " + // + narrowTo); + /* + ObjectImpl objimpl = (ObjectImpl)narrowFrom; + if(objimpl._is_a(PortableServer.getTypeName(narrowTo))) + result = PortableServer.getStubFromObjectImpl(objimpl, narrowTo); + */ + } + } + catch(Exception e) + { + result = null; + } + + if (result == null) + throw new ClassCastException("Can't narrow from " + + fromClass + " to " + narrowTo); + + return result; + } + + public Remote toStub(Remote obj) + throws NoSuchObjectException + { + return PortableServer.toStub(obj); + } + + public void unexportObject(Remote obj) + throws NoSuchObjectException + { + PortableServer.unexportObject(obj); + } + +} diff --git a/libjava/gnu/javax/rmi/CORBA/StubDelegateImpl.java b/libjava/gnu/javax/rmi/CORBA/StubDelegateImpl.java new file mode 100644 index 00000000000..894e50236fd --- /dev/null +++ b/libjava/gnu/javax/rmi/CORBA/StubDelegateImpl.java @@ -0,0 +1,113 @@ +/* StubDelegateImpl.java -- + Copyright (C) 2002 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.javax.rmi.CORBA; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +//import org.omg.CORBA.portable.Delegate; +//import org.omg.CORBA.portable.InputStream; +//import org.omg.CORBA.portable.OutputStream; +//import org.omg.CORBA_2_3.portable.ObjectImpl; +//import org.omg.CORBA.portable.ObjectImpl; +//import org.omg.CORBA.BAD_OPERATION; +//import org.omg.CORBA.ORB; +import java.rmi.RemoteException; +import javax.rmi.CORBA.Stub; +import javax.rmi.CORBA.StubDelegate; +import javax.rmi.CORBA.Tie; +import javax.rmi.CORBA.StubDelegate; + +public class StubDelegateImpl + implements StubDelegate +{ + + private int hashCode; + + public StubDelegateImpl(){ + hashCode = 0; + } + // XXX javax.rmi.ORB -> org.omg.CORBA.ORB + public void connect(Stub self, javax.rmi.ORB orb) + throws RemoteException + { + throw new Error("Not implemented for StubDelegate"); + } + + public boolean equals(Stub self, Object obj) + { + if(self == null || obj == null) + return self == obj; + if(!(obj instanceof Stub)) + return false; + return self.hashCode() == ((Stub)obj).hashCode(); + } + + public int hashCode(Stub self) + { + //FIX ME + return hashCode; + } + + public String toString(Stub self) + { + try + { + return self._orb().object_to_string(self); + } + // XXX javax.rmi.BAD_OPERATION -> org.omg.CORBA.BAD_OPERATION + catch(javax.rmi.BAD_OPERATION bad_operation) + { + return null; + } + } + + public void readObject(Stub self, ObjectInputStream s) + throws IOException, ClassNotFoundException + { + throw new Error("Not implemented for StubDelegate"); + } + + public void writeObject(Stub self, ObjectOutputStream s) + throws IOException + { + throw new Error("Not implemented for StubDelegate"); + } + +} diff --git a/libjava/gnu/javax/rmi/CORBA/UtilDelegateImpl.java b/libjava/gnu/javax/rmi/CORBA/UtilDelegateImpl.java new file mode 100644 index 00000000000..70b2e60c673 --- /dev/null +++ b/libjava/gnu/javax/rmi/CORBA/UtilDelegateImpl.java @@ -0,0 +1,152 @@ +/* UtilDelegateImpl.java -- + Copyright (C) 2002 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.javax.rmi.CORBA; + +import java.rmi.Remote; +import java.rmi.RemoteException; +import java.rmi.server.RMIClassLoader; +import java.net.MalformedURLException; +import java.io.*; +//import org.omg.CORBA.ORB; +//import org.omg.CORBA.SystemException; +//import org.omg.CORBA.portable.InputStream; +//import org.omg.CORBA.portable.OutputStream; +import javax.rmi.CORBA.*; + +public class UtilDelegateImpl + implements UtilDelegate +{ + // XXX javax.rmi.ORB -> org.omg.CORBA.ORB + public Object copyObject(Object obj, javax.rmi.ORB orb) + throws RemoteException + { + throw new Error("Not implemented for UtilDelegate"); + } + + // XXX javax.rmi.ORB -> org.omg.CORBA.ORB + public Object[] copyObjects(Object obj[], javax.rmi.ORB orb) + throws RemoteException + { + throw new Error("Not implemented for UtilDelegate"); + } + + public ValueHandler createValueHandler() + { + throw new Error("Not implemented for UtilDelegate"); + } + + public String getCodebase(Class clz) + { + throw new Error("Not implemented for UtilDelegate"); + } + + public Tie getTie(Remote target) + { + throw new Error("Not implemented for UtilDelegate"); + } + + public boolean isLocal(Stub stub) + throws RemoteException + { + throw new Error("Not implemented for UtilDelegate"); + } + + public Class loadClass(String className, String remoteCodebase, + ClassLoader loader) + throws ClassNotFoundException + { + try{ + if (remoteCodebase == null) + return RMIClassLoader.loadClass(className); + else + return RMIClassLoader.loadClass(remoteCodebase, className); + } + catch (MalformedURLException e1) + { + throw new ClassNotFoundException(className, e1); + } + catch(ClassNotFoundException e2) + { + if(loader != null) + return loader.loadClass(className); + else + return null; + } + } + + public RemoteException mapSystemException(SystemException ex) + { + throw new Error("Not implemented for UtilDelegate"); + } + + public Object readAny(InputStream in) + { + throw new Error("Not implemented for UtilDelegate"); + } + + public void registerTarget(Tie tie, Remote target) + { + throw new Error("Not implemented for UtilDelegate"); + } + + public void unexportObject(Remote target) + { + throw new Error("Not implemented for UtilDelegate"); + } + + public RemoteException wrapException(Throwable orig) + { + throw new Error("Not implemented for UtilDelegate"); + } + + public void writeAbstractObject(OutputStream out, Object obj) + { + throw new Error("Not implemented for UtilDelegate"); + } + + public void writeAny(OutputStream out, Object obj) + { + throw new Error("Not implemented for UtilDelegate"); + } + + public void writeRemoteObject(OutputStream out, Object obj) + { + throw new Error("Not implemented for UtilDelegate"); + } +} diff --git a/libjava/gnu/javax/rmi/CORBA/ValueHandlerImpl.java b/libjava/gnu/javax/rmi/CORBA/ValueHandlerImpl.java new file mode 100644 index 00000000000..6935aa68c4c --- /dev/null +++ b/libjava/gnu/javax/rmi/CORBA/ValueHandlerImpl.java @@ -0,0 +1,82 @@ +/* ValueHandlerImpl.java -- + Copyright (C) 2002 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.javax.rmi.CORBA; + +import java.io.*; +//import org.omg.CORBA.portable.InputStream; +//import org.omg.CORBA.portable.OutputStream; +//import org.omg.SendingContext.RunTime; +import javax.rmi.CORBA.ValueHandler; + +public class ValueHandlerImpl + implements ValueHandler +{ + + public String getRMIRepositoryID(Class clz) + { + throw new Error("Not implemented for ValueHandler"); + } + + // XXX - Runtime -> RunTime + public Runtime getRunTimeCodeBase() + { + throw new Error("Not implemented for ValueHandler"); + } + + public boolean isCustomMarshaled(Class clz) + { + throw new Error("Not implemented for ValueHandler"); + } + + // XXX - Runtime -> RunTime + public Serializable readValue(InputStream in, int offset, Class clz, String repositoryID, Runtime sender) + { + throw new Error("Not implemented for ValueHandler"); + } + + public Serializable writeReplace(Serializable value) + { + throw new Error("Not implemented for ValueHandler"); + } + + public void writeValue(OutputStream out, Serializable value) + { + throw new Error("Not implemented for ValueHandler"); + } +} diff --git a/libjava/gnu/javax/rmi/PortableServer.java b/libjava/gnu/javax/rmi/PortableServer.java new file mode 100644 index 00000000000..b5022cab7b3 --- /dev/null +++ b/libjava/gnu/javax/rmi/PortableServer.java @@ -0,0 +1,142 @@ +/* PortableServer.java -- + Copyright (C) 2002 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.javax.rmi; + +import java.util.Hashtable; +import java.rmi.Remote; +import java.rmi.RemoteException; +import java.rmi.NoSuchObjectException; +import java.rmi.server.ExportException; +import java.rmi.server.UnicastRemoteObject; +import java.rmi.server.RemoteStub; +import javax.rmi.CORBA.*; +//import org.omg.CORBA.portable.ObjectImpl; + +/** + * The relationship of PortableRemoteObjectImpl with PortableServer + * is like that of UnicastRemoteObject with UnicastServer + */ +public class PortableServer +{ + static private Hashtable tieCache = new Hashtable(); + static private Object NO_TIE = new Object(); + + public static final synchronized void exportObject(Remote obj) + throws RemoteException + { + if(Util.getTie(obj) != null) + return; + + Tie tie = getTieFromRemote(obj); + if (tie != null) + Util.registerTarget(tie, obj); + else + UnicastRemoteObject.exportObject(obj); + } + + public static final void unexportObject(Remote obj) + { + if (Util.getTie(obj) != null) + Util.unexportObject(obj); + if (tieCache.get(obj) != null) //?? + tieCache.remove(obj); + } + + public static final Remote toStub(Remote obj) + throws NoSuchObjectException + { + if (obj instanceof Stub || obj instanceof RemoteStub) + return obj; + + Tie tie = Util.getTie(obj); + Remote stub; + if (tie != null) + stub = getStubFromTie(tie); + else + throw new NoSuchObjectException("Can't toStub an unexported object"); + return stub; + } + + static synchronized Tie getTieFromRemote(Remote obj) + { + Object tie = tieCache.get(obj); + if (tie == null) + { + tie = getTieFromClass(obj.getClass()); + if(tie == null) + tieCache.put(obj, NO_TIE); + else + tieCache.put(obj, tie); + } + else + if(tie != NO_TIE) + { + try + { + tie = obj.getClass().newInstance(); + } + catch(Exception _) + { + tie = null; + } + } + else //NO_TIE + tie = null; + + return (Tie)tie; + } + + static synchronized Tie getTieFromClass(Class clz) + { + //FIX ME + return null; + } + + public static Remote getStubFromTie(Tie tie) + { + //FIX ME + return null; + } + + public static Remote getStubFromObjectImpl(ObjectImpl objimpl, Class toClass) + { + //FIX ME + return null; + } +} diff --git a/libjava/java/beans/beancontext/BeanContextServicesSupport.java b/libjava/java/beans/beancontext/BeanContextServicesSupport.java new file mode 100644 index 00000000000..02ee53aa909 --- /dev/null +++ b/libjava/java/beans/beancontext/BeanContextServicesSupport.java @@ -0,0 +1,291 @@ +/* java.beans.beancontext.BeanContextServicesSupport + Copyright (C) 2003 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.beans.beancontext; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Locale; +import java.util.TooManyListenersException; + +/** + * @author Michael Koch + * @since 1.2 + */ +public class BeanContextServicesSupport + extends BeanContextSupport + implements BeanContextServices +{ + private static final long serialVersionUID = -8494482757288719206L; + + protected class BCSSChild + extends BeanContextSupport.BCSChild + { + private static final long serialVersionUID = -6848044915271367103L; + } + + protected class BCSSProxyServiceProvider + implements BeanContextServiceProvider, + BeanContextServiceRevokedListener + { + private static final long serialVersionUID = 7078212910685744490L; + + public Iterator getCurrentServiceSelectors (BeanContextServices bcs, + Class serviceClass) + { + throw new Error ("Not implemented"); + } + + public Object getService (BeanContextServices bcs, + Object requestor, + Class serviceClass, + Object serviceSelector) + { + throw new Error ("Not implemented"); + } + + public void releaseService (BeanContextServices bcs, + Object requestor, + Object service) + { + throw new Error ("Not implemented"); + } + + public void serviceRevoked (BeanContextServiceRevokedEvent bcsre) + { + throw new Error ("Not implemented"); + } + } + + protected static class BCSSServiceProvider + implements Serializable + { + protected BeanContextServiceProvider serviceProvider; + + protected BeanContextServiceProvider getServiceProvider() + { + return serviceProvider; + } + } + + protected transient ArrayList bcsListeners; + + protected transient BCSSProxyServiceProvider proxy; + + protected transient int serializable; + + protected transient HashMap services; + + public BeanContextServicesSupport () + { + this (null, null, true, true); + } + + public BeanContextServicesSupport (BeanContextServices peer) + { + this (peer, null, true, true); + } + + public BeanContextServicesSupport (BeanContextServices peer, Locale lcle) + { + this (peer, lcle, true, true); + } + + public BeanContextServicesSupport (BeanContextServices peer, Locale lcle, + boolean dtime) + { + this (peer, lcle, dtime, true); + } + + public BeanContextServicesSupport (BeanContextServices peer, Locale lcle, + boolean dtime, boolean visible) + { + throw new Error ("Not implemented"); + } + + public void addBeanContextServicesListener (BeanContextServicesListener bcsl) + { + throw new Error ("Not implemented"); + } + + public boolean addService (Class serviceClass, BeanContextServiceProvider bcsp) + { + throw new Error ("Not implemented"); + } + + protected boolean addService (Class serviceClass, + BeanContextServiceProvider bcsp, + boolean fireEvent) + { + throw new Error ("Not implemented"); + } + + protected void bcsPreDeserializationHook (ObjectInputStream ois) + throws ClassNotFoundException, IOException + { + throw new Error ("Not implemented"); + } + + protected void bcsPreSerializationHook (ObjectOutputStream oos) + throws IOException + { + throw new Error ("Not implemented"); + } + + protected void childJustRemovedHook (Object child, + BeanContextSupport.BCSChild bcsc) + { + throw new Error ("Not implemented"); + } + + protected BeanContextSupport.BCSChild createBCSChild (Object targetChild, + Object peer) + { + throw new Error ("Not implemented"); + } + + protected BeanContextServicesSupport.BCSSServiceProvider + createBCSSServiceProvider (Class sc, BeanContextServiceProvider bcsp) + { + throw new Error ("Not implemented"); + } + + protected final void fireServiceAdded (BeanContextServiceAvailableEvent bcssae) + { + throw new Error ("Not implemented"); + } + + protected final void fireServiceAdded (Class serviceClass) + { + throw new Error ("Not implemented"); + } + + protected final void + fireServiceRevoked (BeanContextServiceRevokedEvent bcsre) + { + throw new Error ("Not implemented"); + } + + protected final void fireServiceRevoked (Class serviceClass, + boolean revokeNow) + { + throw new Error ("Not implemented"); + } + + public BeanContextServices getBeanContextServicesPeer () + { + throw new Error ("Not implemented"); + } + + protected static final BeanContextServicesListener + getChildBeanContextServicesListener (Object child) + { + throw new Error ("Not implemented"); + } + + public Iterator getCurrentServiceClasses () + { + throw new Error ("Not implemented"); + } + + public Iterator getCurrentServiceSelectors (Class serviceClass) + { + throw new Error ("Not implemented"); + } + + public Object getService (BeanContextChild child, Object requestor, + Class serviceClass, Object serviceSelector, + BeanContextServiceRevokedListener bcsrl) + throws TooManyListenersException + { + throw new Error ("Not implemented"); + } + + public boolean hasService (Class serviceClass) + { + throw new Error ("Not implemented"); + } + + public void initialize () + { + throw new Error ("Not implemented"); + } + + protected void initializeBeanContextResources () + { + throw new Error ("Not implemented"); + } + + protected void releaseBeanContextResources () + { + throw new Error ("Not implemented"); + } + + public void releaseService (BeanContextChild child, Object requestor, + Object service) + { + throw new Error ("Not implemented"); + } + + public void + removeBeanContextServicesListener (BeanContextServicesListener bcsl) + { + throw new Error ("Not implemented"); + } + + public void revokeService (Class serviceClass, BeanContextServiceProvider bcsp, + boolean revokeCurrentServicesNow) + { + throw new Error ("Not implemented"); + } + + public void serviceAvailable (BeanContextServiceAvailableEvent bcssae) + { + throw new Error ("Not implemented"); + } + + public void serviceRevoked (BeanContextServiceRevokedEvent bcssre) + { + throw new Error ("Not implemented"); + } +} diff --git a/libjava/java/beans/beancontext/BeanContextSupport.java b/libjava/java/beans/beancontext/BeanContextSupport.java new file mode 100644 index 00000000000..5af299f5bb1 --- /dev/null +++ b/libjava/java/beans/beancontext/BeanContextSupport.java @@ -0,0 +1,448 @@ +/* java.beans.beancontext.BeanContextSupport + Copyright (C) 2003 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.beans.beancontext; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.beans.PropertyVetoException; +import java.beans.VetoableChangeListener; +import java.beans.Visibility; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Locale; + +/** + * @author Michael Koch + * @since 1.2 + */ +public class BeanContextSupport extends BeanContextChildSupport + implements BeanContext, Serializable, PropertyChangeListener, + VetoableChangeListener +{ + private static final long serialVersionUID = -4879613978649577204L; + + private void readObject (ObjectInputStream s) + throws ClassNotFoundException, IOException + { + throw new Error ("Not implemented"); + } + + private void writeObject (ObjectOutputStream s) + throws ClassNotFoundException, IOException + { + throw new Error ("Not implemented"); + } + + protected class BCSChild implements Serializable + { + private static final long serialVersionUID = 3289144128843950629L; + } + + protected static class BCSIterator implements Iterator + { + public boolean hasNext () + { + throw new Error ("Not implemented"); + } + + public Object next () + { + throw new Error ("Not implemented"); + } + + public void remove () + { + // This must be a noop remove operation. + } + } + + protected transient ArrayList bcmListeners; + + protected transient HashMap children; + + protected transient boolean designTime; + + protected transient Locale locale; + + protected transient boolean okToUseGui; + + /** + * Construct a BeanContextSupport instance. + */ + public BeanContextSupport () + { + this (null, null, true, true); + } + + /** + * Construct a BeanContextSupport instance. + */ + public BeanContextSupport (BeanContext peer) + { + this (peer, null, true, true); + } + + /** + * Construct a BeanContextSupport instance. + */ + public BeanContextSupport (BeanContext peer, Locale lcle) + { + this (peer, lcle, true, true); + } + + /** + * Construct a BeanContextSupport instance. + */ + public BeanContextSupport (BeanContext peer, Locale lcle, boolean dtime) + { + this (peer, lcle, dtime, true); + } + + /** + * Construct a BeanContextSupport instance. + */ + public BeanContextSupport (BeanContext peer, Locale lcle, boolean dtime, + boolean visible) + { + locale = lcle; + designTime = dtime; + okToUseGui = visible; + + initialize (); + + throw new Error ("Not implemented"); + } + + public boolean add (Object targetChild) + { + throw new Error ("Not implemented"); + } + + public boolean addAll (Collection c) + { + throw new Error ("Not implemented"); + } + + public void addBeanContextMembershipListener (BeanContextMembershipListener bcml) + { + throw new Error ("Not implemented"); + } + + public boolean avoidingGui () + { + throw new Error ("Not implemented"); + } + + protected Iterator bcsChildren () + { + throw new Error ("Not implemented"); + } + + protected void bcsPreDeserializationHook (ObjectInputStream ois) + throws ClassNotFoundException, IOException + { + throw new Error ("Not implemented"); + } + + protected void bcsPreSerializationHook (ObjectOutputStream oos) + throws IOException + { + throw new Error ("Not implemented"); + } + + protected void childDeserializedHook (Object child, BeanContextSupport.BCSChild bcsc) + { + throw new Error ("Not implemented"); + } + + protected void childJustAddedHook (Object child, BeanContextSupport.BCSChild bcsc) + { + throw new Error ("Not implemented"); + } + + protected void childJustRemovedHook (Object child, BeanContextSupport.BCSChild bcsc) + { + throw new Error ("Not implemented"); + } + + protected static final boolean classEquals (Class first, Class second) + { + throw new Error ("Not implemented"); + } + + public void clear () + { + throw new Error ("Not implemented"); + } + + public boolean contains (Object o) + { + throw new Error ("Not implemented"); + } + + public boolean containsAll (Collection c) + { + throw new Error ("Not implemented"); + } + + public boolean containsKey (Object o) + { + throw new Error ("Not implemented"); + } + + protected final Object[] copyChildren () + { + throw new Error ("Not implemented"); + } + + protected BeanContextSupport.BCSChild createBCSChild (Object targetChild, Object peer) + { + throw new Error ("Not implemented"); + } + + protected final void deserialize (ObjectInputStream ois, Collection coll) + throws ClassNotFoundException, IOException + { + throw new Error ("Not implemented"); + } + + public void dontUseGui () + { + throw new Error ("Not implemented"); + } + + protected final void fireChildrenAdded (BeanContextMembershipEvent bcme) + { + throw new Error ("Not implemented"); + } + + protected final void fireChildrenRemoved (BeanContextMembershipEvent bcme) + { + throw new Error ("Not implemented"); + } + + public BeanContext getBeanContextPeer () + { + throw new Error ("Not implemented"); + } + + protected static final BeanContextChild getChildBeanContextChild (Object child) + { + throw new Error ("Not implemented"); + } + + protected static final BeanContextMembershipListener getChildBeanContextMembershipListener (Object child) + { + throw new Error ("Not implemented"); + } + + protected static final PropertyChangeListener getChildPropertyChangeListener (Object child) + { + throw new Error ("Not implemented"); + } + + protected static final Serializable getChildSerializable (Object child) + { + throw new Error ("Not implemented"); + } + + protected static final VetoableChangeListener getChildVetoableChangeListener (Object child) + { + throw new Error ("Not implemented"); + } + + protected static final Visibility getChildVisibility (Object child) + { + throw new Error ("Not implemented"); + } + + public Locale getLocale () + { + throw new Error ("Not implemented"); + } + + public URL getResource (String name, BeanContextChild bcc) + { + throw new Error ("Not implemented"); + } + + public InputStream getResourceAsStream (String name, BeanContextChild bcc) + { + throw new Error ("Not implemented"); + } + + protected void initialize () + { + throw new Error ("Not implemented"); + } + + public Object instantiateChild (String beanName) + throws IOException, ClassNotFoundException + { + throw new Error ("Not implemented"); + } + + public boolean isDesignTime () + { + throw new Error ("Not implemented"); + } + + public boolean isEmpty () + { + throw new Error ("Not implemented"); + } + + public boolean isSerializing () + { + throw new Error ("Not implemented"); + } + + public Iterator iterator () + { + throw new Error ("Not implemented"); + } + + public boolean needsGui () + { + throw new Error ("Not implemented"); + } + + public void okToUseGui () + { + throw new Error ("Not implemented"); + } + + public void propertyChange (PropertyChangeEvent pce) + { + throw new Error ("Not implemented"); + } + + public final void readChildren (ObjectInputStream ois) + throws IOException, ClassNotFoundException + { + throw new Error ("Not implemented"); + } + + public boolean remove (Object targetChild) + { + throw new Error ("Not implemented"); + } + + protected boolean remove (Object targetChild, boolean callChildSetBC) + { + throw new Error ("Not implemented"); + } + + public boolean removeAll (Collection c) + { + throw new Error ("Not implemented"); + } + + public void removeBeanContextMembershipListener (BeanContextMembershipListener bcml) + { + throw new Error ("Not implemented"); + } + + public boolean retainAll (Collection c) + { + throw new Error ("Not implemented"); + } + + protected final void serialize (ObjectOutputStream oos, Collection coll) + throws IOException + { + throw new Error ("Not implemented"); + } + + public void setDesignTime (boolean dtime) + { + throw new Error ("Not implemented"); + } + + public void setLocale (Locale newLocale) + throws PropertyVetoException + { + throw new Error ("Not implemented"); + } + + public int size () + { + throw new Error ("Not implemented"); + } + + public Object[] toArray () + { + throw new Error ("Not implemented"); + } + + public Object[] toArray (Object[] arry) + { + throw new Error ("Not implemented"); + } + + protected boolean validatePendingAdd (Object targetChild) + { + throw new Error ("Not implemented"); + } + + protected boolean validatePendingRemove (Object targetChild) + { + throw new Error ("Not implemented"); + } + + public void vetoableChange (PropertyChangeEvent pce) + throws PropertyVetoException + { + throw new Error ("Not implemented"); + } + + public final void writeChildren (ObjectOutputStream oos) + throws IOException + { + throw new Error ("Not implemented"); + } +} diff --git a/libjava/java/net/natInetAddressNoNet.cc b/libjava/java/net/natInetAddressNoNet.cc new file mode 100644 index 00000000000..0374af18f88 --- /dev/null +++ b/libjava/java/net/natInetAddressNoNet.cc @@ -0,0 +1,36 @@ +/* Copyright (C) 2003 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 <stddef.h> + +#include <java/net/InetAddress.h> + +jbyteArray +java::net::InetAddress::aton (jstring) +{ + return NULL; +} + +jint +java::net::InetAddress::getFamily (jbyteArray bytes) +{ + return 0; +} + +JArray<java::net::InetAddress*> * +java::net::InetAddress::lookup (jstring, java::net::InetAddress *, jboolean) +{ + return NULL; +} + +jstring +java::net::InetAddress::getLocalHostname () +{ + return NULL; +} diff --git a/libjava/java/net/natInetAddressPosix.cc b/libjava/java/net/natInetAddressPosix.cc new file mode 100644 index 00000000000..b97502e19b0 --- /dev/null +++ b/libjava/java/net/natInetAddressPosix.cc @@ -0,0 +1,311 @@ +/* Copyright (C) 2003 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> + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#include <string.h> +#include <errno.h> + +#include <sys/param.h> +#include <sys/types.h> +#ifdef HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif +#ifdef HAVE_NETINET_IN_H +#include <netinet/in.h> +#endif +#ifdef HAVE_ARPA_INET_H +#include <arpa/inet.h> +#endif +#ifdef HAVE_NETDB_H +#include <netdb.h> +#endif + +#include <gcj/cni.h> +#include <jvm.h> +#include <java/net/InetAddress.h> +#include <java/net/UnknownHostException.h> +#include <java/lang/SecurityException.h> + +#if defined(HAVE_UNAME) && ! defined(HAVE_GETHOSTNAME) +#include <sys/utsname.h> +#endif + +#ifndef HAVE_GETHOSTNAME_DECL +extern "C" int gethostname (char *name, int namelen); +#endif + +jbyteArray +java::net::InetAddress::aton (jstring host) +{ + char *hostname; + char buf[100]; + int len = JvGetStringUTFLength(host); + if (len < 100) + hostname = buf; + else + hostname = (char*) _Jv_AllocBytes (len+1); + JvGetStringUTFRegion (host, 0, host->length(), hostname); + buf[len] = '\0'; + char* bytes = NULL; + int blen = 0; +#ifdef HAVE_INET_ATON + struct in_addr laddr; + if (inet_aton (hostname, &laddr)) + { + bytes = (char*) &laddr; + blen = 4; + } +#elif defined(HAVE_INET_ADDR) +#if ! HAVE_IN_ADDR_T + typedef jint in_addr_t; +#endif + in_addr_t laddr = inet_addr (hostname); + if (laddr != (in_addr_t)(-1)) + { + bytes = (char*) &laddr; + blen = 4; + } +#endif +#if defined (HAVE_INET_PTON) && defined (HAVE_INET6) + char inet6_addr[16]; + if (len != 0 && inet_pton (AF_INET6, hostname, inet6_addr) > 0) + { + bytes = inet6_addr; + blen = 16; + } +#endif + if (blen == 0) + return NULL; + jbyteArray result = JvNewByteArray (blen); + memcpy (elements (result), bytes, blen); + return result; +} + +jint +java::net::InetAddress::getFamily (jbyteArray bytes) +{ + int len = bytes->length; + if (len == 4) + return AF_INET; +#ifdef HAVE_INET6 + else if (len == 16) + return AF_INET6; +#endif /* HAVE_INET6 */ + else + JvFail ("unrecognized size"); +} + + +JArray<java::net::InetAddress*> * +java::net::InetAddress::lookup (jstring host, java::net::InetAddress* iaddr, + jboolean all) +{ + struct hostent *hptr = NULL; +#if defined (HAVE_GETHOSTBYNAME_R) || defined (HAVE_GETHOSTBYADDR_R) + struct hostent hent_r; +#if HAVE_STRUCT_HOSTENT_DATA + struct hostent_data fixed_buffer, *buffer_r = &fixed_buffer; +#else +#if defined (__GLIBC__) + // FIXME: in glibc, gethostbyname_r returns NETDB_INTERNAL to herr and + // ERANGE to errno if the buffer size is too small, rather than what is + // expected here. We work around this by setting a bigger buffer size and + // hoping that it is big enough. + char fixed_buffer[1024]; +#else + char fixed_buffer[200]; +#endif + char *buffer_r = fixed_buffer; + int size_r = sizeof (fixed_buffer); +#endif +#endif + + if (host != NULL) + { + char *hostname; + char buf[100]; + int len = JvGetStringUTFLength(host); + if (len < 100) + hostname = buf; + else + hostname = (char*) _Jv_AllocBytes (len+1); + JvGetStringUTFRegion (host, 0, host->length(), hostname); + buf[len] = '\0'; +#ifdef HAVE_GETHOSTBYNAME_R + while (true) + { + int ok; +#if HAVE_STRUCT_HOSTENT_DATA + ok = ! gethostbyname_r (hostname, &hent_r, buffer_r); +#else + int herr = 0; +#ifdef GETHOSTBYNAME_R_RETURNS_INT + ok = ! gethostbyname_r (hostname, &hent_r, buffer_r, size_r, + &hptr, &herr); +#else + hptr = gethostbyname_r (hostname, &hent_r, buffer_r, size_r, &herr); + ok = hptr != NULL; +#endif /* GETHOSTNAME_R_RETURNS_INT */ + if (! ok && herr == ERANGE) + { + size_r *= 2; + buffer_r = (char *) _Jv_AllocBytes (size_r); + } + else +#endif /* HAVE_STRUCT_HOSTENT_DATA */ + break; + } +#else + // FIXME: this is insufficient if some other piece of code calls + // this gethostbyname. + JvSynchronize sync (java::net::InetAddress::localhostAddress); + hptr = gethostbyname (hostname); +#endif /* HAVE_GETHOSTBYNAME_R */ + } + else + { + jbyteArray bytes = iaddr->addr; + char *chars = (char*) elements (bytes); + int len = bytes->length; + int type; + char *val; + if (len == 4) + { + val = chars; + type = iaddr->family = AF_INET; + } +#ifdef HAVE_INET6 + else if (len == 16) + { + val = (char *) &chars; + type = iaddr->family = AF_INET6; + } +#endif /* HAVE_INET6 */ + else + JvFail ("unrecognized size"); + +#ifdef HAVE_GETHOSTBYADDR_R + while (true) + { + int ok; +#if HAVE_STRUCT_HOSTENT_DATA + ok = ! gethostbyaddr_r (val, len, type, &hent_r, buffer_r); +#else + int herr = 0; +#ifdef GETHOSTBYADDR_R_RETURNS_INT + ok = ! gethostbyaddr_r (val, len, type, &hent_r, + buffer_r, size_r, &hptr, &herr); +#else + hptr = gethostbyaddr_r (val, len, type, &hent_r, + buffer_r, size_r, &herr); + ok = hptr != NULL; +#endif /* GETHOSTBYADDR_R_RETURNS_INT */ + if (! ok && herr == ERANGE) + { + size_r *= 2; + buffer_r = (char *) _Jv_AllocBytes (size_r); + } + else +#endif /* HAVE_STRUCT_HOSTENT_DATA */ + break; + } +#else /* HAVE_GETHOSTBYADDR_R */ + // FIXME: this is insufficient if some other piece of code calls + // this gethostbyaddr. + JvSynchronize sync (java::net::InetAddress::localhostAddress); + hptr = gethostbyaddr (val, len, type); +#endif /* HAVE_GETHOSTBYADDR_R */ + } + if (hptr != NULL) + { + if (!all) + host = JvNewStringUTF (hptr->h_name); + java::lang::SecurityException *ex = checkConnect (host); + if (ex != NULL) + { + if (iaddr == NULL || iaddr->addr == NULL) + throw ex; + hptr = NULL; + } + } + if (hptr == NULL) + { + if (iaddr != NULL && iaddr->addr != NULL) + { + iaddr->hostName = iaddr->getHostAddress(); + return NULL; + } + else + throw new java::net::UnknownHostException(host); + } + int count; + if (all) + { + char** ptr = hptr->h_addr_list; + count = 0; + while (*ptr++) count++; + } + else + count = 1; + JArray<java::net::InetAddress*> *result; + java::net::InetAddress** iaddrs; + if (all) + { + result = java::net::InetAddress::allocArray (count); + iaddrs = elements (result); + } + else + { + result = NULL; + iaddrs = &iaddr; + } + + for (int i = 0; i < count; i++) + { + if (iaddrs[i] == NULL) + iaddrs[i] = new java::net::InetAddress (NULL, NULL); + if (iaddrs[i]->hostName == NULL) + iaddrs[i]->hostName = host; + if (iaddrs[i]->addr == NULL) + { + char *bytes = hptr->h_addr_list[i]; + iaddrs[i]->addr = JvNewByteArray (hptr->h_length); + iaddrs[i]->family = getFamily (iaddrs[i]->addr); + memcpy (elements (iaddrs[i]->addr), bytes, hptr->h_length); + } + } + return result; +} + +jstring +java::net::InetAddress::getLocalHostname () +{ + char *chars; +#ifdef HAVE_GETHOSTNAME + char buffer[MAXHOSTNAMELEN]; + if (gethostname (buffer, MAXHOSTNAMELEN)) + return NULL; + chars = buffer; +#elif HAVE_UNAME + struct utsname stuff; + if (uname (&stuff) != 0) + return NULL; + chars = stuff.nodename; +#else + return NULL; +#endif + // It is admittedly non-optimal to convert the hostname to Unicode + // only to convert it back in getByName, but simplicity wins. Note + // that unless there is a SecurityManager, we only get called once + // anyway, thanks to the InetAddress.localhost cache. + return JvNewStringUTF (chars); +} diff --git a/libjava/java/net/natInetAddressWin32.cc b/libjava/java/net/natInetAddressWin32.cc new file mode 100644 index 00000000000..f6748fd5691 --- /dev/null +++ b/libjava/java/net/natInetAddressWin32.cc @@ -0,0 +1,355 @@ +/* Copyright (C) 2003 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> + +#ifdef WIN32 + +#include <windows.h> +#include <winsock.h> +#undef STRICT + +#ifndef MAXHOSTNAMELEN +#define MAXHOSTNAMELEN 64 +#endif /* MAXHOSTNAMELEN */ + +#else /* WIN32 */ + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#include <string.h> +#include <errno.h> + +#include <sys/param.h> +#include <sys/types.h> +#ifdef HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif +#ifdef HAVE_NETINET_IN_H +#include <netinet/in.h> +#endif +#ifdef HAVE_ARPA_INET_H +#include <arpa/inet.h> +#endif +#ifdef HAVE_NETDB_H +#include <netdb.h> +#endif + +#endif /* WIN32 */ + +#include <gcj/cni.h> +#include <jvm.h> +#include <java/net/InetAddress.h> +#include <java/net/UnknownHostException.h> +#include <java/lang/SecurityException.h> + +#if defined(HAVE_UNAME) && ! defined(HAVE_GETHOSTNAME) +#include <sys/utsname.h> +#endif + +#ifndef HAVE_GETHOSTNAME_DECL +extern "C" int gethostname (char *name, int namelen); +#endif + +#ifdef DISABLE_JAVA_NET + +jbyteArray +java::net::InetAddress::aton (jstring) +{ + return NULL; +} + +jint +java::net::InetAddress::getFamily (jbyteArray bytes) +{ + return 0; +} + +JArray<java::net::InetAddress*> * +java::net::InetAddress::lookup (jstring, java::net::InetAddress *, jboolean) +{ + return NULL; +} + +jstring +java::net::InetAddress::getLocalHostname () +{ + return NULL; +} + +#else /* DISABLE_JAVA_NET */ + +jbyteArray +java::net::InetAddress::aton (jstring host) +{ + char *hostname; + char buf[100]; + int len = JvGetStringUTFLength(host); + if (len < 100) + hostname = buf; + else + hostname = (char*) _Jv_AllocBytes (len+1); + JvGetStringUTFRegion (host, 0, host->length(), hostname); + buf[len] = '\0'; + char* bytes = NULL; + int blen = 0; +#ifdef HAVE_INET_ATON + struct in_addr laddr; + if (inet_aton (hostname, &laddr)) + { + bytes = (char*) &laddr; + blen = 4; + } +#elif defined(HAVE_INET_ADDR) +#if ! HAVE_IN_ADDR_T + typedef jint in_addr_t; +#endif + in_addr_t laddr = inet_addr (hostname); + if (laddr != (in_addr_t)(-1)) + { + bytes = (char*) &laddr; + blen = 4; + } +#endif +#if defined (HAVE_INET_PTON) && defined (HAVE_INET6) + char inet6_addr[16]; + if (len != 0 && inet_pton (AF_INET6, hostname, inet6_addr) > 0) + { + bytes = inet6_addr; + blen = 16; + } +#endif + if (blen == 0) + return NULL; + jbyteArray result = JvNewByteArray (blen); + memcpy (elements (result), bytes, blen); + return result; +} + +jint +java::net::InetAddress::getFamily (jbyteArray bytes) +{ + int len = bytes->length; + if (len == 4) + return AF_INET; +#ifdef HAVE_INET6 + else if (len == 16) + return AF_INET6; +#endif /* HAVE_INET6 */ + else + JvFail ("unrecognized size"); +} + + +JArray<java::net::InetAddress*> * +java::net::InetAddress::lookup (jstring host, java::net::InetAddress* iaddr, + jboolean all) +{ + struct hostent *hptr = NULL; +#if defined (HAVE_GETHOSTBYNAME_R) || defined (HAVE_GETHOSTBYADDR_R) + struct hostent hent_r; +#if HAVE_STRUCT_HOSTENT_DATA + struct hostent_data fixed_buffer, *buffer_r = &fixed_buffer; +#else +#if defined (__GLIBC__) + // FIXME: in glibc, gethostbyname_r returns NETDB_INTERNAL to herr and + // ERANGE to errno if the buffer size is too small, rather than what is + // expected here. We work around this by setting a bigger buffer size and + // hoping that it is big enough. + char fixed_buffer[1024]; +#else + char fixed_buffer[200]; +#endif + char *buffer_r = fixed_buffer; + int size_r = sizeof (fixed_buffer); +#endif +#endif + + if (host != NULL) + { + char *hostname; + char buf[100]; + int len = JvGetStringUTFLength(host); + if (len < 100) + hostname = buf; + else + hostname = (char*) _Jv_AllocBytes (len+1); + JvGetStringUTFRegion (host, 0, host->length(), hostname); + buf[len] = '\0'; +#ifdef HAVE_GETHOSTBYNAME_R + while (true) + { + int ok; +#if HAVE_STRUCT_HOSTENT_DATA + ok = ! gethostbyname_r (hostname, &hent_r, buffer_r); +#else + int herr = 0; +#ifdef GETHOSTBYNAME_R_RETURNS_INT + ok = ! gethostbyname_r (hostname, &hent_r, buffer_r, size_r, + &hptr, &herr); +#else + hptr = gethostbyname_r (hostname, &hent_r, buffer_r, size_r, &herr); + ok = hptr != NULL; +#endif /* GETHOSTNAME_R_RETURNS_INT */ + if (! ok && herr == ERANGE) + { + size_r *= 2; + buffer_r = (char *) _Jv_AllocBytes (size_r); + } + else +#endif /* HAVE_STRUCT_HOSTENT_DATA */ + break; + } +#else + // FIXME: this is insufficient if some other piece of code calls + // this gethostbyname. + JvSynchronize sync (java::net::InetAddress::localhostAddress); + hptr = gethostbyname (hostname); +#endif /* HAVE_GETHOSTBYNAME_R */ + } + else + { + jbyteArray bytes = iaddr->addr; + char *chars = (char*) elements (bytes); + int len = bytes->length; + int type; + char *val; + if (len == 4) + { + val = chars; + type = iaddr->family = AF_INET; + } +#ifdef HAVE_INET6 + else if (len == 16) + { + val = (char *) &chars; + type = iaddr->family = AF_INET6; + } +#endif /* HAVE_INET6 */ + else + JvFail ("unrecognized size"); + +#ifdef HAVE_GETHOSTBYADDR_R + while (true) + { + int ok; +#if HAVE_STRUCT_HOSTENT_DATA + ok = ! gethostbyaddr_r (val, len, type, &hent_r, buffer_r); +#else + int herr = 0; +#ifdef GETHOSTBYADDR_R_RETURNS_INT + ok = ! gethostbyaddr_r (val, len, type, &hent_r, + buffer_r, size_r, &hptr, &herr); +#else + hptr = gethostbyaddr_r (val, len, type, &hent_r, + buffer_r, size_r, &herr); + ok = hptr != NULL; +#endif /* GETHOSTBYADDR_R_RETURNS_INT */ + if (! ok && herr == ERANGE) + { + size_r *= 2; + buffer_r = (char *) _Jv_AllocBytes (size_r); + } + else +#endif /* HAVE_STRUCT_HOSTENT_DATA */ + break; + } +#else /* HAVE_GETHOSTBYADDR_R */ + // FIXME: this is insufficient if some other piece of code calls + // this gethostbyaddr. + JvSynchronize sync (java::net::InetAddress::localhostAddress); + hptr = gethostbyaddr (val, len, type); +#endif /* HAVE_GETHOSTBYADDR_R */ + } + if (hptr != NULL) + { + if (!all) + host = JvNewStringUTF (hptr->h_name); + java::lang::SecurityException *ex = checkConnect (host); + if (ex != NULL) + { + if (iaddr == NULL || iaddr->addr == NULL) + throw ex; + hptr = NULL; + } + } + if (hptr == NULL) + { + if (iaddr != NULL && iaddr->addr != NULL) + { + iaddr->hostName = iaddr->getHostAddress(); + return NULL; + } + else + throw new java::net::UnknownHostException(host); + } + int count; + if (all) + { + char** ptr = hptr->h_addr_list; + count = 0; + while (*ptr++) count++; + } + else + count = 1; + JArray<java::net::InetAddress*> *result; + java::net::InetAddress** iaddrs; + if (all) + { + result = java::net::InetAddress::allocArray (count); + iaddrs = elements (result); + } + else + { + result = NULL; + iaddrs = &iaddr; + } + + for (int i = 0; i < count; i++) + { + if (iaddrs[i] == NULL) + iaddrs[i] = new java::net::InetAddress (NULL, NULL); + if (iaddrs[i]->hostName == NULL) + iaddrs[i]->hostName = host; + if (iaddrs[i]->addr == NULL) + { + char *bytes = hptr->h_addr_list[i]; + iaddrs[i]->addr = JvNewByteArray (hptr->h_length); + iaddrs[i]->family = getFamily (iaddrs[i]->addr); + memcpy (elements (iaddrs[i]->addr), bytes, hptr->h_length); + } + } + return result; +} + +jstring +java::net::InetAddress::getLocalHostname () +{ + char *chars; +#ifdef HAVE_GETHOSTNAME + char buffer[MAXHOSTNAMELEN]; + if (gethostname (buffer, MAXHOSTNAMELEN)) + return NULL; + chars = buffer; +#elif HAVE_UNAME + struct utsname stuff; + if (uname (&stuff) != 0) + return NULL; + chars = stuff.nodename; +#else + return NULL; +#endif + // It is admittedly non-optimal to convert the hostname to Unicode + // only to convert it back in getByName, but simplicity wins. Note + // that unless there is a SecurityManager, we only get called once + // anyway, thanks to the InetAddress.localhost cache. + return JvNewStringUTF (chars); +} + +#endif /* DISABLE_JAVA_NET */ diff --git a/libjava/java/net/natNetworkInterfaceNoNet.cc b/libjava/java/net/natNetworkInterfaceNoNet.cc new file mode 100644 index 00000000000..5f3c5089221 --- /dev/null +++ b/libjava/java/net/natNetworkInterfaceNoNet.cc @@ -0,0 +1,21 @@ +/* Copyright (C) 2003 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 <java/net/NetworkInterface.h> +#include <java/net/SocketException.h> +#include <java/util/Vector.h> + +::java::util::Vector* +java::net::NetworkInterface::getRealNetworkInterfaces () +{ + throw new SocketException ( + JvNewStringLatin1 ("NetworkInterface.getrealNetworkInterfaces: unimplemented")); +} diff --git a/libjava/java/net/natNetworkInterfacePosix.cc b/libjava/java/net/natNetworkInterfacePosix.cc new file mode 100644 index 00000000000..f4c5d6b4840 --- /dev/null +++ b/libjava/java/net/natNetworkInterfacePosix.cc @@ -0,0 +1,115 @@ +/* Copyright (C) 2003 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> + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#include <string.h> +#include <errno.h> +#include <stdlib.h> + +#include <sys/param.h> +#include <sys/types.h> +#ifdef HAVE_NETINET_IN_H +#include <netinet/in.h> +#endif +#ifdef HAVE_ARPA_INET_H +#include <arpa/inet.h> +#endif +#ifdef HAVE_NETDB_H +#include <netdb.h> +#endif +#ifdef HAVE_SYS_IOCTL_H +#define BSD_COMP /* Get FIONREAD on Solaris2. */ +#include <sys/ioctl.h> +#endif +#ifdef HAVE_NET_IF_H +#include <net/if.h> +#endif + +#include <gcj/cni.h> +#include <jvm.h> +#include <java/net/NetworkInterface.h> +#include <java/net/Inet4Address.h> +#include <java/net/SocketException.h> +#include <java/util/Vector.h> + +::java::util::Vector* +java::net::NetworkInterface::getRealNetworkInterfaces () +{ + int fd; + int num_interfaces = 0; + struct ifconf if_data; + struct ifreq* if_record; + ::java::util::Vector* ht = new ::java::util::Vector (); + + if_data.ifc_len = 0; + if_data.ifc_buf = NULL; + + // Open a (random) socket to have a file descriptor for the ioctl calls. + fd = _Jv_socket (PF_INET, SOCK_DGRAM, htons (IPPROTO_IP)); + + if (fd < 0) + throw new ::java::net::SocketException; + + // Get all interfaces. If not enough buffers are available try it + // with a bigger buffer size. + do + { + num_interfaces += 16; + + if_data.ifc_len = sizeof (struct ifreq) * num_interfaces; + if_data.ifc_buf = + (char*) _Jv_Realloc (if_data.ifc_buf, if_data.ifc_len); + + // Try to get all local interfaces. + if (::ioctl (fd, SIOCGIFCONF, &if_data) < 0) + throw new java::net::SocketException; + } + while (if_data.ifc_len >= (sizeof (struct ifreq) * num_interfaces)); + + // Get addresses of all interfaces. + if_record = if_data.ifc_req; + + for (int n = 0; n < if_data.ifc_len; n += sizeof (struct ifreq)) + { + struct ifreq ifr; + + memset (&ifr, 0, sizeof (ifr)); + strcpy (ifr.ifr_name, if_record->ifr_name); + + // Try to get the IPv4-address of the local interface + if (::ioctl (fd, SIOCGIFADDR, &ifr) < 0) + throw new java::net::SocketException; + + int len = 4; + struct sockaddr_in sa = *((sockaddr_in*) &(ifr.ifr_addr)); + + jbyteArray baddr = JvNewByteArray (len); + memcpy (elements (baddr), &(sa.sin_addr), len); + jstring if_name = JvNewStringLatin1 (if_record->ifr_name); + Inet4Address* address = + new java::net::Inet4Address (baddr, JvNewStringLatin1 ("")); + ht->add (new NetworkInterface (if_name, address)); + if_record++; + } + +#ifdef HAVE_INET6 + // FIXME: read /proc/net/if_inet6 (on Linux 2.4) +#endif + + _Jv_Free (if_data.ifc_buf); + + if (fd >= 0) + _Jv_close (fd); + + return ht; +} diff --git a/libjava/java/net/natNetworkInterfaceWin32.cc b/libjava/java/net/natNetworkInterfaceWin32.cc new file mode 100644 index 00000000000..47d68b5fd65 --- /dev/null +++ b/libjava/java/net/natNetworkInterfaceWin32.cc @@ -0,0 +1,142 @@ +/* Copyright (C) 2003 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> + +#ifdef WIN32 + +#include <windows.h> +#include <winsock.h> +#undef STRICT + +#else /* WIN32 */ + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#include <string.h> +#include <errno.h> +#include <stdlib.h> + +#include <sys/param.h> +#include <sys/types.h> +#ifdef HAVE_NETINET_IN_H +#include <netinet/in.h> +#endif +#ifdef HAVE_ARPA_INET_H +#include <arpa/inet.h> +#endif +#ifdef HAVE_NETDB_H +#include <netdb.h> +#endif +#ifdef HAVE_SYS_IOCTL_H +#define BSD_COMP /* Get FIONREAD on Solaris2. */ +#include <sys/ioctl.h> +#endif +#ifdef HAVE_NET_IF_H +#include <net/if.h> +#endif + +#endif /* WIN32 */ + +#include <gcj/cni.h> +#include <jvm.h> +#include <java/net/NetworkInterface.h> +#include <java/net/Inet4Address.h> +#include <java/net/SocketException.h> +#include <java/util/Vector.h> + +#ifdef DISABLE_JAVA_NET + +::java::util::Vector* +java::net::NetworkInterface::getRealNetworkInterfaces () +{ + ::java::util::Vector* ht = new ::java::util::Vector(); + return ht; +} + +#else /* DISABLE_JAVA_NET */ + +::java::util::Vector* +java::net::NetworkInterface::getRealNetworkInterfaces () +{ +#ifdef WIN32 + throw new ::java::net::SocketException; +#else + int fd; + int num_interfaces = 0; + struct ifconf if_data; + struct ifreq* if_record; + ::java::util::Vector* ht = new ::java::util::Vector (); + + if_data.ifc_len = 0; + if_data.ifc_buf = NULL; + + // Open a (random) socket to have a file descriptor for the ioctl calls. + fd = _Jv_socket (PF_INET, SOCK_DGRAM, htons (IPPROTO_IP)); + + if (fd < 0) + throw new ::java::net::SocketException; + + // Get all interfaces. If not enough buffers are available try it + // with a bigger buffer size. + do + { + num_interfaces += 16; + + if_data.ifc_len = sizeof (struct ifreq) * num_interfaces; + if_data.ifc_buf = + (char*) _Jv_Realloc (if_data.ifc_buf, if_data.ifc_len); + + // Try to get all local interfaces. + if (::ioctl (fd, SIOCGIFCONF, &if_data) < 0) + throw new java::net::SocketException; + } + while (if_data.ifc_len >= (sizeof (struct ifreq) * num_interfaces)); + + // Get addresses of all interfaces. + if_record = if_data.ifc_req; + + for (int n = 0; n < if_data.ifc_len; n += sizeof (struct ifreq)) + { + struct ifreq ifr; + + memset (&ifr, 0, sizeof (ifr)); + strcpy (ifr.ifr_name, if_record->ifr_name); + + // Try to get the IPv4-address of the local interface + if (::ioctl (fd, SIOCGIFADDR, &ifr) < 0) + throw new java::net::SocketException; + + int len = 4; + struct sockaddr_in sa = *((sockaddr_in*) &(ifr.ifr_addr)); + + jbyteArray baddr = JvNewByteArray (len); + memcpy (elements (baddr), &(sa.sin_addr), len); + jstring if_name = JvNewStringLatin1 (if_record->ifr_name); + Inet4Address* address = + new java::net::Inet4Address (baddr, JvNewStringLatin1 ("")); + ht->add (new NetworkInterface (if_name, address)); + if_record++; + } + +#ifdef HAVE_INET6 + // FIXME: read /proc/net/if_inet6 (on Linux 2.4) +#endif + + _Jv_Free (if_data.ifc_buf); + + if (fd >= 0) + _Jv_close (fd); + + return ht; +#endif /* WIN32 */ +} + +#endif // DISABLE_JAVA_NET // diff --git a/libjava/java/net/natPlainDatagramSocketImplNoNet.cc b/libjava/java/net/natPlainDatagramSocketImplNoNet.cc new file mode 100644 index 00000000000..a2a08d719c4 --- /dev/null +++ b/libjava/java/net/natPlainDatagramSocketImplNoNet.cc @@ -0,0 +1,119 @@ +/* Copyright (C) 2003 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 <java/io/IOException.h> +#include <java/lang/Object.h> +#include <java/net/BindException.h> +#include <java/net/DatagramPacket.h> +#include <java/net/InetAddress.h> +#include <java/net/NetworkInterface.h> +#include <java/net/PlainDatagramSocketImpl.h> +#include <java/net/SocketException.h> + +void +java::net::PlainDatagramSocketImpl::create () +{ + throw new SocketException ( + JvNewStringLatin1 ("DatagramSocketImpl.create: unimplemented")); +} + +void +java::net::PlainDatagramSocketImpl::bind (jint, java::net::InetAddress *) +{ + throw new BindException ( + JvNewStringLatin1 ("DatagramSocketImpl.bind: unimplemented")); +} + +void +java::net::PlainDatagramSocketImpl::connect (java::net::InetAddress *, jint) +{ + throw new SocketException ( + JvNewStringLatin1 ("DatagramSocketImpl.connect: unimplemented")); +} + +void +java::net::PlainDatagramSocketImpl::disconnect () +{ + throw new SocketException ( + JvNewStringLatin1 ("DatagramSocketImpl.disconnect: unimplemented")); +} + +jint +java::net::PlainDatagramSocketImpl::peek (java::net::InetAddress *) +{ + throw new java::io::IOException ( + JvNewStringLatin1 ("DatagramSocketImpl.peek: unimplemented")); +} + +jint +java::net::PlainDatagramSocketImpl::peekData(java::net::DatagramPacket *) +{ + throw new java::io::IOException ( + JvNewStringLatin1 ("DatagramSocketImpl.peekData: unimplemented")); +} + +void +java::net::PlainDatagramSocketImpl::close () +{ + throw new java::io::IOException ( + JvNewStringLatin1 ("DatagramSocketImpl.close: unimplemented")); +} + +void +java::net::PlainDatagramSocketImpl::send (java::net::DatagramPacket *) +{ + throw new java::io::IOException ( + JvNewStringLatin1 ("DatagramSocketImpl.send: unimplemented")); +} + +void +java::net::PlainDatagramSocketImpl::receive (java::net::DatagramPacket *) +{ + throw new java::io::IOException ( + JvNewStringLatin1 ("DatagramSocketImpl.receive: unimplemented")); +} + +void +java::net::PlainDatagramSocketImpl::setTimeToLive (jint) +{ + throw new java::io::IOException ( + JvNewStringLatin1 ("DatagramSocketImpl.setTimeToLive: unimplemented")); +} + +jint +java::net::PlainDatagramSocketImpl::getTimeToLive () +{ + throw new java::io::IOException ( + JvNewStringLatin1 ("DatagramSocketImpl.getTimeToLive: unimplemented")); +} + +void +java::net::PlainDatagramSocketImpl::mcastGrp (java::net::InetAddress *, + java::net::NetworkInterface *, + jboolean) +{ + throw new java::io::IOException ( + JvNewStringLatin1 ("DatagramSocketImpl.mcastGrp: unimplemented")); +} + +void +java::net::PlainDatagramSocketImpl::setOption (jint, java::lang::Object *) +{ + throw new SocketException ( + JvNewStringLatin1 ("DatagramSocketImpl.setOption: unimplemented")); +} + +java::lang::Object * +java::net::PlainDatagramSocketImpl::getOption (jint) +{ + throw new SocketException ( + JvNewStringLatin1 ("DatagramSocketImpl.getOption: unimplemented")); +} diff --git a/libjava/java/net/natPlainDatagramSocketImplPosix.cc b/libjava/java/net/natPlainDatagramSocketImplPosix.cc new file mode 100644 index 00000000000..14f6fee2df0 --- /dev/null +++ b/libjava/java/net/natPlainDatagramSocketImplPosix.cc @@ -0,0 +1,750 @@ +/* Copyright (C) 2003 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> + +#ifdef HAVE_NETINET_IN_H +#include <netinet/in.h> +#endif +#ifdef HAVE_ARPA_INET_H +#include <arpa/inet.h> +#endif +#include <errno.h> +#include <string.h> + +#if HAVE_BSTRING_H +// Needed for bzero, implicitly used by FD_ZERO on IRIX 5.2 +#include <bstring.h> +#endif + +#include <gcj/cni.h> +#include <java/io/IOException.h> +#include <java/io/InterruptedIOException.h> +#include <java/net/BindException.h> +#include <java/net/SocketException.h> +#include <java/net/PlainDatagramSocketImpl.h> +#include <java/net/InetAddress.h> +#include <java/net/NetworkInterface.h> +#include <java/net/DatagramPacket.h> +#include <java/net/PortUnreachableException.h> +#include <java/lang/InternalError.h> +#include <java/lang/Object.h> +#include <java/lang/Boolean.h> +#include <java/lang/Integer.h> + +union SockAddr +{ + struct sockaddr_in address; +#ifdef HAVE_INET6 + struct sockaddr_in6 address6; +#endif +}; + +union McastReq +{ +#if HAVE_STRUCT_IP_MREQ + struct ip_mreq mreq; +#endif +#if HAVE_STRUCT_IPV6_MREQ + struct ipv6_mreq mreq6; +#endif +}; + +union InAddr +{ + struct in_addr addr; +#ifdef HAVE_INET6 + struct in6_addr addr6; +#endif +}; + + +// FIXME: routines here and/or in natPlainSocketImpl.cc could throw +// NoRouteToHostException; also consider UnknownHostException, ConnectException. + +void +java::net::PlainDatagramSocketImpl::create () +{ + int sock = _Jv_socket (AF_INET, SOCK_DGRAM, 0); + + if (sock < 0) + { + char* strerr = strerror (errno); + throw new java::net::SocketException (JvNewStringUTF (strerr)); + } + + _Jv_platform_close_on_exec (sock); + + // We use fnum in place of fd here. From leaving fd null we avoid + // the double close problem in FileDescriptor.finalize. + fnum = sock; +} + +void +java::net::PlainDatagramSocketImpl::bind (jint lport, + java::net::InetAddress *host) +{ + union SockAddr u; + struct sockaddr *ptr = (struct sockaddr *) &u.address; + // FIXME: Use getaddrinfo() to get actual protocol instead of assuming ipv4. + jbyteArray haddress = host->addr; + jbyte *bytes = elements (haddress); + int len = haddress->length; + + if (len == 4) + { + u.address.sin_family = AF_INET; + + if (host != NULL) + memcpy (&u.address.sin_addr, bytes, len); + else + u.address.sin_addr.s_addr = htonl (INADDR_ANY); + + len = sizeof (struct sockaddr_in); + u.address.sin_port = htons (lport); + } +#ifdef HAVE_INET6 + else if (len == 16) + { + u.address6.sin6_family = AF_INET6; + memcpy (&u.address6.sin6_addr, bytes, len); + len = sizeof (struct sockaddr_in6); + u.address6.sin6_port = htons (lport); + } +#endif + else + throw new java::net::SocketException (JvNewStringUTF ("invalid length")); + + if (_Jv_bind (fnum, ptr, len) == 0) + { + socklen_t addrlen = sizeof(u); + + if (lport != 0) + localPort = lport; + else if (::getsockname (fnum, (sockaddr*) &u, &addrlen) == 0) + localPort = ntohs (u.address.sin_port); + else + goto error; + + /* Allow broadcast by default. */ + int broadcast = 1; + if (::setsockopt (fnum, SOL_SOCKET, SO_BROADCAST, (char *) &broadcast, + sizeof (broadcast)) != 0) + goto error; + + return; + } + + error: + char* strerr = strerror (errno); + throw new java::net::BindException (JvNewStringUTF (strerr)); +} + +void +java::net::PlainDatagramSocketImpl::connect (java::net::InetAddress *, jint) +{ + throw new ::java::lang::InternalError (JvNewStringLatin1 ( + "PlainDatagramSocketImpl::connect: not implemented yet")); +} + +void +java::net::PlainDatagramSocketImpl::disconnect () +{ + throw new ::java::lang::InternalError (JvNewStringLatin1 ( + "PlainDatagramSocketImpl::disconnect: not implemented yet")); +} + +jint +java::net::PlainDatagramSocketImpl::peek (java::net::InetAddress *i) +{ + // FIXME: Deal with Multicast and if the socket is connected. + union SockAddr u; + socklen_t addrlen = sizeof(u); + ssize_t retlen = + ::recvfrom (fnum, (char *) NULL, 0, MSG_PEEK, (sockaddr*) &u, + &addrlen); + if (retlen < 0) + goto error; + // FIXME: Deal with Multicast addressing and if the socket is connected. + jbyteArray raddr; + jint rport; + if (u.address.sin_family == AF_INET) + { + raddr = JvNewByteArray (4); + memcpy (elements (raddr), &u.address.sin_addr, 4); + rport = ntohs (u.address.sin_port); + } +#ifdef HAVE_INET6 + else if (u.address.sin_family == AF_INET6) + { + raddr = JvNewByteArray (16); + memcpy (elements (raddr), &u.address6.sin6_addr, 16); + rport = ntohs (u.address6.sin6_port); + } +#endif + else + throw new java::net::SocketException (JvNewStringUTF ("invalid family")); + + i->addr = raddr; + return rport; + error: + char* strerr = strerror (errno); + + if (errno == ECONNREFUSED) + throw new PortUnreachableException (JvNewStringUTF (strerr)); + + throw new java::io::IOException (JvNewStringUTF (strerr)); +} + +jint +java::net::PlainDatagramSocketImpl::peekData(java::net::DatagramPacket *p) +{ + // FIXME: Deal with Multicast and if the socket is connected. + union SockAddr u; + socklen_t addrlen = sizeof(u); + jbyte *dbytes = elements (p->getData()); + ssize_t retlen = 0; + + // Do timeouts via select since SO_RCVTIMEO is not always available. + if (timeout > 0 && fnum >= 0 && fnum < FD_SETSIZE) + { + fd_set rset; + struct timeval tv; + FD_ZERO(&rset); + FD_SET(fnum, &rset); + tv.tv_sec = timeout / 1000; + tv.tv_usec = (timeout % 1000) * 1000; + int retval; + if ((retval = _Jv_select (fnum + 1, &rset, NULL, NULL, &tv)) < 0) + goto error; + else if (retval == 0) + throw new java::io::InterruptedIOException (); + } + + retlen = + ::recvfrom (fnum, (char *) dbytes, p->getLength(), MSG_PEEK, (sockaddr*) &u, + &addrlen); + if (retlen < 0) + goto error; + // FIXME: Deal with Multicast addressing and if the socket is connected. + jbyteArray raddr; + jint rport; + if (u.address.sin_family == AF_INET) + { + raddr = JvNewByteArray (4); + memcpy (elements (raddr), &u.address.sin_addr, 4); + rport = ntohs (u.address.sin_port); + } +#ifdef HAVE_INET6 + else if (u.address.sin_family == AF_INET6) + { + raddr = JvNewByteArray (16); + memcpy (elements (raddr), &u.address6.sin6_addr, 16); + rport = ntohs (u.address6.sin6_port); + } +#endif + else + throw new java::net::SocketException (JvNewStringUTF ("invalid family")); + + p->setAddress (new InetAddress (raddr, NULL)); + p->setPort (rport); + p->setLength ((jint) retlen); + return rport; + + error: + char* strerr = strerror (errno); + + if (errno == ECONNREFUSED) + throw new PortUnreachableException (JvNewStringUTF (strerr)); + + throw new java::io::IOException (JvNewStringUTF (strerr)); +} + +// Close(shutdown) the socket. +void +java::net::PlainDatagramSocketImpl::close () +{ + // Avoid races from asynchronous finalization. + JvSynchronize sync (this); + + // The method isn't declared to throw anything, so we disregard + // the return value. + _Jv_close (fnum); + fnum = -1; + timeout = 0; +} + +void +java::net::PlainDatagramSocketImpl::send (java::net::DatagramPacket *p) +{ + // FIXME: Deal with Multicast and if the socket is connected. + jint rport = p->getPort(); + union SockAddr u; + jbyteArray haddress = p->getAddress()->addr; + jbyte *bytes = elements (haddress); + int len = haddress->length; + struct sockaddr *ptr = (struct sockaddr *) &u.address; + jbyte *dbytes = elements (p->getData()); + if (len == 4) + { + u.address.sin_family = AF_INET; + memcpy (&u.address.sin_addr, bytes, len); + len = sizeof (struct sockaddr_in); + u.address.sin_port = htons (rport); + } +#ifdef HAVE_INET6 + else if (len == 16) + { + u.address6.sin6_family = AF_INET6; + memcpy (&u.address6.sin6_addr, bytes, len); + len = sizeof (struct sockaddr_in6); + u.address6.sin6_port = htons (rport); + } +#endif + else + throw new java::net::SocketException (JvNewStringUTF ("invalid length")); + + if (::sendto (fnum, (char *) dbytes, p->getLength(), 0, ptr, len) >= 0) + return; + + char* strerr = strerror (errno); + + if (errno == ECONNREFUSED) + throw new PortUnreachableException (JvNewStringUTF (strerr)); + + throw new java::io::IOException (JvNewStringUTF (strerr)); +} + +void +java::net::PlainDatagramSocketImpl::receive (java::net::DatagramPacket *p) +{ + // FIXME: Deal with Multicast and if the socket is connected. + union SockAddr u; + socklen_t addrlen = sizeof(u); + jbyte *dbytes = elements (p->getData()); + ssize_t retlen = 0; + + // Do timeouts via select since SO_RCVTIMEO is not always available. + if (timeout > 0 && fnum >= 0 && fnum < FD_SETSIZE) + { + fd_set rset; + struct timeval tv; + FD_ZERO(&rset); + FD_SET(fnum, &rset); + tv.tv_sec = timeout / 1000; + tv.tv_usec = (timeout % 1000) * 1000; + int retval; + if ((retval = _Jv_select (fnum + 1, &rset, NULL, NULL, &tv)) < 0) + goto error; + else if (retval == 0) + throw new java::io::InterruptedIOException (); + } + + retlen = + ::recvfrom (fnum, (char *) dbytes, p->getLength(), 0, (sockaddr*) &u, + &addrlen); + if (retlen < 0) + goto error; + // FIXME: Deal with Multicast addressing and if the socket is connected. + jbyteArray raddr; + jint rport; + if (u.address.sin_family == AF_INET) + { + raddr = JvNewByteArray (4); + memcpy (elements (raddr), &u.address.sin_addr, 4); + rport = ntohs (u.address.sin_port); + } +#ifdef HAVE_INET6 + else if (u.address.sin_family == AF_INET6) + { + raddr = JvNewByteArray (16); + memcpy (elements (raddr), &u.address6.sin6_addr, 16); + rport = ntohs (u.address6.sin6_port); + } +#endif + else + throw new java::net::SocketException (JvNewStringUTF ("invalid family")); + + p->setAddress (new InetAddress (raddr, NULL)); + p->setPort (rport); + p->setLength ((jint) retlen); + return; + + error: + char* strerr = strerror (errno); + + if (errno == ECONNREFUSED) + throw new PortUnreachableException (JvNewStringUTF (strerr)); + + throw new java::io::IOException (JvNewStringUTF (strerr)); +} + +void +java::net::PlainDatagramSocketImpl::setTimeToLive (jint ttl) +{ + // Assumes IPPROTO_IP rather than IPPROTO_IPV6 since socket created is IPv4. + char val = (char) ttl; + socklen_t val_len = sizeof(val); + + if (::setsockopt (fnum, IPPROTO_IP, IP_MULTICAST_TTL, &val, val_len) == 0) + return; + + char* strerr = strerror (errno); + throw new java::io::IOException (JvNewStringUTF (strerr)); +} + +jint +java::net::PlainDatagramSocketImpl::getTimeToLive () +{ + // Assumes IPPROTO_IP rather than IPPROTO_IPV6 since socket created is IPv4. + char val; + socklen_t val_len = sizeof(val); + + if (::getsockopt (fnum, IPPROTO_IP, IP_MULTICAST_TTL, &val, &val_len) == 0) + return ((int) val) & 0xFF; + + char* strerr = strerror (errno); + throw new java::io::IOException (JvNewStringUTF (strerr)); +} + +void +java::net::PlainDatagramSocketImpl::mcastGrp (java::net::InetAddress *inetaddr, + java::net::NetworkInterface *, + jboolean join) +{ + // FIXME: implement use of NetworkInterface + + union McastReq u; + jbyteArray haddress = inetaddr->addr; + jbyte *bytes = elements (haddress); + int len = haddress->length; + int level, opname; + const char *ptr; + if (0) + ; +#if HAVE_STRUCT_IP_MREQ + else if (len == 4) + { + level = IPPROTO_IP; + opname = join ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP; + memcpy (&u.mreq.imr_multiaddr, bytes, len); + // FIXME: If a non-default interface is set, use it; see Stevens p. 501. + // Maybe not, see note in last paragraph at bottom of Stevens p. 497. + u.mreq.imr_interface.s_addr = htonl (INADDR_ANY); + len = sizeof (struct ip_mreq); + ptr = (const char *) &u.mreq; + } +#endif +#if HAVE_STRUCT_IPV6_MREQ + else if (len == 16) + { + level = IPPROTO_IPV6; + + /* Prefer new RFC 2553 names. */ +#ifndef IPV6_JOIN_GROUP +#define IPV6_JOIN_GROUP IPV6_ADD_MEMBERSHIP +#endif +#ifndef IPV6_LEAVE_GROUP +#define IPV6_LEAVE_GROUP IPV6_DROP_MEMBERSHIP +#endif + + opname = join ? IPV6_JOIN_GROUP : IPV6_LEAVE_GROUP; + memcpy (&u.mreq6.ipv6mr_multiaddr, bytes, len); + // FIXME: If a non-default interface is set, use it; see Stevens p. 501. + // Maybe not, see note in last paragraph at bottom of Stevens p. 497. + u.mreq6.ipv6mr_interface = 0; + len = sizeof (struct ipv6_mreq); + ptr = (const char *) &u.mreq6; + } +#endif + else + throw new java::net::SocketException (JvNewStringUTF ("invalid length")); + + if (::setsockopt (fnum, level, opname, ptr, len) == 0) + return; + + char* strerr = strerror (errno); + throw new java::io::IOException (JvNewStringUTF (strerr)); +} + +void +java::net::PlainDatagramSocketImpl::setOption (jint optID, + java::lang::Object *value) +{ + int val; + socklen_t val_len = sizeof (val); + + if (fnum < 0) + throw new java::net::SocketException (JvNewStringUTF ("Socket closed")); + + if (_Jv_IsInstanceOf (value, &java::lang::Boolean::class$)) + { + java::lang::Boolean *boolobj = + static_cast<java::lang::Boolean *> (value); + val = boolobj->booleanValue() ? 1 : 0; + } + else if (_Jv_IsInstanceOf (value, &java::lang::Integer::class$)) + { + java::lang::Integer *intobj = + static_cast<java::lang::Integer *> (value); + val = (int) intobj->intValue(); + } + // Else assume value to be an InetAddress for use with IP_MULTICAST_IF. + + switch (optID) + { + case _Jv_TCP_NODELAY_ : + throw new java::net::SocketException ( + JvNewStringUTF ("TCP_NODELAY not valid for UDP")); + return; + case _Jv_SO_LINGER_ : + throw new java::net::SocketException ( + JvNewStringUTF ("SO_LINGER not valid for UDP")); + return; + case _Jv_SO_KEEPALIVE_ : + throw new java::net::SocketException ( + JvNewStringUTF ("SO_KEEPALIVE not valid for UDP")); + return; + + case _Jv_SO_BROADCAST_ : + if (::setsockopt (fnum, SOL_SOCKET, SO_BROADCAST, (char *) &val, + val_len) != 0) + goto error; + break; + + case _Jv_SO_OOBINLINE_ : + throw new java::net::SocketException ( + JvNewStringUTF ("SO_OOBINLINE: not valid for UDP")); + break; + + case _Jv_SO_SNDBUF_ : + case _Jv_SO_RCVBUF_ : +#if defined(SO_SNDBUF) && defined(SO_RCVBUF) + int opt; + optID == _Jv_SO_SNDBUF_ ? opt = SO_SNDBUF : opt = SO_RCVBUF; + if (::setsockopt (fnum, SOL_SOCKET, opt, (char *) &val, val_len) != 0) + goto error; +#else + throw new java::lang::InternalError ( + JvNewStringUTF ("SO_RCVBUF/SO_SNDBUF not supported")); +#endif + return; + case _Jv_SO_REUSEADDR_ : +#if defined(SO_REUSEADDR) + if (::setsockopt (fnum, SOL_SOCKET, SO_REUSEADDR, (char *) &val, + val_len) != 0) + goto error; +#else + throw new java::lang::InternalError ( + JvNewStringUTF ("SO_REUSEADDR not supported")); +#endif + return; + case _Jv_SO_BINDADDR_ : + throw new java::net::SocketException ( + JvNewStringUTF ("SO_BINDADDR: read only option")); + return; + case _Jv_IP_MULTICAST_IF_ : + union InAddr u; + jbyteArray haddress; + jbyte *bytes; + int len; + int level, opname; + const char *ptr; + + haddress = ((java::net::InetAddress *) value)->addr; + bytes = elements (haddress); + len = haddress->length; + if (len == 4) + { + level = IPPROTO_IP; + opname = IP_MULTICAST_IF; + memcpy (&u.addr, bytes, len); + len = sizeof (struct in_addr); + ptr = (const char *) &u.addr; + } +// Tru64 UNIX V5.0 has struct sockaddr_in6, but no IPV6_MULTICAST_IF +#if defined (HAVE_INET6) && defined (IPV6_MULTICAST_IF) + else if (len == 16) + { + level = IPPROTO_IPV6; + opname = IPV6_MULTICAST_IF; + memcpy (&u.addr6, bytes, len); + len = sizeof (struct in6_addr); + ptr = (const char *) &u.addr6; + } +#endif + else + throw + new java::net::SocketException (JvNewStringUTF ("invalid length")); + + if (::setsockopt (fnum, level, opname, ptr, len) != 0) + goto error; + return; + + case _Jv_IP_MULTICAST_IF2_ : + throw new java::net::SocketException ( + JvNewStringUTF ("IP_MULTICAST_IF2: not yet implemented")); + break; + + case _Jv_IP_MULTICAST_LOOP_ : + throw new java::net::SocketException ( + JvNewStringUTF ("IP_MULTICAST_LOOP: not yet implemented")); + break; + + case _Jv_IP_TOS_ : + if (::setsockopt (fnum, SOL_SOCKET, IP_TOS, (char *) &val, + val_len) != 0) + goto error; + return; + + case _Jv_SO_TIMEOUT_ : + timeout = val; + return; + default : + errno = ENOPROTOOPT; + } + + error: + char* strerr = strerror (errno); + throw new java::net::SocketException (JvNewStringUTF (strerr)); +} + +java::lang::Object * +java::net::PlainDatagramSocketImpl::getOption (jint optID) +{ + int val; + socklen_t val_len = sizeof(val); + union SockAddr u; + socklen_t addrlen = sizeof(u); + + switch (optID) + { + case _Jv_TCP_NODELAY_ : + throw new java::net::SocketException ( + JvNewStringUTF ("TCP_NODELAY not valid for UDP")); + break; + case _Jv_SO_LINGER_ : + throw new java::net::SocketException ( + JvNewStringUTF ("SO_LINGER not valid for UDP")); + break; + case _Jv_SO_KEEPALIVE_ : + throw new java::net::SocketException ( + JvNewStringUTF ("SO_KEEPALIVE not valid for UDP")); + break; + + case _Jv_SO_BROADCAST_ : + if (::getsockopt (fnum, SOL_SOCKET, SO_BROADCAST, (char *) &val, + &val_len) != 0) + goto error; + return new java::lang::Boolean (val != 0); + + case _Jv_SO_OOBINLINE_ : + throw new java::net::SocketException ( + JvNewStringUTF ("SO_OOBINLINE not valid for UDP")); + break; + + case _Jv_SO_RCVBUF_ : + case _Jv_SO_SNDBUF_ : +#if defined(SO_SNDBUF) && defined(SO_RCVBUF) + int opt; + optID == _Jv_SO_SNDBUF_ ? opt = SO_SNDBUF : opt = SO_RCVBUF; + if (::getsockopt (fnum, SOL_SOCKET, opt, (char *) &val, &val_len) != 0) + goto error; + else + return new java::lang::Integer (val); +#else + throw new java::lang::InternalError ( + JvNewStringUTF ("SO_RCVBUF/SO_SNDBUF not supported")); +#endif + break; + case _Jv_SO_BINDADDR_: + // cache the local address + if (localAddress == NULL) + { + jbyteArray laddr; + if (::getsockname (fnum, (sockaddr*) &u, &addrlen) != 0) + goto error; + if (u.address.sin_family == AF_INET) + { + laddr = JvNewByteArray (4); + memcpy (elements (laddr), &u.address.sin_addr, 4); + } +#ifdef HAVE_INET6 + else if (u.address.sin_family == AF_INET6) + { + laddr = JvNewByteArray (16); + memcpy (elements (laddr), &u.address6.sin6_addr, 16); + } +#endif + else + throw new java::net::SocketException ( + JvNewStringUTF ("invalid family")); + localAddress = new java::net::InetAddress (laddr, NULL); + } + return localAddress; + break; + case _Jv_SO_REUSEADDR_ : +#if defined(SO_REUSEADDR) + if (::getsockopt (fnum, SOL_SOCKET, SO_REUSEADDR, (char *) &val, + &val_len) != 0) + goto error; + return new java::lang::Boolean (val != 0); +#else + throw new java::lang::InternalError ( + JvNewStringUTF ("SO_REUSEADDR not supported")); +#endif + break; + case _Jv_IP_MULTICAST_IF_ : +#ifdef HAVE_INET_NTOA + struct in_addr inaddr; + socklen_t inaddr_len; + char *bytes; + + inaddr_len = sizeof(inaddr); + if (::getsockopt (fnum, IPPROTO_IP, IP_MULTICAST_IF, (char *) &inaddr, + &inaddr_len) != 0) + goto error; + + bytes = inet_ntoa (inaddr); + + return java::net::InetAddress::getByName (JvNewStringLatin1 (bytes)); +#else + throw new java::net::SocketException ( + JvNewStringUTF ("IP_MULTICAST_IF: not available - no inet_ntoa()")); +#endif + break; + case _Jv_SO_TIMEOUT_ : + return new java::lang::Integer (timeout); + break; + + case _Jv_IP_MULTICAST_IF2_ : + throw new java::net::SocketException ( + JvNewStringUTF ("IP_MULTICAST_IF2: not yet implemented")); + break; + + case _Jv_IP_MULTICAST_LOOP_ : + if (::getsockopt (fnum, SOL_SOCKET, IP_MULTICAST_LOOP, (char *) &val, + &val_len) != 0) + goto error; + return new java::lang::Boolean (val != 0); + + case _Jv_IP_TOS_ : + if (::getsockopt (fnum, SOL_SOCKET, IP_TOS, (char *) &val, + &val_len) != 0) + goto error; + return new java::lang::Integer (val); + + default : + errno = ENOPROTOOPT; + } + + error: + char* strerr = strerror (errno); + throw new java::net::SocketException (JvNewStringUTF (strerr)); +} diff --git a/libjava/java/net/natPlainDatagramSocketImplWin32.cc b/libjava/java/net/natPlainDatagramSocketImplWin32.cc new file mode 100644 index 00000000000..d0d006d4b43 --- /dev/null +++ b/libjava/java/net/natPlainDatagramSocketImplWin32.cc @@ -0,0 +1,872 @@ +/* Copyright (C) 2003 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> + +#ifdef WIN32 + +#include <errno.h> +#include <string.h> + +#else /* WIN32 */ + +#ifdef HAVE_NETINET_IN_H +#include <netinet/in.h> +#endif +#ifdef HAVE_ARPA_INET_H +#include <arpa/inet.h> +#endif +#include <errno.h> +#include <string.h> + +#endif /* WIN32 */ + +#if HAVE_BSTRING_H +// Needed for bzero, implicitly used by FD_ZERO on IRIX 5.2 +#include <bstring.h> +#endif + +#include <gcj/cni.h> +#include <java/io/IOException.h> +#include <java/io/InterruptedIOException.h> +#include <java/net/BindException.h> +#include <java/net/SocketException.h> +#include <java/net/PlainDatagramSocketImpl.h> +#include <java/net/InetAddress.h> +#include <java/net/NetworkInterface.h> +#include <java/net/DatagramPacket.h> +#include <java/net/PortUnreachableException.h> +#include <java/lang/InternalError.h> +#include <java/lang/Object.h> +#include <java/lang/Boolean.h> +#include <java/lang/Integer.h> + +#ifdef DISABLE_JAVA_NET + +void +java::net::PlainDatagramSocketImpl::create () +{ + throw new SocketException ( + JvNewStringLatin1 ("DatagramSocketImpl.create: unimplemented")); +} + +void +java::net::PlainDatagramSocketImpl::bind (jint, java::net::InetAddress *) +{ + throw new BindException ( + JvNewStringLatin1 ("DatagramSocketImpl.bind: unimplemented")); +} + +void +java::net::PlainDatagramSocketImpl::connect (java::net::InetAddress *, jint) +{ + throw new SocketException ( + JvNewStringLatin1 ("DatagramSocketImpl.connect: unimplemented")); +} + +void +java::net::PlainDatagramSocketImpl::disconnect () +{ + throw new SocketException ( + JvNewStringLatin1 ("DatagramSocketImpl.disconnect: unimplemented")); +} + +jint +java::net::PlainDatagramSocketImpl::peek (java::net::InetAddress *) +{ + throw new java::io::IOException ( + JvNewStringLatin1 ("DatagramSocketImpl.peek: unimplemented")); +} + +jint +java::net::PlainDatagramSocketImpl::peekData(java::net::DatagramPacket *) +{ + throw new java::io::IOException ( + JvNewStringLatin1 ("DatagramSocketImpl.peekData: unimplemented")); +} + +void +java::net::PlainDatagramSocketImpl::close () +{ + throw new java::io::IOException ( + JvNewStringLatin1 ("DatagramSocketImpl.close: unimplemented")); +} + +void +java::net::PlainDatagramSocketImpl::send (java::net::DatagramPacket *) +{ + throw new java::io::IOException ( + JvNewStringLatin1 ("DatagramSocketImpl.send: unimplemented")); +} + +void +java::net::PlainDatagramSocketImpl::receive (java::net::DatagramPacket *) +{ + throw new java::io::IOException ( + JvNewStringLatin1 ("DatagramSocketImpl.receive: unimplemented")); +} + +void +java::net::PlainDatagramSocketImpl::setTimeToLive (jint) +{ + throw new java::io::IOException ( + JvNewStringLatin1 ("DatagramSocketImpl.setTimeToLive: unimplemented")); +} + +jint +java::net::PlainDatagramSocketImpl::getTimeToLive () +{ + throw new java::io::IOException ( + JvNewStringLatin1 ("DatagramSocketImpl.getTimeToLive: unimplemented")); +} + +void +java::net::PlainDatagramSocketImpl::mcastGrp (java::net::InetAddress *, + java::net::NetworkInterface *, + jboolean) +{ + throw new java::io::IOException ( + JvNewStringLatin1 ("DatagramSocketImpl.mcastGrp: unimplemented")); +} + +void +java::net::PlainDatagramSocketImpl::setOption (jint, java::lang::Object *) +{ + throw new SocketException ( + JvNewStringLatin1 ("DatagramSocketImpl.setOption: unimplemented")); +} + +java::lang::Object * +java::net::PlainDatagramSocketImpl::getOption (jint) +{ + throw new SocketException ( + JvNewStringLatin1 ("DatagramSocketImpl.getOption: unimplemented")); +} + +#else /* DISABLE_JAVA_NET */ + + +union SockAddr +{ + struct sockaddr_in address; +#ifdef HAVE_INET6 + struct sockaddr_in6 address6; +#endif +}; + +union McastReq +{ +#if HAVE_STRUCT_IP_MREQ + struct ip_mreq mreq; +#endif +#if HAVE_STRUCT_IPV6_MREQ + struct ipv6_mreq mreq6; +#endif +}; + +union InAddr +{ + struct in_addr addr; +#ifdef HAVE_INET6 + struct in6_addr addr6; +#endif +}; + + +// FIXME: routines here and/or in natPlainSocketImpl.cc could throw +// NoRouteToHostException; also consider UnknownHostException, ConnectException. + +void +java::net::PlainDatagramSocketImpl::create () +{ + int sock = _Jv_socket (AF_INET, SOCK_DGRAM, 0); + + if (sock < 0) + { + char* strerr = strerror (errno); + throw new java::net::SocketException (JvNewStringUTF (strerr)); + } + + _Jv_platform_close_on_exec (sock); + + // We use fnum in place of fd here. From leaving fd null we avoid + // the double close problem in FileDescriptor.finalize. + fnum = sock; +} + +void +java::net::PlainDatagramSocketImpl::bind (jint lport, + java::net::InetAddress *host) +{ + union SockAddr u; + struct sockaddr *ptr = (struct sockaddr *) &u.address; + // FIXME: Use getaddrinfo() to get actual protocol instead of assuming ipv4. + jbyteArray haddress = host->addr; + jbyte *bytes = elements (haddress); + int len = haddress->length; + + if (len == 4) + { + u.address.sin_family = AF_INET; + + if (host != NULL) + memcpy (&u.address.sin_addr, bytes, len); + else + u.address.sin_addr.s_addr = htonl (INADDR_ANY); + + len = sizeof (struct sockaddr_in); + u.address.sin_port = htons (lport); + } +#ifdef HAVE_INET6 + else if (len == 16) + { + u.address6.sin6_family = AF_INET6; + memcpy (&u.address6.sin6_addr, bytes, len); + len = sizeof (struct sockaddr_in6); + u.address6.sin6_port = htons (lport); + } +#endif + else + throw new java::net::SocketException (JvNewStringUTF ("invalid length")); + + if (_Jv_bind (fnum, ptr, len) == 0) + { + socklen_t addrlen = sizeof(u); + + if (lport != 0) + localPort = lport; + else if (::getsockname (fnum, (sockaddr*) &u, &addrlen) == 0) + localPort = ntohs (u.address.sin_port); + else + goto error; + + /* Allow broadcast by default. */ + int broadcast = 1; + if (::setsockopt (fnum, SOL_SOCKET, SO_BROADCAST, (char *) &broadcast, + sizeof (broadcast)) != 0) + goto error; + + return; + } + + error: + char* strerr = strerror (errno); + throw new java::net::BindException (JvNewStringUTF (strerr)); +} + +void +java::net::PlainDatagramSocketImpl::connect (java::net::InetAddress *, jint) +{ + throw new ::java::lang::InternalError (JvNewStringLatin1 ( + "PlainDatagramSocketImpl::connect: not implemented yet")); +} + +void +java::net::PlainDatagramSocketImpl::disconnect () +{ + throw new ::java::lang::InternalError (JvNewStringLatin1 ( + "PlainDatagramSocketImpl::disconnect: not implemented yet")); +} + +jint +java::net::PlainDatagramSocketImpl::peek (java::net::InetAddress *i) +{ + // FIXME: Deal with Multicast and if the socket is connected. + union SockAddr u; + socklen_t addrlen = sizeof(u); + ssize_t retlen = + ::recvfrom (fnum, (char *) NULL, 0, MSG_PEEK, (sockaddr*) &u, + &addrlen); + if (retlen < 0) + goto error; + // FIXME: Deal with Multicast addressing and if the socket is connected. + jbyteArray raddr; + jint rport; + if (u.address.sin_family == AF_INET) + { + raddr = JvNewByteArray (4); + memcpy (elements (raddr), &u.address.sin_addr, 4); + rport = ntohs (u.address.sin_port); + } +#ifdef HAVE_INET6 + else if (u.address.sin_family == AF_INET6) + { + raddr = JvNewByteArray (16); + memcpy (elements (raddr), &u.address6.sin6_addr, 16); + rport = ntohs (u.address6.sin6_port); + } +#endif + else + throw new java::net::SocketException (JvNewStringUTF ("invalid family")); + + i->addr = raddr; + return rport; + error: + char* strerr = strerror (errno); + + if (errno == ECONNREFUSED) + throw new PortUnreachableException (JvNewStringUTF (strerr)); + + throw new java::io::IOException (JvNewStringUTF (strerr)); +} + +jint +java::net::PlainDatagramSocketImpl::peekData(java::net::DatagramPacket *p) +{ + // FIXME: Deal with Multicast and if the socket is connected. + union SockAddr u; + socklen_t addrlen = sizeof(u); + jbyte *dbytes = elements (p->getData()); + ssize_t retlen = 0; + +// FIXME: implement timeout support for Win32 +#ifndef WIN32 + // Do timeouts via select since SO_RCVTIMEO is not always available. + if (timeout > 0 && fnum >= 0 && fnum < FD_SETSIZE) + { + fd_set rset; + struct timeval tv; + FD_ZERO(&rset); + FD_SET(fnum, &rset); + tv.tv_sec = timeout / 1000; + tv.tv_usec = (timeout % 1000) * 1000; + int retval; + if ((retval = _Jv_select (fnum + 1, &rset, NULL, NULL, &tv)) < 0) + goto error; + else if (retval == 0) + throw new java::io::InterruptedIOException (); + } +#endif /* WIN32 */ + + retlen = + ::recvfrom (fnum, (char *) dbytes, p->getLength(), MSG_PEEK, (sockaddr*) &u, + &addrlen); + if (retlen < 0) + goto error; + // FIXME: Deal with Multicast addressing and if the socket is connected. + jbyteArray raddr; + jint rport; + if (u.address.sin_family == AF_INET) + { + raddr = JvNewByteArray (4); + memcpy (elements (raddr), &u.address.sin_addr, 4); + rport = ntohs (u.address.sin_port); + } +#ifdef HAVE_INET6 + else if (u.address.sin_family == AF_INET6) + { + raddr = JvNewByteArray (16); + memcpy (elements (raddr), &u.address6.sin6_addr, 16); + rport = ntohs (u.address6.sin6_port); + } +#endif + else + throw new java::net::SocketException (JvNewStringUTF ("invalid family")); + + p->setAddress (new InetAddress (raddr, NULL)); + p->setPort (rport); + p->setLength ((jint) retlen); + return rport; + + error: + char* strerr = strerror (errno); + + if (errno == ECONNREFUSED) + throw new PortUnreachableException (JvNewStringUTF (strerr)); + + throw new java::io::IOException (JvNewStringUTF (strerr)); +} + +// Close(shutdown) the socket. +void +java::net::PlainDatagramSocketImpl::close () +{ + // Avoid races from asynchronous finalization. + JvSynchronize sync (this); + + // The method isn't declared to throw anything, so we disregard + // the return value. + _Jv_close (fnum); + fnum = -1; + timeout = 0; +} + +void +java::net::PlainDatagramSocketImpl::send (java::net::DatagramPacket *p) +{ + // FIXME: Deal with Multicast and if the socket is connected. + jint rport = p->getPort(); + union SockAddr u; + jbyteArray haddress = p->getAddress()->addr; + jbyte *bytes = elements (haddress); + int len = haddress->length; + struct sockaddr *ptr = (struct sockaddr *) &u.address; + jbyte *dbytes = elements (p->getData()); + if (len == 4) + { + u.address.sin_family = AF_INET; + memcpy (&u.address.sin_addr, bytes, len); + len = sizeof (struct sockaddr_in); + u.address.sin_port = htons (rport); + } +#ifdef HAVE_INET6 + else if (len == 16) + { + u.address6.sin6_family = AF_INET6; + memcpy (&u.address6.sin6_addr, bytes, len); + len = sizeof (struct sockaddr_in6); + u.address6.sin6_port = htons (rport); + } +#endif + else + throw new java::net::SocketException (JvNewStringUTF ("invalid length")); + + if (::sendto (fnum, (char *) dbytes, p->getLength(), 0, ptr, len) >= 0) + return; + + char* strerr = strerror (errno); + + if (errno == ECONNREFUSED) + throw new PortUnreachableException (JvNewStringUTF (strerr)); + + throw new java::io::IOException (JvNewStringUTF (strerr)); +} + +void +java::net::PlainDatagramSocketImpl::receive (java::net::DatagramPacket *p) +{ + // FIXME: Deal with Multicast and if the socket is connected. + union SockAddr u; + socklen_t addrlen = sizeof(u); + jbyte *dbytes = elements (p->getData()); + ssize_t retlen = 0; + +// FIXME: implement timeout support for Win32 +#ifndef WIN32 + // Do timeouts via select since SO_RCVTIMEO is not always available. + if (timeout > 0 && fnum >= 0 && fnum < FD_SETSIZE) + { + fd_set rset; + struct timeval tv; + FD_ZERO(&rset); + FD_SET(fnum, &rset); + tv.tv_sec = timeout / 1000; + tv.tv_usec = (timeout % 1000) * 1000; + int retval; + if ((retval = _Jv_select (fnum + 1, &rset, NULL, NULL, &tv)) < 0) + goto error; + else if (retval == 0) + throw new java::io::InterruptedIOException (); + } +#endif /* WIN32 */ + + retlen = + ::recvfrom (fnum, (char *) dbytes, p->getLength(), 0, (sockaddr*) &u, + &addrlen); + if (retlen < 0) + goto error; + // FIXME: Deal with Multicast addressing and if the socket is connected. + jbyteArray raddr; + jint rport; + if (u.address.sin_family == AF_INET) + { + raddr = JvNewByteArray (4); + memcpy (elements (raddr), &u.address.sin_addr, 4); + rport = ntohs (u.address.sin_port); + } +#ifdef HAVE_INET6 + else if (u.address.sin_family == AF_INET6) + { + raddr = JvNewByteArray (16); + memcpy (elements (raddr), &u.address6.sin6_addr, 16); + rport = ntohs (u.address6.sin6_port); + } +#endif + else + throw new java::net::SocketException (JvNewStringUTF ("invalid family")); + + p->setAddress (new InetAddress (raddr, NULL)); + p->setPort (rport); + p->setLength ((jint) retlen); + return; + + error: + char* strerr = strerror (errno); + + if (errno == ECONNREFUSED) + throw new PortUnreachableException (JvNewStringUTF (strerr)); + + throw new java::io::IOException (JvNewStringUTF (strerr)); +} + +void +java::net::PlainDatagramSocketImpl::setTimeToLive (jint ttl) +{ + // Assumes IPPROTO_IP rather than IPPROTO_IPV6 since socket created is IPv4. + char val = (char) ttl; + socklen_t val_len = sizeof(val); + + if (::setsockopt (fnum, IPPROTO_IP, IP_MULTICAST_TTL, &val, val_len) == 0) + return; + + char* strerr = strerror (errno); + throw new java::io::IOException (JvNewStringUTF (strerr)); +} + +jint +java::net::PlainDatagramSocketImpl::getTimeToLive () +{ + // Assumes IPPROTO_IP rather than IPPROTO_IPV6 since socket created is IPv4. + char val; + socklen_t val_len = sizeof(val); + + if (::getsockopt (fnum, IPPROTO_IP, IP_MULTICAST_TTL, &val, &val_len) == 0) + return ((int) val) & 0xFF; + + char* strerr = strerror (errno); + throw new java::io::IOException (JvNewStringUTF (strerr)); +} + +void +java::net::PlainDatagramSocketImpl::mcastGrp (java::net::InetAddress *inetaddr, + java::net::NetworkInterface *, + jboolean join) +{ + // FIXME: implement use of NetworkInterface + + union McastReq u; + jbyteArray haddress = inetaddr->addr; + jbyte *bytes = elements (haddress); + int len = haddress->length; + int level, opname; + const char *ptr; + if (0) + ; +#if HAVE_STRUCT_IP_MREQ + else if (len == 4) + { + level = IPPROTO_IP; + opname = join ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP; + memcpy (&u.mreq.imr_multiaddr, bytes, len); + // FIXME: If a non-default interface is set, use it; see Stevens p. 501. + // Maybe not, see note in last paragraph at bottom of Stevens p. 497. + u.mreq.imr_interface.s_addr = htonl (INADDR_ANY); + len = sizeof (struct ip_mreq); + ptr = (const char *) &u.mreq; + } +#endif +#if HAVE_STRUCT_IPV6_MREQ + else if (len == 16) + { + level = IPPROTO_IPV6; + + /* Prefer new RFC 2553 names. */ +#ifndef IPV6_JOIN_GROUP +#define IPV6_JOIN_GROUP IPV6_ADD_MEMBERSHIP +#endif +#ifndef IPV6_LEAVE_GROUP +#define IPV6_LEAVE_GROUP IPV6_DROP_MEMBERSHIP +#endif + + opname = join ? IPV6_JOIN_GROUP : IPV6_LEAVE_GROUP; + memcpy (&u.mreq6.ipv6mr_multiaddr, bytes, len); + // FIXME: If a non-default interface is set, use it; see Stevens p. 501. + // Maybe not, see note in last paragraph at bottom of Stevens p. 497. + u.mreq6.ipv6mr_interface = 0; + len = sizeof (struct ipv6_mreq); + ptr = (const char *) &u.mreq6; + } +#endif + else + throw new java::net::SocketException (JvNewStringUTF ("invalid length")); + + if (::setsockopt (fnum, level, opname, ptr, len) == 0) + return; + + char* strerr = strerror (errno); + throw new java::io::IOException (JvNewStringUTF (strerr)); +} + +void +java::net::PlainDatagramSocketImpl::setOption (jint optID, + java::lang::Object *value) +{ + int val; + socklen_t val_len = sizeof (val); + + if (fnum < 0) + throw new java::net::SocketException (JvNewStringUTF ("Socket closed")); + + if (_Jv_IsInstanceOf (value, &java::lang::Boolean::class$)) + { + java::lang::Boolean *boolobj = + static_cast<java::lang::Boolean *> (value); + val = boolobj->booleanValue() ? 1 : 0; + } + else if (_Jv_IsInstanceOf (value, &java::lang::Integer::class$)) + { + java::lang::Integer *intobj = + static_cast<java::lang::Integer *> (value); + val = (int) intobj->intValue(); + } + // Else assume value to be an InetAddress for use with IP_MULTICAST_IF. + + switch (optID) + { + case _Jv_TCP_NODELAY_ : + throw new java::net::SocketException ( + JvNewStringUTF ("TCP_NODELAY not valid for UDP")); + return; + case _Jv_SO_LINGER_ : + throw new java::net::SocketException ( + JvNewStringUTF ("SO_LINGER not valid for UDP")); + return; + case _Jv_SO_KEEPALIVE_ : + throw new java::net::SocketException ( + JvNewStringUTF ("SO_KEEPALIVE not valid for UDP")); + return; + + case _Jv_SO_BROADCAST_ : + if (::setsockopt (fnum, SOL_SOCKET, SO_BROADCAST, (char *) &val, + val_len) != 0) + goto error; + break; + + case _Jv_SO_OOBINLINE_ : + throw new java::net::SocketException ( + JvNewStringUTF ("SO_OOBINLINE: not valid for UDP")); + break; + + case _Jv_SO_SNDBUF_ : + case _Jv_SO_RCVBUF_ : +#if defined(SO_SNDBUF) && defined(SO_RCVBUF) + int opt; + optID == _Jv_SO_SNDBUF_ ? opt = SO_SNDBUF : opt = SO_RCVBUF; + if (::setsockopt (fnum, SOL_SOCKET, opt, (char *) &val, val_len) != 0) + goto error; +#else + throw new java::lang::InternalError ( + JvNewStringUTF ("SO_RCVBUF/SO_SNDBUF not supported")); +#endif + return; + case _Jv_SO_REUSEADDR_ : +#if defined(SO_REUSEADDR) + if (::setsockopt (fnum, SOL_SOCKET, SO_REUSEADDR, (char *) &val, + val_len) != 0) + goto error; +#else + throw new java::lang::InternalError ( + JvNewStringUTF ("SO_REUSEADDR not supported")); +#endif + return; + case _Jv_SO_BINDADDR_ : + throw new java::net::SocketException ( + JvNewStringUTF ("SO_BINDADDR: read only option")); + return; + case _Jv_IP_MULTICAST_IF_ : + union InAddr u; + jbyteArray haddress; + jbyte *bytes; + int len; + int level, opname; + const char *ptr; + + haddress = ((java::net::InetAddress *) value)->addr; + bytes = elements (haddress); + len = haddress->length; + if (len == 4) + { + level = IPPROTO_IP; + opname = IP_MULTICAST_IF; + memcpy (&u.addr, bytes, len); + len = sizeof (struct in_addr); + ptr = (const char *) &u.addr; + } +// Tru64 UNIX V5.0 has struct sockaddr_in6, but no IPV6_MULTICAST_IF +#if defined (HAVE_INET6) && defined (IPV6_MULTICAST_IF) + else if (len == 16) + { + level = IPPROTO_IPV6; + opname = IPV6_MULTICAST_IF; + memcpy (&u.addr6, bytes, len); + len = sizeof (struct in6_addr); + ptr = (const char *) &u.addr6; + } +#endif + else + throw + new java::net::SocketException (JvNewStringUTF ("invalid length")); + + if (::setsockopt (fnum, level, opname, ptr, len) != 0) + goto error; + return; + + case _Jv_IP_MULTICAST_IF2_ : + throw new java::net::SocketException ( + JvNewStringUTF ("IP_MULTICAST_IF2: not yet implemented")); + break; + + case _Jv_IP_MULTICAST_LOOP_ : + throw new java::net::SocketException ( + JvNewStringUTF ("IP_MULTICAST_LOOP: not yet implemented")); + break; + + case _Jv_IP_TOS_ : + if (::setsockopt (fnum, SOL_SOCKET, IP_TOS, (char *) &val, + val_len) != 0) + goto error; + return; + + case _Jv_SO_TIMEOUT_ : + timeout = val; + return; + default : + errno = ENOPROTOOPT; + } + + error: + char* strerr = strerror (errno); + throw new java::net::SocketException (JvNewStringUTF (strerr)); +} + +java::lang::Object * +java::net::PlainDatagramSocketImpl::getOption (jint optID) +{ + int val; + socklen_t val_len = sizeof(val); + union SockAddr u; + socklen_t addrlen = sizeof(u); + + switch (optID) + { + case _Jv_TCP_NODELAY_ : + throw new java::net::SocketException ( + JvNewStringUTF ("TCP_NODELAY not valid for UDP")); + break; + case _Jv_SO_LINGER_ : + throw new java::net::SocketException ( + JvNewStringUTF ("SO_LINGER not valid for UDP")); + break; + case _Jv_SO_KEEPALIVE_ : + throw new java::net::SocketException ( + JvNewStringUTF ("SO_KEEPALIVE not valid for UDP")); + break; + + case _Jv_SO_BROADCAST_ : + if (::getsockopt (fnum, SOL_SOCKET, SO_BROADCAST, (char *) &val, + &val_len) != 0) + goto error; + return new java::lang::Boolean (val != 0); + + case _Jv_SO_OOBINLINE_ : + throw new java::net::SocketException ( + JvNewStringUTF ("SO_OOBINLINE not valid for UDP")); + break; + + case _Jv_SO_RCVBUF_ : + case _Jv_SO_SNDBUF_ : +#if defined(SO_SNDBUF) && defined(SO_RCVBUF) + int opt; + optID == _Jv_SO_SNDBUF_ ? opt = SO_SNDBUF : opt = SO_RCVBUF; + if (::getsockopt (fnum, SOL_SOCKET, opt, (char *) &val, &val_len) != 0) + goto error; + else + return new java::lang::Integer (val); +#else + throw new java::lang::InternalError ( + JvNewStringUTF ("SO_RCVBUF/SO_SNDBUF not supported")); +#endif + break; + case _Jv_SO_BINDADDR_: + // cache the local address + if (localAddress == NULL) + { + jbyteArray laddr; + if (::getsockname (fnum, (sockaddr*) &u, &addrlen) != 0) + goto error; + if (u.address.sin_family == AF_INET) + { + laddr = JvNewByteArray (4); + memcpy (elements (laddr), &u.address.sin_addr, 4); + } +#ifdef HAVE_INET6 + else if (u.address.sin_family == AF_INET6) + { + laddr = JvNewByteArray (16); + memcpy (elements (laddr), &u.address6.sin6_addr, 16); + } +#endif + else + throw new java::net::SocketException ( + JvNewStringUTF ("invalid family")); + localAddress = new java::net::InetAddress (laddr, NULL); + } + return localAddress; + break; + case _Jv_SO_REUSEADDR_ : +#if defined(SO_REUSEADDR) + if (::getsockopt (fnum, SOL_SOCKET, SO_REUSEADDR, (char *) &val, + &val_len) != 0) + goto error; + return new java::lang::Boolean (val != 0); +#else + throw new java::lang::InternalError ( + JvNewStringUTF ("SO_REUSEADDR not supported")); +#endif + break; + case _Jv_IP_MULTICAST_IF_ : +#ifdef HAVE_INET_NTOA + struct in_addr inaddr; + socklen_t inaddr_len; + char *bytes; + + inaddr_len = sizeof(inaddr); + if (::getsockopt (fnum, IPPROTO_IP, IP_MULTICAST_IF, (char *) &inaddr, + &inaddr_len) != 0) + goto error; + + bytes = inet_ntoa (inaddr); + + return java::net::InetAddress::getByName (JvNewStringLatin1 (bytes)); +#else + throw new java::net::SocketException ( + JvNewStringUTF ("IP_MULTICAST_IF: not available - no inet_ntoa()")); +#endif + break; + case _Jv_SO_TIMEOUT_ : + return new java::lang::Integer (timeout); + break; + + case _Jv_IP_MULTICAST_IF2_ : + throw new java::net::SocketException ( + JvNewStringUTF ("IP_MULTICAST_IF2: not yet implemented")); + break; + + case _Jv_IP_MULTICAST_LOOP_ : + if (::getsockopt (fnum, SOL_SOCKET, IP_MULTICAST_LOOP, (char *) &val, + &val_len) != 0) + goto error; + return new java::lang::Boolean (val != 0); + + case _Jv_IP_TOS_ : + if (::getsockopt (fnum, SOL_SOCKET, IP_TOS, (char *) &val, + &val_len) != 0) + goto error; + return new java::lang::Integer (val); + + default : + errno = ENOPROTOOPT; + } + + error: + char* strerr = strerror (errno); + throw new java::net::SocketException (JvNewStringUTF (strerr)); +} + +#endif /* DISABLE_JAVA_NET */ diff --git a/libjava/java/net/natPlainSocketImplNoNet.cc b/libjava/java/net/natPlainSocketImplNoNet.cc new file mode 100644 index 00000000000..e65438ef1d5 --- /dev/null +++ b/libjava/java/net/natPlainSocketImplNoNet.cc @@ -0,0 +1,128 @@ +/* Copyright (C) 2003 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 <java/io/IOException.h> +#include <java/net/BindException.h> +#include <java/net/ConnectException.h> +#include <java/net/PlainSocketImpl.h> +#include <java/net/SocketException.h> + +void +java::net::PlainSocketImpl::create (jboolean) +{ + throw new java::io::IOException ( + JvNewStringLatin1 ("SocketImpl.create: unimplemented")); +} + +void +java::net::PlainSocketImpl::bind (java::net::InetAddress *, jint) +{ + throw new BindException ( + JvNewStringLatin1 ("SocketImpl.bind: unimplemented")); +} + +void +java::net::PlainSocketImpl::connect (java::net::SocketAddress *, jint) +{ + throw new ConnectException ( + JvNewStringLatin1 ("SocketImpl.connect: unimplemented")); +} + +void +java::net::PlainSocketImpl::listen (jint) +{ + throw new java::io::IOException ( + JvNewStringLatin1 ("SocketImpl.listen: unimplemented")); +} + +void +java::net::PlainSocketImpl::accept (java::net::PlainSocketImpl *) +{ + throw new java::io::IOException ( + JvNewStringLatin1 ("SocketImpl.accept: unimplemented")); +} + +void +java::net::PlainSocketImpl::setOption (jint, java::lang::Object *) +{ + throw new SocketException ( + JvNewStringLatin1 ("SocketImpl.setOption: unimplemented")); +} + +java::lang::Object * +java::net::PlainSocketImpl::getOption (jint) +{ + throw new SocketException ( + JvNewStringLatin1 ("SocketImpl.getOption: unimplemented")); +} + +jint +java::net::PlainSocketImpl::read(void) +{ + throw new SocketException ( + JvNewStringLatin1 ("SocketImpl.read: unimplemented")); +} + +jint +java::net::PlainSocketImpl::read(jbyteArray buffer, jint offset, jint count) +{ + throw new SocketException ( + JvNewStringLatin1 ("SocketImpl.read: unimplemented")); +} + +void +java::net::PlainSocketImpl::write(jint b) +{ + throw new SocketException ( + JvNewStringLatin1 ("SocketImpl.write: unimplemented")); +} + +void +java::net::PlainSocketImpl::write(jbyteArray b, jint offset, jint len) +{ + throw new SocketException ( + JvNewStringLatin1 ("SocketImpl.write: unimplemented")); +} + +void +java::net::PlainSocketImpl::sendUrgentData(jint data) +{ + throw new SocketException ( + JvNewStringLatin1 ("SocketImpl.sendUrgentData: unimplemented")); +} + +jint +java::net::PlainSocketImpl::available(void) +{ + throw new SocketException ( + JvNewStringLatin1 ("SocketImpl.available: unimplemented")); +} + +void +java::net::PlainSocketImpl::close(void) +{ + throw new SocketException ( + JvNewStringLatin1 ("SocketImpl.close: unimplemented")); +} + +void +java::net::PlainSocketImpl::shutdownInput (void) +{ + throw new SocketException ( + JvNewStringLatin1 ("SocketImpl.shutdownInput: unimplemented")); +} + +void +java::net::PlainSocketImpl::shutdownOutput (void) +{ + throw new SocketException ( + JvNewStringLatin1 ("SocketImpl.shutdownOutput: unimplemented")); +} diff --git a/libjava/java/net/natPlainSocketImplPosix.cc b/libjava/java/net/natPlainSocketImplPosix.cc new file mode 100644 index 00000000000..65feac87324 --- /dev/null +++ b/libjava/java/net/natPlainSocketImplPosix.cc @@ -0,0 +1,856 @@ +/* Copyright (C) 2003 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> + +#ifdef HAVE_SYS_IOCTL_H +#define BSD_COMP /* Get FIONREAD on Solaris2. */ +#include <sys/ioctl.h> +#endif + +// Pick up FIONREAD on Solaris 2.5. +#ifdef HAVE_SYS_FILIO_H +#include <sys/filio.h> +#endif + +#include <netinet/in.h> +#include <netinet/tcp.h> +#include <errno.h> +#include <string.h> + +#if HAVE_BSTRING_H +// Needed for bzero, implicitly used by FD_ZERO on IRIX 5.2 +#include <bstring.h> +#endif + +#include <gcj/cni.h> +#include <gcj/javaprims.h> +#include <java/io/IOException.h> +#include <java/io/InterruptedIOException.h> +#include <java/net/BindException.h> +#include <java/net/ConnectException.h> +#include <java/net/PlainSocketImpl.h> +#include <java/net/InetAddress.h> +#include <java/net/InetSocketAddress.h> +#include <java/net/SocketException.h> +#include <java/net/SocketTimeoutException.h> +#include <java/lang/InternalError.h> +#include <java/lang/Object.h> +#include <java/lang/Boolean.h> +#include <java/lang/Class.h> +#include <java/lang/Integer.h> +#include <java/lang/Thread.h> +#include <java/lang/NullPointerException.h> +#include <java/lang/ArrayIndexOutOfBoundsException.h> +#include <java/lang/IllegalArgumentException.h> + +union SockAddr +{ + struct sockaddr_in address; +#ifdef HAVE_INET6 + struct sockaddr_in6 address6; +#endif +}; + +void +java::net::PlainSocketImpl::create (jboolean stream) +{ + int sock = _Jv_socket (AF_INET, stream ? SOCK_STREAM : SOCK_DGRAM, 0); + + if (sock < 0) + { + char* strerr = strerror (errno); + throw new java::io::IOException (JvNewStringUTF (strerr)); + } + + _Jv_platform_close_on_exec (sock); + + // We use fnum in place of fd here. From leaving fd null we avoid + // the double close problem in FileDescriptor.finalize. + fnum = sock; +} + +void +java::net::PlainSocketImpl::bind (java::net::InetAddress *host, jint lport) +{ + union SockAddr u; + struct sockaddr *ptr = (struct sockaddr *) &u.address; + jbyteArray haddress = host->addr; + jbyte *bytes = elements (haddress); + int len = haddress->length; + int i = 1; + + if (len == 4) + { + u.address.sin_family = AF_INET; + + if (host != NULL) + memcpy (&u.address.sin_addr, bytes, len); + else + u.address.sin_addr.s_addr = htonl (INADDR_ANY); + + len = sizeof (struct sockaddr_in); + u.address.sin_port = htons (lport); + } +#ifdef HAVE_INET6 + else if (len == 16) + { + u.address6.sin6_family = AF_INET6; + memcpy (&u.address6.sin6_addr, bytes, len); + len = sizeof (struct sockaddr_in6); + u.address6.sin6_port = htons (lport); + } +#endif + else + throw new java::net::SocketException (JvNewStringUTF ("invalid length")); + + // Enable SO_REUSEADDR, so that servers can reuse ports left in TIME_WAIT. + ::setsockopt(fnum, SOL_SOCKET, SO_REUSEADDR, (char *) &i, sizeof(i)); + + if (_Jv_bind (fnum, ptr, len) == 0) + { + address = host; + socklen_t addrlen = sizeof(u); + + if (lport != 0) + localport = lport; + else if (::getsockname (fnum, (sockaddr*) &u, &addrlen) == 0) + localport = ntohs (u.address.sin_port); + else + goto error; + + return; + } + + error: + char* strerr = strerror (errno); + throw new java::net::BindException (JvNewStringUTF (strerr)); +} + +void +java::net::PlainSocketImpl::connect (java::net::SocketAddress *addr, + jint timeout) +{ + java::net::InetSocketAddress *tmp = (java::net::InetSocketAddress*) addr; + java::net::InetAddress *host = tmp->getAddress(); + jint rport = tmp->getPort(); + + union SockAddr u; + socklen_t addrlen = sizeof(u); + jbyteArray haddress = host->addr; + jbyte *bytes = elements (haddress); + int len = haddress->length; + struct sockaddr *ptr = (struct sockaddr *) &u.address; + if (len == 4) + { + u.address.sin_family = AF_INET; + memcpy (&u.address.sin_addr, bytes, len); + len = sizeof (struct sockaddr_in); + u.address.sin_port = htons (rport); + } +#ifdef HAVE_INET6 + else if (len == 16) + { + u.address6.sin6_family = AF_INET6; + memcpy (&u.address6.sin6_addr, bytes, len); + len = sizeof (struct sockaddr_in6); + u.address6.sin6_port = htons (rport); + } +#endif + else + throw new java::net::SocketException (JvNewStringUTF ("invalid length")); + + if (timeout > 0) + { + int flags = ::fcntl (fnum, F_GETFL); + ::fcntl (fnum, F_SETFL, flags | O_NONBLOCK); + + if ((_Jv_connect (fnum, ptr, len) != 0) && (errno != EINPROGRESS)) + goto error; + + fd_set rset; + struct timeval tv; + FD_ZERO(&rset); + FD_SET(fnum, &rset); + tv.tv_sec = timeout / 1000; + tv.tv_usec = (timeout % 1000) * 1000; + int retval; + + if ((retval = _Jv_select (fnum + 1, &rset, NULL, NULL, &tv)) < 0) + goto error; + else if (retval == 0) + throw new java::net::SocketTimeoutException + (JvNewStringUTF ("Connect timed out")); + } + else + { + if (_Jv_connect (fnum, ptr, len) != 0) + goto error; + } + + address = host; + port = rport; + + // A bind may not have been done on this socket; if so, set localport now. + if (localport == 0) + { + if (::getsockname (fnum, (sockaddr*) &u, &addrlen) == 0) + localport = ntohs (u.address.sin_port); + else + goto error; + } + + return; + + error: + char* strerr = strerror (errno); + throw new java::net::ConnectException (JvNewStringUTF (strerr)); +} + +void +java::net::PlainSocketImpl::listen (jint backlog) +{ + if (::listen (fnum, backlog) != 0) + { + char* strerr = strerror (errno); + throw new java::io::IOException (JvNewStringUTF (strerr)); + } +} + +void +java::net::PlainSocketImpl::accept (java::net::PlainSocketImpl *s) +{ + union SockAddr u; + socklen_t addrlen = sizeof(u); + int new_socket = 0; + + // Do timeouts via select since SO_RCVTIMEO is not always available. + if (timeout > 0 && fnum >= 0 && fnum < FD_SETSIZE) + { + fd_set rset; + struct timeval tv; + FD_ZERO(&rset); + FD_SET(fnum, &rset); + tv.tv_sec = timeout / 1000; + tv.tv_usec = (timeout % 1000) * 1000; + int retval; + if ((retval = _Jv_select (fnum + 1, &rset, NULL, NULL, &tv)) < 0) + goto error; + else if (retval == 0) + throw new java::io::InterruptedIOException ( + JvNewStringUTF("Accept timed out")); + } + + new_socket = _Jv_accept (fnum, (sockaddr*) &u, &addrlen); + + if (new_socket < 0) + goto error; + + _Jv_platform_close_on_exec (new_socket); + + jbyteArray raddr; + jint rport; + if (u.address.sin_family == AF_INET) + { + raddr = JvNewByteArray (4); + memcpy (elements (raddr), &u.address.sin_addr, 4); + rport = ntohs (u.address.sin_port); + } +#ifdef HAVE_INET6 + else if (u.address.sin_family == AF_INET6) + { + raddr = JvNewByteArray (16); + memcpy (elements (raddr), &u.address6.sin6_addr, 16); + rport = ntohs (u.address6.sin6_port); + } +#endif + else + throw new java::net::SocketException (JvNewStringUTF ("invalid family")); + + s->fnum = new_socket; + s->localport = localport; + s->address = new InetAddress (raddr, NULL); + s->port = rport; + return; + + error: + char* strerr = strerror (errno); + throw new java::io::IOException (JvNewStringUTF (strerr)); +} + +// Close(shutdown) the socket. +void +java::net::PlainSocketImpl::close() +{ + // Avoid races from asynchronous finalization. + JvSynchronize sync (this); + + // should we use shutdown here? how would that effect so_linger? + int res = _Jv_close (fnum); + + if (res == -1) + { + // These three errors are not errors according to tests performed + // on the reference implementation. + if (errno != ENOTCONN && errno != ECONNRESET && errno != EBADF) + throw new java::io::IOException (JvNewStringUTF (strerror (errno))); + } + // Safe place to reset the file pointer. + fnum = -1; + timeout = 0; +} + +// Write a byte to the socket. +void +java::net::PlainSocketImpl::write(jint b) +{ + jbyte d =(jbyte) b; + int r = 0; + + while (r != 1) + { + r = _Jv_write (fnum, &d, 1); + if (r == -1) + { + if (java::lang::Thread::interrupted()) + { + java::io::InterruptedIOException *iioe + = new java::io::InterruptedIOException + (JvNewStringLatin1 (strerror (errno))); + iioe->bytesTransferred = 0; + throw iioe; + } + // Some errors should not cause exceptions. + if (errno != ENOTCONN && errno != ECONNRESET && errno != EBADF) + throw new java::io::IOException (JvNewStringUTF (strerror (errno))); + break; + } + } +} + +// Write some bytes to the socket. +void +java::net::PlainSocketImpl::write(jbyteArray b, jint offset, jint len) +{ + if (! b) + throw new java::lang::NullPointerException; + if (offset < 0 || len < 0 || offset + len > JvGetArrayLength (b)) + throw new java::lang::ArrayIndexOutOfBoundsException; + + jbyte *bytes = elements (b) + offset; + int written = 0; + + while (len > 0) + { + int r = _Jv_write (fnum, bytes, len); + + if (r == -1) + { + if (java::lang::Thread::interrupted()) + { + java::io::InterruptedIOException *iioe + = new java::io::InterruptedIOException + (JvNewStringLatin1 (strerror (errno))); + iioe->bytesTransferred = written; + throw iioe; + } + // Some errors should not cause exceptions. + if (errno != ENOTCONN && errno != ECONNRESET && errno != EBADF) + throw new java::io::IOException (JvNewStringUTF (strerror (errno))); + break; + } + + written += r; + len -= r; + bytes += r; + } +} + +void +java::net::PlainSocketImpl::sendUrgentData (jint) +{ + throw new SocketException (JvNewStringLatin1 ( + "PlainSocketImpl: sending of urgent data not supported by this socket")); +} + +// Read a single byte from the socket. +jint +java::net::PlainSocketImpl::read(void) +{ + jbyte b; + + // Do timeouts via select. + if (timeout > 0 && fnum >= 0 && fnum < FD_SETSIZE) + { + // Create the file descriptor set. + fd_set read_fds; + FD_ZERO (&read_fds); + FD_SET (fnum,&read_fds); + // Create the timeout struct based on our internal timeout value. + struct timeval timeout_value; + timeout_value.tv_sec = timeout / 1000; + timeout_value.tv_usec = (timeout % 1000) * 1000; + // Select on the fds. + int sel_retval = + _Jv_select (fnum + 1, &read_fds, NULL, NULL, &timeout_value); + // If select returns 0 we've waited without getting data... + // that means we've timed out. + if (sel_retval == 0) + throw new java::io::InterruptedIOException + (JvNewStringUTF ("read timed out") ); + // If select returns ok we know we either got signalled or read some data... + // either way we need to try to read. + } + + int r = _Jv_read (fnum, &b, 1); + + if (r == 0) + return -1; + + if (java::lang::Thread::interrupted()) + { + java::io::InterruptedIOException *iioe = + new java::io::InterruptedIOException + (JvNewStringUTF("read interrupted")); + iioe->bytesTransferred = r == -1 ? 0 : r; + throw iioe; + } + else if (r == -1) + { + // Some errors cause us to return end of stream... + if (errno == ENOTCONN) + return -1; + + // Other errors need to be signalled. + throw new java::io::IOException (JvNewStringUTF (strerror (errno))); + } + + return b & 0xFF; +} + +// Read count bytes into the buffer, starting at offset. +jint +java::net::PlainSocketImpl::read(jbyteArray buffer, jint offset, jint count) +{ + if (! buffer) + throw new java::lang::NullPointerException; + + jsize bsize = JvGetArrayLength (buffer); + + if (offset < 0 || count < 0 || offset + count > bsize) + throw new java::lang::ArrayIndexOutOfBoundsException; + + jbyte *bytes = elements (buffer) + offset; + + // Do timeouts via select. + if (timeout > 0 && fnum >= 0 && fnum < FD_SETSIZE) + { + // Create the file descriptor set. + fd_set read_fds; + FD_ZERO (&read_fds); + FD_SET (fnum, &read_fds); + // Create the timeout struct based on our internal timeout value. + struct timeval timeout_value; + timeout_value.tv_sec = timeout / 1000; + timeout_value.tv_usec =(timeout % 1000) * 1000; + // Select on the fds. + int sel_retval = + _Jv_select (fnum + 1, &read_fds, NULL, NULL, &timeout_value); + // We're only interested in the 0 return. + // error returns still require us to try to read + // the socket to see what happened. + if (sel_retval == 0) + { + java::io::InterruptedIOException *iioe = + new java::io::InterruptedIOException + (JvNewStringUTF ("read interrupted")); + iioe->bytesTransferred = 0; + throw iioe; + } + } + + // Read the socket. + int r = ::recv (fnum, (char *) bytes, count, 0); + + if (r == 0) + return -1; + + if (java::lang::Thread::interrupted()) + { + java::io::InterruptedIOException *iioe = + new java::io::InterruptedIOException + (JvNewStringUTF ("read interrupted")); + iioe->bytesTransferred = r == -1 ? 0 : r; + throw iioe; + } + else if (r == -1) + { + // Some errors cause us to return end of stream... + if (errno == ENOTCONN) + return -1; + + // Other errors need to be signalled. + throw new java::io::IOException (JvNewStringUTF (strerror (errno))); + } + + return r; +} + +// How many bytes are available? +jint +java::net::PlainSocketImpl::available(void) +{ +#if defined(FIONREAD) || defined(HAVE_SELECT) + long num = 0; + int r = 0; + bool num_set = false; + +#if defined(FIONREAD) + r = ::ioctl (fnum, FIONREAD, &num); + + if (r == -1 && errno == ENOTTY) + { + // If the ioctl doesn't work, we don't care. + r = 0; + num = 0; + } + else + num_set = true; +#elif defined(HAVE_SELECT) + if (fnum < 0) + { + errno = EBADF; + r = -1; + } +#endif + + if (r == -1) + { + posix_error: + throw new java::io::IOException(JvNewStringUTF(strerror(errno))); + } + + // If we didn't get anything we can use select. + +#if defined(HAVE_SELECT) + if (! num_set) + if (! num_set && fnum >= 0 && fnum < FD_SETSIZE) + { + fd_set rd; + FD_ZERO (&rd); + FD_SET (fnum, &rd); + struct timeval tv; + tv.tv_sec = 0; + tv.tv_usec = 0; + r = _Jv_select (fnum + 1, &rd, NULL, NULL, &tv); + if(r == -1) + goto posix_error; + num = r == 0 ? 0 : 1; + } +#endif /* HAVE_SELECT */ + + return (jint) num; +#else + throw new java::io::IOException (JvNewStringUTF ("unimplemented")); +#endif +} + +void +java::net::PlainSocketImpl::setOption (jint optID, java::lang::Object *value) +{ + int val; + socklen_t val_len = sizeof (val); + + if (fnum < 0) + throw new java::net::SocketException (JvNewStringUTF ("Socket closed")); + + if (_Jv_IsInstanceOf (value, &java::lang::Boolean::class$)) + { + java::lang::Boolean *boolobj = + static_cast<java::lang::Boolean *> (value); + if (boolobj->booleanValue()) + val = 1; + else + { + if (optID == _Jv_SO_LINGER_) + val = -1; + else + val = 0; + } + } + else if (_Jv_IsInstanceOf (value, &java::lang::Integer::class$)) + { + java::lang::Integer *intobj = + static_cast<java::lang::Integer *> (value); + val = (int) intobj->intValue(); + } + else + { + throw new java::lang::IllegalArgumentException ( + JvNewStringLatin1 ("`value' must be Boolean or Integer")); + } + + switch (optID) + { + case _Jv_TCP_NODELAY_ : +#ifdef TCP_NODELAY + if (::setsockopt (fnum, IPPROTO_TCP, TCP_NODELAY, (char *) &val, + val_len) != 0) + goto error; +#else + throw new java::lang::InternalError + (JvNewStringUTF ("TCP_NODELAY not supported")); +#endif /* TCP_NODELAY */ + return; + + case _Jv_SO_KEEPALIVE_ : + if (::setsockopt (fnum, SOL_SOCKET, SO_KEEPALIVE, (char *) &val, + val_len) != 0) + goto error; + break; + + case _Jv_SO_BROADCAST_ : + throw new java::net::SocketException + (JvNewStringUTF ("SO_BROADCAST not valid for TCP")); + break; + + case _Jv_SO_OOBINLINE_ : + if (::setsockopt (fnum, SOL_SOCKET, SO_OOBINLINE, (char *) &val, + val_len) != 0) + goto error; + break; + + case _Jv_SO_LINGER_ : +#ifdef SO_LINGER + struct linger l_val; + l_val.l_onoff = (val != -1); + l_val.l_linger = val; + + if (::setsockopt (fnum, SOL_SOCKET, SO_LINGER, (char *) &l_val, + sizeof(l_val)) != 0) + goto error; +#else + throw new java::lang::InternalError ( + JvNewStringUTF ("SO_LINGER not supported")); +#endif /* SO_LINGER */ + return; + + case _Jv_SO_SNDBUF_ : + case _Jv_SO_RCVBUF_ : +#if defined(SO_SNDBUF) && defined(SO_RCVBUF) + int opt; + optID == _Jv_SO_SNDBUF_ ? opt = SO_SNDBUF : opt = SO_RCVBUF; + if (::setsockopt (fnum, SOL_SOCKET, opt, (char *) &val, val_len) != 0) + goto error; +#else + throw new java::lang::InternalError ( + JvNewStringUTF ("SO_RCVBUF/SO_SNDBUF not supported")); +#endif + return; + + case _Jv_SO_BINDADDR_ : + throw new java::net::SocketException ( + JvNewStringUTF ("SO_BINDADDR: read only option")); + return; + + case _Jv_IP_MULTICAST_IF_ : + throw new java::net::SocketException ( + JvNewStringUTF ("IP_MULTICAST_IF: not valid for TCP")); + return; + + case _Jv_IP_MULTICAST_IF2_ : + throw new java::net::SocketException ( + JvNewStringUTF ("IP_MULTICAST_IF2: not valid for TCP")); + break; + + case _Jv_IP_MULTICAST_LOOP_ : + throw new java::net::SocketException ( + JvNewStringUTF ("IP_MULTICAST_LOOP: not valid for TCP")); + break; + + case _Jv_IP_TOS_ : + if (::setsockopt (fnum, SOL_SOCKET, IP_TOS, (char *) &val, + val_len) != 0) + goto error; + break; + + case _Jv_SO_REUSEADDR_ : + throw new java::net::SocketException ( + JvNewStringUTF ("SO_REUSEADDR: not valid for TCP")); + return; + + case _Jv_SO_TIMEOUT_ : + timeout = val; + return; + + default : + errno = ENOPROTOOPT; + } + + error: + char* strerr = strerror (errno); + throw new java::net::SocketException (JvNewStringUTF (strerr)); +} + +java::lang::Object * +java::net::PlainSocketImpl::getOption (jint optID) +{ + int val; + socklen_t val_len = sizeof(val); + union SockAddr u; + socklen_t addrlen = sizeof(u); + struct linger l_val; + socklen_t l_val_len = sizeof(l_val); + + switch (optID) + { +#ifdef TCP_NODELAY + case _Jv_TCP_NODELAY_ : + if (::getsockopt (fnum, IPPROTO_TCP, TCP_NODELAY, (char *) &val, + &val_len) != 0) + goto error; + else + return new java::lang::Boolean (val != 0); +#else + throw new java::lang::InternalError + (JvNewStringUTF ("TCP_NODELAY not supported")); +#endif + break; + + case _Jv_SO_LINGER_ : +#ifdef SO_LINGER + if (::getsockopt (fnum, SOL_SOCKET, SO_LINGER, (char *) &l_val, + &l_val_len) != 0) + goto error; + + if (l_val.l_onoff) + return new java::lang::Integer (l_val.l_linger); + else + return new java::lang::Boolean ((jboolean)false); +#else + throw new java::lang::InternalError + (JvNewStringUTF ("SO_LINGER not supported")); +#endif + break; + + case _Jv_SO_KEEPALIVE_ : + if (::getsockopt (fnum, SOL_SOCKET, SO_KEEPALIVE, (char *) &val, + &val_len) != 0) + goto error; + else + return new java::lang::Boolean (val != 0); + + case _Jv_SO_BROADCAST_ : + if (::getsockopt (fnum, SOL_SOCKET, SO_BROADCAST, (char *) &val, + &val_len) != 0) + goto error; + return new java::lang::Boolean ((jboolean)val); + + case _Jv_SO_OOBINLINE_ : + if (::getsockopt (fnum, SOL_SOCKET, SO_OOBINLINE, (char *) &val, + &val_len) != 0) + goto error; + return new java::lang::Boolean ((jboolean)val); + + case _Jv_SO_RCVBUF_ : + case _Jv_SO_SNDBUF_ : +#if defined(SO_SNDBUF) && defined(SO_RCVBUF) + int opt; + optID == _Jv_SO_SNDBUF_ ? opt = SO_SNDBUF : opt = SO_RCVBUF; + if (::getsockopt (fnum, SOL_SOCKET, opt, (char *) &val, &val_len) != 0) + goto error; + else + return new java::lang::Integer (val); +#else + throw new java::lang::InternalError + (JvNewStringUTF ("SO_RCVBUF/SO_SNDBUF not supported")); +#endif + break; + case _Jv_SO_BINDADDR_: + // cache the local address + if (localAddress == NULL) + { + jbyteArray laddr; + + if (::getsockname (fnum, (sockaddr*) &u, &addrlen) != 0) + goto error; + + if (u.address.sin_family == AF_INET) + { + laddr = JvNewByteArray (4); + memcpy (elements (laddr), &u.address.sin_addr, 4); + } +#ifdef HAVE_INET6 + else if (u.address.sin_family == AF_INET6) + { + laddr = JvNewByteArray (16); + memcpy (elements (laddr), &u.address6.sin6_addr, 16); + } +#endif + else + throw new java::net::SocketException + (JvNewStringUTF ("invalid family")); + localAddress = new java::net::InetAddress (laddr, NULL); + } + + return localAddress; + break; + case _Jv_IP_MULTICAST_IF_ : + throw new java::net::SocketException + (JvNewStringUTF ("IP_MULTICAST_IF: not valid for TCP")); + break; + + case _Jv_IP_MULTICAST_IF2_ : + throw new java::net::SocketException + (JvNewStringUTF ("IP_MULTICAST_IF2: not valid for TCP")); + break; + + case _Jv_IP_MULTICAST_LOOP_ : + throw new java::net::SocketException + (JvNewStringUTF ("IP_MULTICAST_LOOP: not valid for TCP")); + break; + + case _Jv_IP_TOS_ : + if (::getsockopt (fnum, SOL_SOCKET, IP_TOS, (char *) &val, + &val_len) != 0) + goto error; + return new java::lang::Integer (val); + break; + + case _Jv_SO_REUSEADDR_ : + throw new java::net::SocketException + (JvNewStringUTF ("SO_REUSEADDR: not valid for TCP")); + break; + + case _Jv_SO_TIMEOUT_ : + return new java::lang::Integer (timeout); + break; + + default : + errno = ENOPROTOOPT; + } + + error: + char* strerr = strerror (errno); + throw new java::net::SocketException (JvNewStringUTF (strerr)); +} + +void +java::net::PlainSocketImpl::shutdownInput (void) +{ + if (::shutdown (fnum, 0)) + throw new SocketException (JvNewStringUTF (strerror (errno))); +} + +void +java::net::PlainSocketImpl::shutdownOutput (void) +{ + if (::shutdown (fnum, 1)) + throw new SocketException (JvNewStringUTF (strerror (errno))); +} diff --git a/libjava/java/net/natPlainSocketImplWin32.cc b/libjava/java/net/natPlainSocketImplWin32.cc new file mode 100644 index 00000000000..1485ea842f9 --- /dev/null +++ b/libjava/java/net/natPlainSocketImplWin32.cc @@ -0,0 +1,1019 @@ +/* Copyright (C) 2003 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> + +#ifndef DISABLE_JAVA_NET + +#ifdef WIN32 + +#include <windows.h> +#include <winsock.h> +#include <errno.h> +#include <string.h> +#undef STRICT +#undef MAX_PRIORITY +#undef MIN_PRIORITY +#undef FIONREAD + +// These functions make the Win32 socket API look more POSIXy +static inline int +write(int s, void *buf, int len) +{ + return send(s, (char*)buf, len, 0); +} + +static inline int +read(int s, void *buf, int len) +{ + return recv(s, (char*)buf, len, 0); +} + +// these errors cannot occur on Win32 +#else /* WIN32 */ + +#ifdef HAVE_SYS_IOCTL_H +#define BSD_COMP /* Get FIONREAD on Solaris2. */ +#include <sys/ioctl.h> +#endif + +// Pick up FIONREAD on Solaris 2.5. +#ifdef HAVE_SYS_FILIO_H +#include <sys/filio.h> +#endif + +#include <netinet/in.h> +#include <netinet/tcp.h> +#include <errno.h> +#include <string.h> + +#endif /* WIN32 */ +#endif /* DISABLE_JAVA_NET */ + +#if HAVE_BSTRING_H +// Needed for bzero, implicitly used by FD_ZERO on IRIX 5.2 +#include <bstring.h> +#endif + + +#include <gcj/cni.h> +#include <gcj/javaprims.h> +#include <java/io/IOException.h> +#include <java/io/InterruptedIOException.h> +#include <java/net/BindException.h> +#include <java/net/ConnectException.h> +#include <java/net/PlainSocketImpl.h> +#include <java/net/InetAddress.h> +#include <java/net/InetSocketAddress.h> +#include <java/net/SocketException.h> +#include <java/net/SocketTimeoutException.h> +#include <java/lang/InternalError.h> +#include <java/lang/Object.h> +#include <java/lang/Boolean.h> +#include <java/lang/Class.h> +#include <java/lang/Integer.h> +#include <java/lang/Thread.h> +#include <java/lang/NullPointerException.h> +#include <java/lang/ArrayIndexOutOfBoundsException.h> +#include <java/lang/IllegalArgumentException.h> + +#ifdef DISABLE_JAVA_NET + +void +java::net::PlainSocketImpl::create (jboolean) +{ + throw new java::io::IOException ( + JvNewStringLatin1 ("SocketImpl.create: unimplemented")); +} + +void +java::net::PlainSocketImpl::bind (java::net::InetAddress *, jint) +{ + throw new BindException ( + JvNewStringLatin1 ("SocketImpl.bind: unimplemented")); +} + +void +java::net::PlainSocketImpl::connect (java::net::SocketAddress *, jint) +{ + throw new ConnectException ( + JvNewStringLatin1 ("SocketImpl.connect: unimplemented")); +} + +void +java::net::PlainSocketImpl::listen (jint) +{ + throw new java::io::IOException ( + JvNewStringLatin1 ("SocketImpl.listen: unimplemented")); +} + +void +java::net::PlainSocketImpl::accept (java::net::PlainSocketImpl *) +{ + throw new java::io::IOException ( + JvNewStringLatin1 ("SocketImpl.accept: unimplemented")); +} + +void +java::net::PlainSocketImpl::setOption (jint, java::lang::Object *) +{ + throw new SocketException ( + JvNewStringLatin1 ("SocketImpl.setOption: unimplemented")); +} + +java::lang::Object * +java::net::PlainSocketImpl::getOption (jint) +{ + throw new SocketException ( + JvNewStringLatin1 ("SocketImpl.getOption: unimplemented")); +} + +jint +java::net::PlainSocketImpl::read(void) +{ + throw new SocketException ( + JvNewStringLatin1 ("SocketImpl.read: unimplemented")); +} + +jint +java::net::PlainSocketImpl::read(jbyteArray buffer, jint offset, jint count) +{ + throw new SocketException ( + JvNewStringLatin1 ("SocketImpl.read: unimplemented")); +} + +void +java::net::PlainSocketImpl::write(jint b) +{ + throw new SocketException ( + JvNewStringLatin1 ("SocketImpl.write: unimplemented")); +} + +void +java::net::PlainSocketImpl::write(jbyteArray b, jint offset, jint len) +{ + throw new SocketException ( + JvNewStringLatin1 ("SocketImpl.write: unimplemented")); +} + +void +java::net::PlainSocketImpl::sendUrgentData(jint data) +{ + throw new SocketException ( + JvNewStringLatin1 ("SocketImpl.sendUrgentData: unimplemented")); +} + +jint +java::net::PlainSocketImpl::available(void) +{ + throw new SocketException ( + JvNewStringLatin1 ("SocketImpl.available: unimplemented")); +} + +void +java::net::PlainSocketImpl::close(void) +{ + throw new SocketException ( + JvNewStringLatin1 ("SocketImpl.close: unimplemented")); +} + +void +java::net::PlainSocketImpl::shutdownInput (void) +{ + throw new SocketException ( + JvNewStringLatin1 ("SocketImpl.shutdownInput: unimplemented")); +} + +void +java::net::PlainSocketImpl::shutdownOutput (void) +{ + throw new SocketException ( + JvNewStringLatin1 ("SocketImpl.shutdownOutput: unimplemented")); +} + +#else /* DISABLE_JAVA_NET */ + +union SockAddr +{ + struct sockaddr_in address; +#ifdef HAVE_INET6 + struct sockaddr_in6 address6; +#endif +}; + +void +java::net::PlainSocketImpl::create (jboolean stream) +{ + int sock = _Jv_socket (AF_INET, stream ? SOCK_STREAM : SOCK_DGRAM, 0); + + if (sock < 0) + { + char* strerr = strerror (errno); + throw new java::io::IOException (JvNewStringUTF (strerr)); + } + + _Jv_platform_close_on_exec (sock); + + // We use fnum in place of fd here. From leaving fd null we avoid + // the double close problem in FileDescriptor.finalize. + fnum = sock; +} + +void +java::net::PlainSocketImpl::bind (java::net::InetAddress *host, jint lport) +{ + union SockAddr u; + struct sockaddr *ptr = (struct sockaddr *) &u.address; + jbyteArray haddress = host->addr; + jbyte *bytes = elements (haddress); + int len = haddress->length; + int i = 1; + + if (len == 4) + { + u.address.sin_family = AF_INET; + + if (host != NULL) + memcpy (&u.address.sin_addr, bytes, len); + else + u.address.sin_addr.s_addr = htonl (INADDR_ANY); + + len = sizeof (struct sockaddr_in); + u.address.sin_port = htons (lport); + } +#ifdef HAVE_INET6 + else if (len == 16) + { + u.address6.sin6_family = AF_INET6; + memcpy (&u.address6.sin6_addr, bytes, len); + len = sizeof (struct sockaddr_in6); + u.address6.sin6_port = htons (lport); + } +#endif + else + throw new java::net::SocketException (JvNewStringUTF ("invalid length")); + + // Enable SO_REUSEADDR, so that servers can reuse ports left in TIME_WAIT. + ::setsockopt(fnum, SOL_SOCKET, SO_REUSEADDR, (char *) &i, sizeof(i)); + + if (_Jv_bind (fnum, ptr, len) == 0) + { + address = host; + socklen_t addrlen = sizeof(u); + + if (lport != 0) + localport = lport; + else if (::getsockname (fnum, (sockaddr*) &u, &addrlen) == 0) + localport = ntohs (u.address.sin_port); + else + goto error; + + return; + } + + error: + char* strerr = strerror (errno); + throw new java::net::BindException (JvNewStringUTF (strerr)); +} + +void +java::net::PlainSocketImpl::connect (java::net::SocketAddress *addr, + jint timeout) +{ + java::net::InetSocketAddress *tmp = (java::net::InetSocketAddress*) addr; + java::net::InetAddress *host = tmp->getAddress(); + jint rport = tmp->getPort(); + + union SockAddr u; + socklen_t addrlen = sizeof(u); + jbyteArray haddress = host->addr; + jbyte *bytes = elements (haddress); + int len = haddress->length; + struct sockaddr *ptr = (struct sockaddr *) &u.address; + if (len == 4) + { + u.address.sin_family = AF_INET; + memcpy (&u.address.sin_addr, bytes, len); + len = sizeof (struct sockaddr_in); + u.address.sin_port = htons (rport); + } +#ifdef HAVE_INET6 + else if (len == 16) + { + u.address6.sin6_family = AF_INET6; + memcpy (&u.address6.sin6_addr, bytes, len); + len = sizeof (struct sockaddr_in6); + u.address6.sin6_port = htons (rport); + } +#endif + else + throw new java::net::SocketException (JvNewStringUTF ("invalid length")); + +// FIXME: implement timeout support for Win32 +#ifndef WIN32 + if (timeout > 0) + { + int flags = ::fcntl (fnum, F_GETFL); + ::fcntl (fnum, F_SETFL, flags | O_NONBLOCK); + + if ((_Jv_connect (fnum, ptr, len) != 0) && (errno != EINPROGRESS)) + goto error; + + fd_set rset; + struct timeval tv; + FD_ZERO(&rset); + FD_SET(fnum, &rset); + tv.tv_sec = timeout / 1000; + tv.tv_usec = (timeout % 1000) * 1000; + int retval; + + if ((retval = _Jv_select (fnum + 1, &rset, NULL, NULL, &tv)) < 0) + goto error; + else if (retval == 0) + throw new java::net::SocketTimeoutException + (JvNewStringUTF ("Connect timed out")); + } + else +#endif + { + if (_Jv_connect (fnum, ptr, len) != 0) + goto error; + } + + address = host; + port = rport; + + // A bind may not have been done on this socket; if so, set localport now. + if (localport == 0) + { + if (::getsockname (fnum, (sockaddr*) &u, &addrlen) == 0) + localport = ntohs (u.address.sin_port); + else + goto error; + } + + return; + + error: + char* strerr = strerror (errno); + throw new java::net::ConnectException (JvNewStringUTF (strerr)); +} + +void +java::net::PlainSocketImpl::listen (jint backlog) +{ + if (::listen (fnum, backlog) != 0) + { + char* strerr = strerror (errno); + throw new java::io::IOException (JvNewStringUTF (strerr)); + } +} + +void +java::net::PlainSocketImpl::accept (java::net::PlainSocketImpl *s) +{ + union SockAddr u; + socklen_t addrlen = sizeof(u); + int new_socket = 0; + +// FIXME: implement timeout support for Win32 +#ifndef WIN32 + // Do timeouts via select since SO_RCVTIMEO is not always available. + if (timeout > 0 && fnum >= 0 && fnum < FD_SETSIZE) + { + fd_set rset; + struct timeval tv; + FD_ZERO(&rset); + FD_SET(fnum, &rset); + tv.tv_sec = timeout / 1000; + tv.tv_usec = (timeout % 1000) * 1000; + int retval; + if ((retval = _Jv_select (fnum + 1, &rset, NULL, NULL, &tv)) < 0) + goto error; + else if (retval == 0) + throw new java::io::InterruptedIOException ( + JvNewStringUTF("Accept timed out")); + } +#endif /* WIN32 */ + + new_socket = _Jv_accept (fnum, (sockaddr*) &u, &addrlen); + + if (new_socket < 0) + goto error; + + _Jv_platform_close_on_exec (new_socket); + + jbyteArray raddr; + jint rport; + if (u.address.sin_family == AF_INET) + { + raddr = JvNewByteArray (4); + memcpy (elements (raddr), &u.address.sin_addr, 4); + rport = ntohs (u.address.sin_port); + } +#ifdef HAVE_INET6 + else if (u.address.sin_family == AF_INET6) + { + raddr = JvNewByteArray (16); + memcpy (elements (raddr), &u.address6.sin6_addr, 16); + rport = ntohs (u.address6.sin6_port); + } +#endif + else + throw new java::net::SocketException (JvNewStringUTF ("invalid family")); + + s->fnum = new_socket; + s->localport = localport; + s->address = new InetAddress (raddr, NULL); + s->port = rport; + return; + + error: + char* strerr = strerror (errno); + throw new java::io::IOException (JvNewStringUTF (strerr)); +} + +// Close(shutdown) the socket. +void +java::net::PlainSocketImpl::close() +{ + // Avoid races from asynchronous finalization. + JvSynchronize sync (this); + + // should we use shutdown here? how would that effect so_linger? + int res = _Jv_close (fnum); + + if (res == -1) + { + // These three errors are not errors according to tests performed + // on the reference implementation. + if (errno != ENOTCONN && errno != ECONNRESET && errno != EBADF) + throw new java::io::IOException (JvNewStringUTF (strerror (errno))); + } + // Safe place to reset the file pointer. + fnum = -1; + timeout = 0; +} + +// Write a byte to the socket. +void +java::net::PlainSocketImpl::write(jint b) +{ + jbyte d =(jbyte) b; + int r = 0; + + while (r != 1) + { + r = _Jv_write (fnum, &d, 1); + if (r == -1) + { + if (java::lang::Thread::interrupted()) + { + java::io::InterruptedIOException *iioe + = new java::io::InterruptedIOException + (JvNewStringLatin1 (strerror (errno))); + iioe->bytesTransferred = 0; + throw iioe; + } + // Some errors should not cause exceptions. + if (errno != ENOTCONN && errno != ECONNRESET && errno != EBADF) + throw new java::io::IOException (JvNewStringUTF (strerror (errno))); + break; + } + } +} + +// Write some bytes to the socket. +void +java::net::PlainSocketImpl::write(jbyteArray b, jint offset, jint len) +{ + if (! b) + throw new java::lang::NullPointerException; + if (offset < 0 || len < 0 || offset + len > JvGetArrayLength (b)) + throw new java::lang::ArrayIndexOutOfBoundsException; + + jbyte *bytes = elements (b) + offset; + int written = 0; + + while (len > 0) + { + int r = _Jv_write (fnum, bytes, len); + + if (r == -1) + { + if (java::lang::Thread::interrupted()) + { + java::io::InterruptedIOException *iioe + = new java::io::InterruptedIOException + (JvNewStringLatin1 (strerror (errno))); + iioe->bytesTransferred = written; + throw iioe; + } + // Some errors should not cause exceptions. + if (errno != ENOTCONN && errno != ECONNRESET && errno != EBADF) + throw new java::io::IOException (JvNewStringUTF (strerror (errno))); + break; + } + + written += r; + len -= r; + bytes += r; + } +} + +void +java::net::PlainSocketImpl::sendUrgentData (jint) +{ + throw new SocketException (JvNewStringLatin1 ( + "PlainSocketImpl: sending of urgent data not supported by this socket")); +} + +// Read a single byte from the socket. +jint +java::net::PlainSocketImpl::read(void) +{ + jbyte b; + +// FIXME: implement timeout support for Win32 +#ifndef WIN32 + // Do timeouts via select. + if (timeout > 0 && fnum >= 0 && fnum < FD_SETSIZE) + { + // Create the file descriptor set. + fd_set read_fds; + FD_ZERO (&read_fds); + FD_SET (fnum,&read_fds); + // Create the timeout struct based on our internal timeout value. + struct timeval timeout_value; + timeout_value.tv_sec = timeout / 1000; + timeout_value.tv_usec = (timeout % 1000) * 1000; + // Select on the fds. + int sel_retval = + _Jv_select (fnum + 1, &read_fds, NULL, NULL, &timeout_value); + // If select returns 0 we've waited without getting data... + // that means we've timed out. + if (sel_retval == 0) + throw new java::io::InterruptedIOException + (JvNewStringUTF ("read timed out") ); + // If select returns ok we know we either got signalled or read some data... + // either way we need to try to read. + } +#endif /* WIN32 */ + + int r = _Jv_read (fnum, &b, 1); + + if (r == 0) + return -1; + + if (java::lang::Thread::interrupted()) + { + java::io::InterruptedIOException *iioe = + new java::io::InterruptedIOException + (JvNewStringUTF("read interrupted")); + iioe->bytesTransferred = r == -1 ? 0 : r; + throw iioe; + } + else if (r == -1) + { + // Some errors cause us to return end of stream... + if (errno == ENOTCONN) + return -1; + + // Other errors need to be signalled. + throw new java::io::IOException (JvNewStringUTF (strerror (errno))); + } + + return b & 0xFF; +} + +// Read count bytes into the buffer, starting at offset. +jint +java::net::PlainSocketImpl::read(jbyteArray buffer, jint offset, jint count) +{ + if (! buffer) + throw new java::lang::NullPointerException; + + jsize bsize = JvGetArrayLength (buffer); + + if (offset < 0 || count < 0 || offset + count > bsize) + throw new java::lang::ArrayIndexOutOfBoundsException; + + jbyte *bytes = elements (buffer) + offset; + +// FIXME: implement timeout support for Win32 +#ifndef WIN32 + // Do timeouts via select. + if (timeout > 0 && fnum >= 0 && fnum < FD_SETSIZE) + { + // Create the file descriptor set. + fd_set read_fds; + FD_ZERO (&read_fds); + FD_SET (fnum, &read_fds); + // Create the timeout struct based on our internal timeout value. + struct timeval timeout_value; + timeout_value.tv_sec = timeout / 1000; + timeout_value.tv_usec =(timeout % 1000) * 1000; + // Select on the fds. + int sel_retval = + _Jv_select (fnum + 1, &read_fds, NULL, NULL, &timeout_value); + // We're only interested in the 0 return. + // error returns still require us to try to read + // the socket to see what happened. + if (sel_retval == 0) + { + java::io::InterruptedIOException *iioe = + new java::io::InterruptedIOException + (JvNewStringUTF ("read interrupted")); + iioe->bytesTransferred = 0; + throw iioe; + } + } +#endif + + // Read the socket. + int r = ::recv (fnum, (char *) bytes, count, 0); + + if (r == 0) + return -1; + + if (java::lang::Thread::interrupted()) + { + java::io::InterruptedIOException *iioe = + new java::io::InterruptedIOException + (JvNewStringUTF ("read interrupted")); + iioe->bytesTransferred = r == -1 ? 0 : r; + throw iioe; + } + else if (r == -1) + { + // Some errors cause us to return end of stream... + if (errno == ENOTCONN) + return -1; + + // Other errors need to be signalled. + throw new java::io::IOException (JvNewStringUTF (strerror (errno))); + } + + return r; +} + +// How many bytes are available? +jint +java::net::PlainSocketImpl::available(void) +{ +#if defined(FIONREAD) || defined(HAVE_SELECT) + long num = 0; + int r = 0; + bool num_set = false; + +#if defined(FIONREAD) + r = ::ioctl (fnum, FIONREAD, &num); + + if (r == -1 && errno == ENOTTY) + { + // If the ioctl doesn't work, we don't care. + r = 0; + num = 0; + } + else + num_set = true; +#elif defined(HAVE_SELECT) + if (fnum < 0) + { + errno = EBADF; + r = -1; + } +#endif + + if (r == -1) + { + posix_error: + throw new java::io::IOException(JvNewStringUTF(strerror(errno))); + } + + // If we didn't get anything we can use select. + +#if defined(HAVE_SELECT) + if (! num_set) + if (! num_set && fnum >= 0 && fnum < FD_SETSIZE) + { + fd_set rd; + FD_ZERO (&rd); + FD_SET (fnum, &rd); + struct timeval tv; + tv.tv_sec = 0; + tv.tv_usec = 0; + r = _Jv_select (fnum + 1, &rd, NULL, NULL, &tv); + if(r == -1) + goto posix_error; + num = r == 0 ? 0 : 1; + } +#endif /* HAVE_SELECT */ + + return (jint) num; +#else + throw new java::io::IOException (JvNewStringUTF ("unimplemented")); +#endif +} + +void +java::net::PlainSocketImpl::setOption (jint optID, java::lang::Object *value) +{ + int val; + socklen_t val_len = sizeof (val); + + if (fnum < 0) + throw new java::net::SocketException (JvNewStringUTF ("Socket closed")); + + if (_Jv_IsInstanceOf (value, &java::lang::Boolean::class$)) + { + java::lang::Boolean *boolobj = + static_cast<java::lang::Boolean *> (value); + if (boolobj->booleanValue()) + val = 1; + else + { + if (optID == _Jv_SO_LINGER_) + val = -1; + else + val = 0; + } + } + else if (_Jv_IsInstanceOf (value, &java::lang::Integer::class$)) + { + java::lang::Integer *intobj = + static_cast<java::lang::Integer *> (value); + val = (int) intobj->intValue(); + } + else + { + throw new java::lang::IllegalArgumentException ( + JvNewStringLatin1 ("`value' must be Boolean or Integer")); + } + + switch (optID) + { + case _Jv_TCP_NODELAY_ : +#ifdef TCP_NODELAY + if (::setsockopt (fnum, IPPROTO_TCP, TCP_NODELAY, (char *) &val, + val_len) != 0) + goto error; +#else + throw new java::lang::InternalError + (JvNewStringUTF ("TCP_NODELAY not supported")); +#endif /* TCP_NODELAY */ + return; + + case _Jv_SO_KEEPALIVE_ : + if (::setsockopt (fnum, SOL_SOCKET, SO_KEEPALIVE, (char *) &val, + val_len) != 0) + goto error; + break; + + case _Jv_SO_BROADCAST_ : + throw new java::net::SocketException + (JvNewStringUTF ("SO_BROADCAST not valid for TCP")); + break; + + case _Jv_SO_OOBINLINE_ : + if (::setsockopt (fnum, SOL_SOCKET, SO_OOBINLINE, (char *) &val, + val_len) != 0) + goto error; + break; + + case _Jv_SO_LINGER_ : +#ifdef SO_LINGER + struct linger l_val; + l_val.l_onoff = (val != -1); + l_val.l_linger = val; + + if (::setsockopt (fnum, SOL_SOCKET, SO_LINGER, (char *) &l_val, + sizeof(l_val)) != 0) + goto error; +#else + throw new java::lang::InternalError ( + JvNewStringUTF ("SO_LINGER not supported")); +#endif /* SO_LINGER */ + return; + + case _Jv_SO_SNDBUF_ : + case _Jv_SO_RCVBUF_ : +#if defined(SO_SNDBUF) && defined(SO_RCVBUF) + int opt; + optID == _Jv_SO_SNDBUF_ ? opt = SO_SNDBUF : opt = SO_RCVBUF; + if (::setsockopt (fnum, SOL_SOCKET, opt, (char *) &val, val_len) != 0) + goto error; +#else + throw new java::lang::InternalError ( + JvNewStringUTF ("SO_RCVBUF/SO_SNDBUF not supported")); +#endif + return; + + case _Jv_SO_BINDADDR_ : + throw new java::net::SocketException ( + JvNewStringUTF ("SO_BINDADDR: read only option")); + return; + + case _Jv_IP_MULTICAST_IF_ : + throw new java::net::SocketException ( + JvNewStringUTF ("IP_MULTICAST_IF: not valid for TCP")); + return; + + case _Jv_IP_MULTICAST_IF2_ : + throw new java::net::SocketException ( + JvNewStringUTF ("IP_MULTICAST_IF2: not valid for TCP")); + break; + + case _Jv_IP_MULTICAST_LOOP_ : + throw new java::net::SocketException ( + JvNewStringUTF ("IP_MULTICAST_LOOP: not valid for TCP")); + break; + + case _Jv_IP_TOS_ : + if (::setsockopt (fnum, SOL_SOCKET, IP_TOS, (char *) &val, + val_len) != 0) + goto error; + break; + + case _Jv_SO_REUSEADDR_ : + throw new java::net::SocketException ( + JvNewStringUTF ("SO_REUSEADDR: not valid for TCP")); + return; + + case _Jv_SO_TIMEOUT_ : + timeout = val; + return; + + default : + errno = ENOPROTOOPT; + } + + error: + char* strerr = strerror (errno); + throw new java::net::SocketException (JvNewStringUTF (strerr)); +} + +java::lang::Object * +java::net::PlainSocketImpl::getOption (jint optID) +{ + int val; + socklen_t val_len = sizeof(val); + union SockAddr u; + socklen_t addrlen = sizeof(u); + struct linger l_val; + socklen_t l_val_len = sizeof(l_val); + + switch (optID) + { +#ifdef TCP_NODELAY + case _Jv_TCP_NODELAY_ : + if (::getsockopt (fnum, IPPROTO_TCP, TCP_NODELAY, (char *) &val, + &val_len) != 0) + goto error; + else + return new java::lang::Boolean (val != 0); +#else + throw new java::lang::InternalError + (JvNewStringUTF ("TCP_NODELAY not supported")); +#endif + break; + + case _Jv_SO_LINGER_ : +#ifdef SO_LINGER + if (::getsockopt (fnum, SOL_SOCKET, SO_LINGER, (char *) &l_val, + &l_val_len) != 0) + goto error; + + if (l_val.l_onoff) + return new java::lang::Integer (l_val.l_linger); + else + return new java::lang::Boolean ((jboolean)false); +#else + throw new java::lang::InternalError + (JvNewStringUTF ("SO_LINGER not supported")); +#endif + break; + + case _Jv_SO_KEEPALIVE_ : + if (::getsockopt (fnum, SOL_SOCKET, SO_KEEPALIVE, (char *) &val, + &val_len) != 0) + goto error; + else + return new java::lang::Boolean (val != 0); + + case _Jv_SO_BROADCAST_ : + if (::getsockopt (fnum, SOL_SOCKET, SO_BROADCAST, (char *) &val, + &val_len) != 0) + goto error; + return new java::lang::Boolean ((jboolean)val); + + case _Jv_SO_OOBINLINE_ : + if (::getsockopt (fnum, SOL_SOCKET, SO_OOBINLINE, (char *) &val, + &val_len) != 0) + goto error; + return new java::lang::Boolean ((jboolean)val); + + case _Jv_SO_RCVBUF_ : + case _Jv_SO_SNDBUF_ : +#if defined(SO_SNDBUF) && defined(SO_RCVBUF) + int opt; + optID == _Jv_SO_SNDBUF_ ? opt = SO_SNDBUF : opt = SO_RCVBUF; + if (::getsockopt (fnum, SOL_SOCKET, opt, (char *) &val, &val_len) != 0) + goto error; + else + return new java::lang::Integer (val); +#else + throw new java::lang::InternalError + (JvNewStringUTF ("SO_RCVBUF/SO_SNDBUF not supported")); +#endif + break; + case _Jv_SO_BINDADDR_: + // cache the local address + if (localAddress == NULL) + { + jbyteArray laddr; + + if (::getsockname (fnum, (sockaddr*) &u, &addrlen) != 0) + goto error; + + if (u.address.sin_family == AF_INET) + { + laddr = JvNewByteArray (4); + memcpy (elements (laddr), &u.address.sin_addr, 4); + } +#ifdef HAVE_INET6 + else if (u.address.sin_family == AF_INET6) + { + laddr = JvNewByteArray (16); + memcpy (elements (laddr), &u.address6.sin6_addr, 16); + } +#endif + else + throw new java::net::SocketException + (JvNewStringUTF ("invalid family")); + localAddress = new java::net::InetAddress (laddr, NULL); + } + + return localAddress; + break; + case _Jv_IP_MULTICAST_IF_ : + throw new java::net::SocketException + (JvNewStringUTF ("IP_MULTICAST_IF: not valid for TCP")); + break; + + case _Jv_IP_MULTICAST_IF2_ : + throw new java::net::SocketException + (JvNewStringUTF ("IP_MULTICAST_IF2: not valid for TCP")); + break; + + case _Jv_IP_MULTICAST_LOOP_ : + throw new java::net::SocketException + (JvNewStringUTF ("IP_MULTICAST_LOOP: not valid for TCP")); + break; + + case _Jv_IP_TOS_ : + if (::getsockopt (fnum, SOL_SOCKET, IP_TOS, (char *) &val, + &val_len) != 0) + goto error; + return new java::lang::Integer (val); + break; + + case _Jv_SO_REUSEADDR_ : + throw new java::net::SocketException + (JvNewStringUTF ("SO_REUSEADDR: not valid for TCP")); + break; + + case _Jv_SO_TIMEOUT_ : + return new java::lang::Integer (timeout); + break; + + default : + errno = ENOPROTOOPT; + } + + error: + char* strerr = strerror (errno); + throw new java::net::SocketException (JvNewStringUTF (strerr)); +} + +void +java::net::PlainSocketImpl::shutdownInput (void) +{ + if (::shutdown (fnum, 0)) + throw new SocketException (JvNewStringUTF (strerror (errno))); +} + +void +java::net::PlainSocketImpl::shutdownOutput (void) +{ + if (::shutdown (fnum, 1)) + throw new SocketException (JvNewStringUTF (strerror (errno))); +} + +#endif /* DISABLE_JAVA_NET */ diff --git a/libjava/javax/print/attribute/Attribute.java b/libjava/javax/print/attribute/Attribute.java new file mode 100644 index 00000000000..babf200651c --- /dev/null +++ b/libjava/javax/print/attribute/Attribute.java @@ -0,0 +1,50 @@ +/* Attribute.java -- + Copyright (C) 2002 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package javax.print.attribute; + +import java.io.Serializable; + +/** + * @author Michael Koch + */ +public interface Attribute extends Serializable +{ + public Class getCategory (); + + public String getName (); +} diff --git a/libjava/javax/print/attribute/AttributeSet.java b/libjava/javax/print/attribute/AttributeSet.java new file mode 100644 index 00000000000..325251a1dd7 --- /dev/null +++ b/libjava/javax/print/attribute/AttributeSet.java @@ -0,0 +1,77 @@ +/* AttributeSet.java -- + Copyright (C) 2002 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package javax.print.attribute; + +/** + * @author Michael Koch + */ +public interface AttributeSet +{ + /** + * Adds the specified attribute value to this attribute set + * if it is not already present. + */ + public boolean add (Attribute attribute); + + /** + * Adds all of the elements in the specified set to this attribute. + */ + public boolean addAll (AttributeSet attributes); + + public void clear (); + + public boolean containsKey (Class category); + + public boolean containsValue (Attribute attribute); + + public boolean equals (Object obj); + + public Attribute get (Class Category); + + public int hashCode (); + + public boolean isEmpty (); + + public boolean remove (Attribute attribute); + + public boolean remove (Class category); + + public int size (); + + public Attribute[] toArray (); +} diff --git a/libjava/javax/print/attribute/PrintRequestAttributeSet.java b/libjava/javax/print/attribute/PrintRequestAttributeSet.java new file mode 100644 index 00000000000..f8f6dba2d49 --- /dev/null +++ b/libjava/javax/print/attribute/PrintRequestAttributeSet.java @@ -0,0 +1,55 @@ +/* PrintRequestAttributeSet.java -- + Copyright (C) 2002 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package javax.print.attribute; + +/** + * @author Michael Koch + */ +public interface PrintRequestAttributeSet extends AttributeSet +{ + /** + * Adds the specified attribute value to this attribute set + * if it is not already present. + */ + public boolean add (Attribute attribute); + + /** + * Adds all of the elements in the specified set to this attribute. + */ + public boolean addAll (AttributeSet attributes); +} diff --git a/libjava/javax/rmi/BAD_OPERATION.java b/libjava/javax/rmi/BAD_OPERATION.java new file mode 100644 index 00000000000..36081a47c57 --- /dev/null +++ b/libjava/javax/rmi/BAD_OPERATION.java @@ -0,0 +1,4 @@ +package javax.rmi; + +/** XXX - Stub till we have org.omg.CORBA */ +public class BAD_OPERATION extends Exception { } diff --git a/libjava/javax/rmi/CORBA/ClassDesc.java b/libjava/javax/rmi/CORBA/ClassDesc.java new file mode 100644 index 00000000000..052046df926 --- /dev/null +++ b/libjava/javax/rmi/CORBA/ClassDesc.java @@ -0,0 +1,55 @@ +/* ClassDesc.java -- + Copyright (C) 2002 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package javax.rmi.CORBA; + +import java.io.Serializable; + +public class ClassDesc + implements Serializable +{ + /* + * The following is serialized form required by Java API Doc + */ + private String repid; + private String codebase; + + public ClassDesc() + { + } +} diff --git a/libjava/javax/rmi/CORBA/ObjectImpl.java b/libjava/javax/rmi/CORBA/ObjectImpl.java new file mode 100644 index 00000000000..d76d673cede --- /dev/null +++ b/libjava/javax/rmi/CORBA/ObjectImpl.java @@ -0,0 +1,9 @@ +package javax.rmi.CORBA; + +/** XXX - Stub till we have org.omg.CORBA */ +public class ObjectImpl +{ + public ObjectImpl _orb() { return null; } + public String object_to_string(ObjectImpl o) + throws javax.rmi.BAD_OPERATION { return null; } +} diff --git a/libjava/javax/rmi/CORBA/PortableRemoteObjectDelegate.java b/libjava/javax/rmi/CORBA/PortableRemoteObjectDelegate.java new file mode 100644 index 00000000000..a073cf4705c --- /dev/null +++ b/libjava/javax/rmi/CORBA/PortableRemoteObjectDelegate.java @@ -0,0 +1,63 @@ +/* PortableRemoteObjectDelegate.java -- Interface supporting PortableRemoteObject + Copyright (C) 2002 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package javax.rmi.CORBA; + +import java.rmi.*; + +/** + * A delegate is a singleton class that support delegation for method + * implementation in PortableRemoteObject. + */ +public interface PortableRemoteObjectDelegate +{ + void connect(Remote target, Remote source) + throws RemoteException; + + void exportObject(Remote obj) + throws RemoteException; + + Object narrow(Object narrowFrom, Class narrowTo) + throws ClassCastException; + + Remote toStub(Remote obj) + throws NoSuchObjectException; + + void unexportObject(Remote obj) + throws NoSuchObjectException; +} diff --git a/libjava/javax/rmi/CORBA/Stub.java b/libjava/javax/rmi/CORBA/Stub.java new file mode 100644 index 00000000000..c79b85cb46e --- /dev/null +++ b/libjava/javax/rmi/CORBA/Stub.java @@ -0,0 +1,120 @@ +/* Stub.java -- + Copyright (C) 2002 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package javax.rmi.CORBA; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.rmi.RemoteException; +//import org.omg.CORBA.ORB; +//import org.omg.CORBA_2_3.portable.ObjectImpl; +//import org.omg.CORBA.portable.ObjectImpl; +import gnu.javax.rmi.CORBA.DelegateFactory; +import gnu.javax.rmi.CORBA.GetDelegateInstanceException; + +public abstract class Stub extends ObjectImpl + implements Serializable +{ + private transient StubDelegate delegate; + + protected Stub() + { + try + { + delegate = (StubDelegate)DelegateFactory.getInstance("Stub"); + } + catch(GetDelegateInstanceException e) + { + delegate = null; + } + } + + public int hashCode() + { + if(delegate != null) + return delegate.hashCode(this); + else + return 0; + } + + public boolean equals(Object obj) + { + if(delegate != null) + return delegate.equals(this, obj); + else + return false; + } + + public String toString() + { + String s = null; + if(delegate != null) + s = delegate.toString(this); + if(s == null) + s = super.toString(); + return s; + } + + // XXX javax.rmi.ORB -> org.omg.CORBA.ORB + public void connect(javax.rmi.ORB orb) + throws RemoteException + { + if(delegate != null) + delegate.connect(this, orb); + } + + /** + * The following two routines are required by serialized form of Java API doc. + */ + private void readObject(ObjectInputStream stream) + throws IOException, ClassNotFoundException + { + if(delegate != null) + delegate.readObject(this, stream); + } + + private void writeObject(ObjectOutputStream stream) + throws IOException + { + if(delegate != null) + delegate.writeObject(this, stream); + } + +} diff --git a/libjava/javax/rmi/CORBA/StubDelegate.java b/libjava/javax/rmi/CORBA/StubDelegate.java new file mode 100644 index 00000000000..6c7f69fe7dc --- /dev/null +++ b/libjava/javax/rmi/CORBA/StubDelegate.java @@ -0,0 +1,65 @@ +/* StubDelegate.java -- + Copyright (C) 2002 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package javax.rmi.CORBA; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.rmi.RemoteException; +//import org.omg.CORBA.ORB; + +public interface StubDelegate +{ + + // XXX javax.rmi.ORB -> org.omg.CORBA.ORB + void connect(Stub self, javax.rmi.ORB orb) + throws RemoteException; + + boolean equals(Stub self, Object obj); + + int hashCode(Stub self); + + void readObject(Stub self, ObjectInputStream s) + throws IOException, ClassNotFoundException; + + String toString(Stub self); + + void writeObject(Stub self, ObjectOutputStream s) + throws IOException; +} diff --git a/libjava/javax/rmi/CORBA/SystemException.java b/libjava/javax/rmi/CORBA/SystemException.java new file mode 100644 index 00000000000..f8afdc35e35 --- /dev/null +++ b/libjava/javax/rmi/CORBA/SystemException.java @@ -0,0 +1,4 @@ +package javax.rmi.CORBA; + +/** XXX - Stub till we have org.omg.CORBA */ +public class SystemException extends Exception { } diff --git a/libjava/javax/rmi/CORBA/Tie.java b/libjava/javax/rmi/CORBA/Tie.java new file mode 100644 index 00000000000..ca14e3d4236 --- /dev/null +++ b/libjava/javax/rmi/CORBA/Tie.java @@ -0,0 +1,62 @@ +/* Tie.java -- + Copyright (C) 2002 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package javax.rmi.CORBA; + +import java.rmi.Remote; +//import org.omg.CORBA.ORB; +//import org.omg.CORBA.portable.InvokeHandler; + +public interface Tie // XXX extends InvokeHandler +{ + + void deactivate(); + + Remote getTarget(); + + // XXX javax.rmi.ORB -> org.omg.CORBA.ORB + javax.rmi.ORB orb(); + + // XXX javax.rmi.ORB -> org.omg.CORBA.ORB + void orb(javax.rmi.ORB orb); + + void setTarget(Remote target); + + // XXX Object -> org.omg.CORBA.Object + Object thisObject(); +} diff --git a/libjava/javax/rmi/CORBA/Util.java b/libjava/javax/rmi/CORBA/Util.java new file mode 100644 index 00000000000..45a189d97c5 --- /dev/null +++ b/libjava/javax/rmi/CORBA/Util.java @@ -0,0 +1,187 @@ +/* Util.java -- + Copyright (C) 2002 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package javax.rmi.CORBA; + +import java.rmi.Remote; +import java.rmi.RemoteException; +import java.lang.Object; +import java.io.*; +//import org.omg.CORBA.*; +//import org.omg.CORBA.portable.InputStream; +//import org.omg.CORBA.portable.OutputStream; +import gnu.javax.rmi.CORBA.DelegateFactory; +import gnu.javax.rmi.CORBA.GetDelegateInstanceException; + +public class Util +{ + + private static UtilDelegate delegate; + static + { + try + { + delegate = (UtilDelegate)DelegateFactory.getInstance("Util"); + } + catch(GetDelegateInstanceException e) + { + delegate = null; + } + } + + private Util() + { + } + + // XXX - javax.rmi.ORB -> org.omg.CORBA.ORB + public static Object copyObject(Object obj, javax.rmi.ORB orb) + throws RemoteException + { + if(delegate != null) + return delegate.copyObject(obj, orb); + else + return null; + } + + // XXX - javax.rmi.ORB -> org.omg.CORBA.ORB + public static Object[] copyObjects(Object obj[], javax.rmi.ORB orb) + throws RemoteException + { + if(delegate != null) + return delegate.copyObjects(obj, orb); + else + return null; + } + + public static ValueHandler createValueHandler() + { + if(delegate != null) + return delegate.createValueHandler(); + else + return null; + } + + public static String getCodebase(Class clz) + { + if(delegate != null) + return delegate.getCodebase(clz); + else + return null; + } + + public static Tie getTie(Remote target) + { + if(delegate != null) + return delegate.getTie(target); + else + return null; + } + + public static boolean isLocal(Stub stub) + throws RemoteException + { + if(delegate != null) + return delegate.isLocal(stub); + else + return false; + } + + public static Class loadClass(String className, String remoteCodebase, ClassLoader loader) + throws ClassNotFoundException + { + if(delegate != null) + return delegate.loadClass(className, remoteCodebase, loader); + else + throw new ClassNotFoundException(className + ": delegate == null"); + } + + public static RemoteException mapSystemException(SystemException ex) + { + if(delegate != null) + return delegate.mapSystemException(ex); + else + return null; + } + + public static Object readAny(InputStream in) + { + if(delegate != null) + return delegate.readAny(in); + else + return null; + } + + public static void registerTarget(Tie tie, Remote target) + { + if(delegate != null) + delegate.registerTarget(tie, target); + } + + public static void unexportObject(Remote target) + { + if(delegate != null) + delegate.unexportObject(target); + } + + public static RemoteException wrapException(Throwable orig) + { + if(delegate != null) + return delegate.wrapException(orig); + else + return null; + } + + public static void writeAbstractObject(OutputStream out, Object obj) + { + if(delegate != null) + delegate.writeAbstractObject(out, obj); + } + + public static void writeAny(OutputStream out, Object obj) + { + if(delegate != null) + delegate.writeAny(out, obj); + } + + public static void writeRemoteObject(OutputStream out, Object obj) + { + if(delegate != null) + delegate.writeRemoteObject(out, obj); + } + +} diff --git a/libjava/javax/rmi/CORBA/UtilDelegate.java b/libjava/javax/rmi/CORBA/UtilDelegate.java new file mode 100644 index 00000000000..4d611bc8bfb --- /dev/null +++ b/libjava/javax/rmi/CORBA/UtilDelegate.java @@ -0,0 +1,84 @@ +/* UtilDelegate.java -- + Copyright (C) 2002 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package javax.rmi.CORBA; + +import java.rmi.Remote; +import java.rmi.RemoteException; +import java.io.*; +//import org.omg.CORBA.ORB; +//import org.omg.CORBA.SystemException; +//import org.omg.CORBA.portable.InputStream; +//import org.omg.CORBA.portable.OutputStream; + +public interface UtilDelegate +{ + + // XXX javax.rmi.ORB -> org.omg.CORBA.ORB + Object copyObject(Object obj, javax.rmi.ORB orb) throws RemoteException; + + // XXX javax.rmi.ORB -> org.omg.CORBA.ORB + Object[] copyObjects(Object obj[], javax.rmi.ORB orb) throws RemoteException; + + ValueHandler createValueHandler(); + + String getCodebase(Class clz); + + Tie getTie(Remote target); + + boolean isLocal(Stub stub) throws RemoteException; + + Class loadClass(String className, String remoteCodebase, + ClassLoader loader) throws ClassNotFoundException; + + RemoteException mapSystemException(SystemException ex); + + Object readAny(InputStream in); + + void registerTarget(Tie tie, Remote target); + + void unexportObject(Remote target); + + RemoteException wrapException(Throwable orig); + + void writeAbstractObject(OutputStream out, Object obj); + + void writeAny(OutputStream out, Object obj); + + void writeRemoteObject(OutputStream out, Object obj); +} diff --git a/libjava/javax/rmi/CORBA/ValueHandler.java b/libjava/javax/rmi/CORBA/ValueHandler.java new file mode 100644 index 00000000000..3a008f18cca --- /dev/null +++ b/libjava/javax/rmi/CORBA/ValueHandler.java @@ -0,0 +1,63 @@ +/* ValueHandler.java -- + Copyright (C) 2002 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package javax.rmi.CORBA; + +import java.io.*; +//import org.omg.CORBA.portable.InputStream; +//import org.omg.CORBA.portable.OutputStream; +//import org.omg.SendingContext.RunTime; + +public interface ValueHandler +{ + + String getRMIRepositoryID(Class clz); + + // XXX Runtime -> RunTime + Runtime getRunTimeCodeBase(); + + boolean isCustomMarshaled(Class clz); + + // XXX Runtime -> RunTime + Serializable readValue(InputStream in, int offset, Class clz, + String repositoryID, Runtime sender); + + Serializable writeReplace(Serializable value); + + void writeValue(OutputStream out, Serializable value); +} diff --git a/libjava/javax/rmi/ORB.java b/libjava/javax/rmi/ORB.java new file mode 100644 index 00000000000..be7a894e65a --- /dev/null +++ b/libjava/javax/rmi/ORB.java @@ -0,0 +1,4 @@ +package javax.rmi; + +/** XXX - Stub till we have org.omg.CORBA */ +public class ORB { } diff --git a/libjava/javax/rmi/PortableRemoteObject.java b/libjava/javax/rmi/PortableRemoteObject.java new file mode 100644 index 00000000000..ee40d9c9e74 --- /dev/null +++ b/libjava/javax/rmi/PortableRemoteObject.java @@ -0,0 +1,114 @@ +/* PortableRemoteObject.java -- + Copyright (C) 2002 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package javax.rmi; + +import java.rmi.Remote; +import java.rmi.RemoteException; +import java.rmi.NoSuchObjectException; +import gnu.javax.rmi.CORBA.DelegateFactory; +import gnu.javax.rmi.CORBA.GetDelegateInstanceException; +import javax.rmi.CORBA.PortableRemoteObjectDelegate; +import javax.rmi.CORBA.Util; + +public class PortableRemoteObject + implements Remote /* why doc doesn't say should implement Remote */ +{ + + private static PortableRemoteObjectDelegate delegate; + static + { + try + { + delegate = (PortableRemoteObjectDelegate)DelegateFactory.getInstance + ("PortableRemoteObject"); + } + catch(GetDelegateInstanceException e) + { + e.printStackTrace(); + delegate = null; + } + } + + protected PortableRemoteObject() + throws RemoteException + { + if(delegate != null) + exportObject((Remote)this); + } + + public static void connect(Remote target, Remote source) + throws RemoteException + { + if(delegate != null) + delegate.connect(target, source); + } + + public static void exportObject(Remote obj) + throws RemoteException + { + if(delegate != null) + delegate.exportObject(obj); + } + + public static Object narrow(Object narrowFrom, Class narrowTo) + throws ClassCastException + { + if(delegate != null) + return delegate.narrow(narrowFrom, narrowTo); + else + return null; + } + + public static Remote toStub(Remote obj) + throws NoSuchObjectException + { + if(delegate != null) + return delegate.toStub(obj); + else + return null; + } + + public static void unexportObject(Remote obj) + throws NoSuchObjectException + { + if(delegate != null) + delegate.unexportObject(obj); + } + +} diff --git a/libjava/javax/swing/JFormattedTextField.java b/libjava/javax/swing/JFormattedTextField.java new file mode 100644 index 00000000000..c7838e80a36 --- /dev/null +++ b/libjava/javax/swing/JFormattedTextField.java @@ -0,0 +1,230 @@ +/* JFormattedTextField.java -- + Copyright (C) 2003 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package javax.swing; + +import java.awt.event.FocusEvent; +import java.io.Serializable; +import java.text.Format; +import javax.swing.text.Document; +import javax.swing.text.DocumentFilter; +import javax.swing.text.NavigationFilter; + +/** + * @author Michael Koch + * @since 1.4 + */ +public class JFormattedTextField extends JTextField +{ + public abstract static class AbstractFormatter implements Serializable + { + public AbstractFormatter () + { + //Do nothing here. + } + + protected Object clone () + { + throw new InternalError ("not implemented"); + } + + protected Action[] getActions () + { + throw new InternalError ("not implemented"); + } + + protected DocumentFilter getDocumentFilter () + { + throw new InternalError ("not implemented"); + } + + protected JFormattedTextField getFormattedTextField () + { + throw new InternalError ("not implemented"); + } + + protected NavigationFilter getNavigationFilter () + { + throw new InternalError ("not implemented"); + } + + public void install (JFormattedTextField ftf) + { + throw new InternalError ("not implemented"); + } + + public void uninstall () + { + throw new InternalError ("not implemented"); + } + + protected void invalidEdit () + { + throw new InternalError ("not implemented"); + } + + protected void setEditValid () + { + throw new InternalError ("not implemented"); + } + + public abstract Object stringToValue (String text); + + public abstract String valueToString (Object value); + } + + public abstract static class AbstractFormatterFactory + { + public AbstractFormatterFactory () + { + // Do nothing here. + } + + public abstract AbstractFormatter getFormatter (JFormattedTextField tf); + } + + public static final int COMMIT = 0; + public static final int COMMIT_OR_REVERT = 1; + public static final int REVERT = 2; + public static final int PERSIST = 3; + + public JFormattedTextField () + { + throw new InternalError ("not implemented"); + } + + public JFormattedTextField (Format format) + { + throw new InternalError ("not implemented"); + } + + public JFormattedTextField (AbstractFormatter formatter) + { + throw new InternalError ("not implemented"); + } + + public JFormattedTextField (AbstractFormatterFactory factory) + { + throw new InternalError ("not implemented"); + } + + public JFormattedTextField (AbstractFormatterFactory factory, Object value) + { + throw new InternalError ("not implemented"); + } + + public JFormattedTextField (Object value) + { + throw new InternalError ("not implemented"); + } + + public void commitEdit () + { + throw new InternalError ("not implemented"); + } + + public Action[] getActions () + { + throw new InternalError ("not implemented"); + } + + public int getFocusLostBehaviour () + { + throw new InternalError ("not implemented"); + } + + public AbstractFormatter getFormatter () + { + throw new InternalError ("not implemented"); + } + + public AbstractFormatterFactory getFormatterFactory () + { + throw new InternalError ("not implemented"); + } + + public String getUIClassID () + { + throw new InternalError ("not implemented"); + } + + public Object getValue () + { + throw new InternalError ("not implemented"); + } + + protected void invalidEdit () + { + throw new InternalError ("not implemented"); + } + + public boolean isEditValid () + { + throw new InternalError ("not implemented"); + } + + protected void processFocusEvent (FocusEvent evt) + { + throw new InternalError ("not implemented"); + } + + public void setDocument (Document document) + { + throw new InternalError ("not implemented"); + } + + public void setLostFocusBehavior (int behavior) + { + throw new InternalError ("not implemented"); + } + + protected void setFormatter (AbstractFormatter formatter) + { + throw new InternalError ("not implemented"); + } + + public void setFormatterFactory (AbstractFormatterFactory factory) + { + throw new InternalError ("not implemented"); + } + + public void setValue (Object value) + { + throw new InternalError ("not implemented"); + } +} diff --git a/libjava/javax/swing/text/DocumentFilter.java b/libjava/javax/swing/text/DocumentFilter.java new file mode 100644 index 00000000000..7a8e95df98d --- /dev/null +++ b/libjava/javax/swing/text/DocumentFilter.java @@ -0,0 +1,43 @@ +/* DocumentFilter.java -- + Copyright (C) 2003 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package javax.swing.text; + +public class DocumentFilter +{ +} diff --git a/libjava/javax/swing/text/NavigationFilter.java b/libjava/javax/swing/text/NavigationFilter.java new file mode 100644 index 00000000000..37d1c380a65 --- /dev/null +++ b/libjava/javax/swing/text/NavigationFilter.java @@ -0,0 +1,43 @@ +/* NavigationFilter.java -- + Copyright (C) 2003 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package javax.swing.text; + +public class NavigationFilter +{ +} diff --git a/libjava/testsuite/libjava.cni/cni.exp b/libjava/testsuite/libjava.cni/cni.exp new file mode 100644 index 00000000000..22df1462c1d --- /dev/null +++ b/libjava/testsuite/libjava.cni/cni.exp @@ -0,0 +1,119 @@ +# Tests for CNI code. + +# Compile a single C++ file and produce a .o file. OPTIONS is a list +# of options to pass to the compiler. Returns 0 on failure, 1 on +# success. +proc gcj_cni_compile_cxx_to_o {file {options {}}} { + global srcdir + + set name [file rootname [file tail $file]] + set oname ${name}.o + + # Find the generated header. + lappend options "additional_flags=-I. -I.." + # Find libgcj headers. + lappend options "additional_flags=-I$srcdir/.." + + set x [libjava_prune_warnings \ + [target_compile $file $oname object $options]] + if {$x != ""} { + verbose "target_compile failed: $x" 2 + fail "[file tail $file] compilation" + return 0 + } + + pass "[file tail $file] compilation" + return 1 +} + +# Build header files given name of .java file. Return 0 on failure. +proc gcj_cni_build_headers {file} { + set gcjh [find_gcjh] + set jvscan [find_jvscan] + + set class_out [string trim \ + [libjava_prune_warnings \ + [lindex [local_exec "$jvscan --encoding=UTF-8 $file --list-class" "" "" 300] 1]]] + if {[string match "*parse error*" $class_out]} { + fail "$file header generation" + return 0 + } + + foreach file [split $class_out] { + set x [string trim [libjava_prune_warnings \ + [lindex [local_exec "$gcjh $file" "" "" 300] 1]]] + if {$x != ""} { + verbose "local_exec failed: $x" 2 + fail "$file header generation" + return 0 + } + } + + pass "$file header generation" + return 1 +} + +# Do all the work for a single CNI test. Return 0 on failure. +proc gcj_cni_test_one {file} { + global runtests + + # The base name. We use it for several purposes. + set main [file rootname [file tail $file]] + if {! [runtest_file_p $runtests $main]} { + # Simply skip it. + return 1 + } + + if {! [bytecompile_file $file [pwd]]} { + fail "bytecompile $file" + # FIXME - should use `untested' on all remaining tests. + # But that is hard. + return 0 + } + pass "bytecompile $file" + + if {! [gcj_cni_build_headers $file]} { + # FIXME + return 0 + } + + set cfile [file join [file dirname $file] nat$main.cc] + if {! [gcj_cni_compile_cxx_to_o $cfile]} { + # FIXME + return 0 + } + + if {! [gcj_link $main $main [list $file nat$main.o]]} { + # FIXME + return 0 + } + + if {! [gcj_invoke $main [file rootname $file].out {}]} { + # FIXME + return 0 + } + + # When we succeed we remove all our clutter. + eval gcj_cleanup [glob -nocomplain -- ${main}.*] [list $main nat$main.o] + + return 1 +} + +# Run the CNI tests. +proc gcj_cni_run {} { + global srcdir subdir + global build_triplet host_triplet + + # For now we only test CNI on native builds. + if {$build_triplet == $host_triplet} { + catch { lsort [glob -nocomplain ${srcdir}/${subdir}/*.java] } srcfiles + + foreach x $srcfiles { + gcj_cni_test_one $x + } + } else { + verbose "CNI tests not run in cross-compilation environment" + } +} + +gcj_cni_run diff --git a/libjava/testsuite/libjava.cni/longfield.java b/libjava/testsuite/libjava.cni/longfield.java new file mode 100644 index 00000000000..917bf953a05 --- /dev/null +++ b/libjava/testsuite/libjava.cni/longfield.java @@ -0,0 +1,22 @@ +public class longfield +{ + long lval = 232300; + boolean bval = true; + String sval = "maude"; + + public native void doitc (); + + public void doitj() + { + System.out.println(lval); + System.out.println(bval); + System.out.println(sval); + } + + public static void main(String[] args) + { + longfield f = new longfield(); + f.doitc(); + f.doitj(); + } +} diff --git a/libjava/testsuite/libjava.cni/longfield.out b/libjava/testsuite/libjava.cni/longfield.out new file mode 100644 index 00000000000..d041bbbf7d0 --- /dev/null +++ b/libjava/testsuite/libjava.cni/longfield.out @@ -0,0 +1,6 @@ +232300 +true +maude +232300 +true +maude diff --git a/libjava/testsuite/libjava.cni/natlongfield.cc b/libjava/testsuite/libjava.cni/natlongfield.cc new file mode 100644 index 00000000000..c16a46c76ac --- /dev/null +++ b/libjava/testsuite/libjava.cni/natlongfield.cc @@ -0,0 +1,15 @@ +#include <gcj/cni.h> + +#include "longfield.h" +#include <java/lang/System.h> +#include <java/io/PrintStream.h> + +void +longfield::doitc () +{ + java::io::PrintStream *ps = java::lang::System::out; + + ps->println(lval); + ps->println(bval); + ps->println(sval); +} diff --git a/libjava/testsuite/libjava.cni/natshortfield.cc b/libjava/testsuite/libjava.cni/natshortfield.cc new file mode 100644 index 00000000000..08a7d5c0507 --- /dev/null +++ b/libjava/testsuite/libjava.cni/natshortfield.cc @@ -0,0 +1,10 @@ +#include <stdio.h> +#include "shortfield.h" + +void shortfield::ouch () +{ + printf ("list: %d %d 0x%x\n", + modCount, + size__, + data); +} diff --git a/libjava/testsuite/libjava.cni/shortfield.java b/libjava/testsuite/libjava.cni/shortfield.java new file mode 100644 index 00000000000..68b6c5e22fb --- /dev/null +++ b/libjava/testsuite/libjava.cni/shortfield.java @@ -0,0 +1,21 @@ +class shortfieldbase +{ + short modCount; +} + +public class shortfield extends shortfieldbase +{ + short size__; + int data; + + native void ouch (); + + public static void main (String[] s) + { + shortfield f = new shortfield(); + f.modCount = 99; + f.size__ = 2; + f.data = 0x12345678; + f.ouch(); + } +} diff --git a/libjava/testsuite/libjava.cni/shortfield.out b/libjava/testsuite/libjava.cni/shortfield.out new file mode 100644 index 00000000000..06485dbae49 --- /dev/null +++ b/libjava/testsuite/libjava.cni/shortfield.out @@ -0,0 +1 @@ +list: 99 2 0x12345678 diff --git a/libjava/testsuite/libjava.lang/initfield.java b/libjava/testsuite/libjava.lang/initfield.java new file mode 100644 index 00000000000..4ee6154806d --- /dev/null +++ b/libjava/testsuite/libjava.lang/initfield.java @@ -0,0 +1,20 @@ +// gcj generated buggy code when we reference a field of a +// non-constant member that we inherit from an interface. + +interface iface +{ + final value x = new value(); +} + +final class value +{ + Object field = "maude"; +} + +public class initfield implements iface +{ + public static void main(String[] args) + { + System.out.println(x.field); + } +} diff --git a/libjava/testsuite/libjava.lang/initfield.out b/libjava/testsuite/libjava.lang/initfield.out new file mode 100644 index 00000000000..b3668c4d4d6 --- /dev/null +++ b/libjava/testsuite/libjava.lang/initfield.out @@ -0,0 +1 @@ +maude |