diff options
| author | Casey Marshall <csm@gnu.org> | 2006-09-17 07:31:39 +0000 |
|---|---|---|
| committer | Casey Marshall <csm@gnu.org> | 2006-09-17 07:31:39 +0000 |
| commit | 133e014be0604b45f8ccede687acf1ea979d4955 (patch) | |
| tree | 03bfec201e509081586497b0e4db7944e633cab7 /gnu/java/nio/SocketChannelImpl.java | |
| parent | a344c95abdd44f1c697d0520bf97ac3c8403a3b6 (diff) | |
| download | classpath-133e014be0604b45f8ccede687acf1ea979d4955.tar.gz | |
2006-09-16 Casey Marshall <csm@gnu.org>
* NEWS: updated.
* configure.ac (AC_CHECK_HEADERS): check for `sys/event.h'.
(AC_CHECK_FUNCS): add checks for readv, writev, getifaddrs,
kqueue, and kevent.
(HAVE_INET6): define if IPv6 is supported.
* gnu/java/net/PlainDatagramSocketImpl.java (channel): new field.
(native_fd): removed.
(impl): new field.
(<init>): throw IOException; initialize fields.
(finalize): removed.
(getNativeFD): removed.
(bind): use `PlainSocketImpl.bind.'
(create): use `PlainSocketImpl.initSocket.'
(disconnect): use `PlainSocketImpl.disconnect.'
(getLocalPort): new method.
(send): use `VMChannel.send.'
(receive): use `VMChannel.receive.'
(setOption): use `PlainSocketImpl.setOption.'
(getOption): use `PlainSocketImpl.getOption.'
(close): use `VMChannel.State.close.'
(join): use `PlainSocketImpl.join.'
(leave): use `PlainSocketImpl.leave.'
(joinGroup, leaveGroup): implemented.
* gnu/java/net/PlainSocketImpl.java: make non-final.
(native_fd): removed.
(impl): new field.
(channel): new field.
(<init>): initialize `impl.'
(finalize, getNativeFD): removed.
(setOption): use `PlainSocketImpl.setOption.'
(getOption): use `PlainSocketImpl.getOption.'
(shutdownInput): use `PlainSocketImpl.shutdownInput.'
(shutdownOutput): use `PlainSocketImpl.shutdownOutput.'
(create): create `channel,' initialize `impl's native state.
(connect): use `connect(SocketAddress, int).'
(connect): use `SocketChannelImpl.connect;' initialize `address'
and `port.'
(bind): use `VMPlainSocketImpl.bind.'
(listen): use `VMPlainSocketImpl.listen.'
(accept): use `SocketChannelImpl.accept.'
(available): use `VMChannel.available.'
(close): use `PlainSocketImpl.close.'
(sendUrgentData): use `PlainSocketImpl.sendUrgentData.'
(getVMChannel, getInetAddress, getLocalPort, getLocalAddress,
getPort): new methods.
(SocketInputStream.read): use `VMChannel.read.'
(SocketInputStream.read): use `SocketChannel.read.'
(SocketOutputStream.write): use `VMChannel.write.'
(SocketOutputStream.write): use `SocketChannel.write.'
* gnu/java/nio/DatagramChannelImpl.java: implement VMChannel.
(channel): new field.
(<init>): initialize `channel.'
(implCloseSelectableChannel): use `VMChannel.close.'
(implConfigureBlocking): use `VMChannel.setBlocking.'
(connect): use `VMChannel.connect.'
(disconnect): use `VMChannel.disconnect.'
(isConnected): use `VMChannel.getPeerAddress.'
(write): use `VMChannel.write.'
(write): use `VMChannel.writeGathering.'
(read): use `VMChannel.read.'
(read): use `VMChannel.readScattering.'
(receive): use `VMChannel.receive.'
(send): use `VMChannel.send.'
(getVMChannel): new method.
* gnu/java/nio/DatagramChannelSelectionKey.java (getNativeFD):
access native FD through VMChannel.State.
* gnu/java/nio/FileChannelImpl.java: moved from
gnu/java/nio/channels/FileChannelImpl.java.
* gnu/java/nio/FileLockImpl.java: fix imports.
* gnu/java/nio/KqueueSelectionKeyImpl.java: new file.
* gnu/java/nio/KqueueSelectorImpl.java: new file.
* gnu/java/nio/NIOSocket.java (impl): removed.
(channel): new field.
(<init>): init superclass with a `NIOSocketImpl;' init `channel.'
(getPlainSocketImpl, setChannel): removed.
(isConnected): new method.
* gnu/java/nio/NIOSocketImpl.java: new file.
* gnu/java/nio/PipeImpl.java (SourceChannelImpl): implement
`VMChannelOwner.'
(SourceChannelImpl.native_fd): removed.
(SourceChannelImpl.<init>): init with a `VMChannel.'
(SourceChannelImpl.getNativeFD): removed.
(SourceChannelImpl.getVMChannel): new method.
(SourceChannelImpl.implCloseSelectableChannel): implement.
(SinkChannelImpl): implement `VMChannelOwner.'
(SinkChannelImpl.native_fd): removed.
(SinkChannelImpl.<init>): init with a `VMChannel.'
(SinkChannelImpl.implCloseSelectableChannel): implement.
(SinkChannelImpl.getNativeFD): removed.
(SinkChannelImpl.getVMChannel): new method.
* gnu/java/nio/SelectionKeyImpl.java (getNativeFD): mark
deprecated.
* gnu/java/nio/SelectorProviderImpl.java (SELECTOR_IMPL_KQUEUE,
SELECTOR_IMPL_EPOLL, SELECTOR_IMPL): new constants.
(openSelector): return kqueue selector if available.
* gnu/java/nio/ServerSocketChannelImpl.java: implement
`VMChannelOwner.'
(channel): new field.
(<init>): init `channel.'
(finalizer): check if the `VMChannel.State' is valid.
(implCloseSelectableChannel): use `VMChannel.close.'
(implConfigureBlocking): use `VMChannel.setBlocking.'
(accept): use `VMChannel.accept.'
(getVMChannel): new method.
* gnu/java/nio/ServerSocketChannelSelectionKey.java (getNativeFD):
access native FD through `VMChannel.State.'
* gnu/java/nio/SocketChannelImpl.java: implement `VMChannelOwner.'
(impl): removed.
(channel, connected, connectAddress): new field.
(<init>): new constructors.
(getPlainSocketImpl): removed.
(implCloseSelectableChannel): use `VMChannel.close.'
(implConfigureBlocking): use `VMChannel.setBlocking.'
(connect): use `connect(SocketAddress,int).'
(connect): use `VMChannel.connect.'
(finishConnect): don't use a selector.
(isConnected): use `VMChannel.getPeerAddress.'
(read): use `VMChannel.read.'
(read): use `VMChannel.readScattering.'
(write): use `VMChannel.write.'
(write): use `VMChannel.writeGathering.'
(getVMChannel): new method.
* gnu/java/nio/SocketChannelSelectionKey.java (getNativeFD): get
native FD from `VMChannel.State.'
* gnu/java/nio/SocketChannelSelectionKeyImpl.java (getNativeFD):
get native FD from `VMChannel.State.'
* gnu/java/nio/VMChannelOwner.java: new file.
* gnu/java/nio/channels/FileChannelImpl.java: removed.
* include/Makefile.am: generate `gnu_java_nio_FileChannelImpl.h'
and `gnu_java_nio_KqueueSelectorImpl.h;' don't generate
`gnu_java_nio_channels_FileChannelImpl.h.'
* include/gnu_java_net_VMPlainSocketImpl.h: regenerated.
* include/gnu_java_nio_FileChannelImpl.h: new file.
* include/gnu_java_nio_KqueueSelectorImpl.h: new file.
* include/gnu_java_nio_VMChannel.h: regenerated.
* include/gnu_java_nio_VMPipe.h: regenerated.
* include/java_net_VMNetworkInterface.h: regenerated.
* java/io/FileDescriptor.java: fix imports.
* java/io/FileInputStream.java (<init>): handle exceptions.
(read): wrap the destination arary.
* java/io/FileOutputStream.java (<init>): handle exceptions.
(write): wrap the source array.
* java/io/RandomAccessFile.java (<init>): handle exceptions.
* java/net/DatagramSocket.java (<init>): handle exceptions.
(receive): handle length/port setting.
(connect): bind to any address/port if the argument is null.
* java/net/NetworkInterface.java (name, inetAddress): removed.
(netif): new field.
(<init>): make private.
(getName): return `netif.name.'
(getInetAddresses): access `netif.addresses.'
(getDisplayName): return `netif.name.'
(getByName, getByAddress): handle changes to `VMNetworkInterface.'
(condense): removed.
(getNetworkInterfaces): handle changes to `VMNetworkInterface.'
(equals): compare `netif' fields.
(hashCode): get hash codes from `netif.'
(toString): use a StringBuffer.
* java/net/ServerSocket.java (close): don't set `impl' to null.
(isClosed): use `VMChannel.State.isClosed.'
* java/net/Socket.java (getLocalAddress): don't use `getOption' if
the `SocketImpl' is a `PlainSocketImpl.'
(close): just close the `impl.'
(toString): use `super.toString' in the value we return.
(isConnected): just access `impl,' not `getImpl.'
(isBound): use `PlainSocketImpl' methods if we can.
(isClosed): look at `VMChannel.State.'
* native/jni/classpath/jcl.c (JNI_OnLoad): new function.
(JCL_NewRawDataObject): don't initialize cached fields here; throw
an exception if they were not.
(JCL_GetRawData): throw an exception if cached fields weren't
created.
* native/jni/java-lang/java_lang_VMProcess.c: handle
FileChannelImpl move.
* native/jni/java-net/gnu_java_net_VMPlainSocketImpl.c
(IO_EXCEPTION, SOCKET_EXCEPTION, BIND_EXCEPTION,
THROW_NO_NETWORK): new macros.
(Java_gnu_java_net_VMPlainSocketImpl_bind): reipmlemented.
(Java_gnu_java_net_VMPlainSocketImpl_bind6): new function.
(Java_gnu_java_net_VMPlainSocketImpl_listen): reimplemented.
(java_sockopt): new enum.
(Java_gnu_java_net_VMPlainSocketImpl_setOption): reimplemented.
(Java_gnu_java_net_VMPlainSocketImpl_getOption): reimplemented.
(Java_gnu_java_net_VMPlainSocketImpl_shutdownInput):
reimplemented.
(Java_gnu_java_net_VMPlainSocketImpl_shutdownOutput):
reimplemented.
(Java_gnu_java_net_VMPlainSocketImpl_sendUrgentData): new
function.
(Java_gnu_java_net_VMPlainSocketImpl_join): new function.
(Java_gnu_java_net_VMPlainSocketImpl_join6): new function.
(Java_gnu_java_net_VMPlainSocketImpl_read): removed.
(Java_gnu_java_net_VMPlainSocketImpl_leave): new function.
(Java_gnu_java_net_VMPlainSocketImpl_leave6): new function.
(Java_gnu_java_net_VMPlainSocketImpl_joinGroup): new function.
(Java_gnu_java_net_VMPlainSocketImpl_write): removed.
(Java_gnu_java_net_VMPlainSocketImpl_joinGroup6): new function.
(Java_gnu_java_net_VMPlainSocketImpl_leaveGroup): new function.
(Java_gnu_java_net_VMPlainSocketImpl_leaveGroup6): new function.
(getif_address): new function.
(getif_index): new function.
* native/jni/java-net/java_net_VMNetworkInterface.c
(java_net_VMNetworkInterface_init,
java_net_VMNetworkInterface_addAddress): new file-scope globals.
(Java_java_net_VMNetworkInterface_initIds): new function.
(struct netif_entry): new struct.
(free_netif_list): new function.
(Java_java_net_VMNetworkInterface_getInterfaces): removed.
(Java_java_net_VMNetworkInterface_getVMInterfaces): new function.
* native/jni/java-nio/Makefile.am (libjavanio_la_SOURCES): remove
gnu_java_nio_channels_FileChannelImpl.c, add
gnu_java_nio_KqueueSelectorImpl.c.
* native/jni/java-nio/gnu_java_nio_KqueueSelectorImpl.c: new file.
* native/jni/java-nio/gnu_java_nio_VMChannel.c
(INTERRUPTED_IO_EXCEPTION, SOCKET_TIMEOUT_EXCEPTION, ALIGN_UP,
ALIGN_DOWN): new macros.
(JCL_init_buffer): get the address through GetDirectBufferAddress
if possible.
(Java_gnu_java_nio_VMChannel_stdin_1fd,
Java_gnu_java_nio_VMChannel_stdout_1fd,
Java_gnu_java_nio_VMChannel_stderr_1fd): new functions.
(Java_gnu_java_nio_VMChannel_setBlocking): fix setting blocking
value.
(Java_gnu_java_nio_VMChannel_read): renamed...
(Java_gnu_java_nio_VMChannel_read__ILjava_nio_ByteBuffer_2): to
this; handle interrupted IO; add HAVE_READ check.
(Java_gnu_java_nio_VMChannel_write): renamed...
(Java_gnu_java_nio_VMChannel_write__ILjava_nio_ByteBuffer_2): to
this; handle zero-length write; add HAVE_WRITE check.
(Java_gnu_java_nio_VMChannel_receive): new function.
(Java_gnu_java_nio_VMChannel_send): new function.
(Java_gnu_java_nio_VMChannel_send6): new function.
(Java_gnu_java_nio_VMChannel_read__I): new function.
(Java_gnu_java_nio_VMChannel_write__II): new function.
(Java_gnu_java_nio_VMChannel_socket): new function.
(Java_gnu_java_nio_VMChannel_connect): new function.
(Java_gnu_java_nio_VMChannel_connect6): new function.
(Java_gnu_java_nio_VMChannel_getsockname): new function.
(Java_gnu_java_nio_VMChannel_getpeername): new function.
(Java_gnu_java_nio_VMChannel_accept): new function.
(Java_gnu_java_nio_VMChannel_disconnect): new function.
(Java_gnu_java_nio_VMChannel_close): new function.
(Java_gnu_java_nio_VMChannel_available): new function.
(FileChannel_mode): new enum.
(Java_gnu_java_nio_VMChannel_open): new function.
(Java_gnu_java_nio_VMChannel_position): new function.
(Java_gnu_java_nio_VMChannel_seek): new function.
(Java_gnu_java_nio_VMChannel_truncate): new funciton.
(Java_gnu_java_nio_VMChannel_lock): new function.
(Java_gnu_java_nio_VMChannel_unlock): new function.
(Java_gnu_java_nio_VMChannel_size): new function.
(Java_gnu_java_nio_VMChannel_map): new function.
(Java_gnu_java_nio_VMChannel_flush): new function.
* native/jni/java-nio/gnu_java_nio_VMPipe.c
(Java_gnu_java_nio_VMPipe_init): removed.
(Java_gnu_java_nio_VMPipe_pipe0): new function.
* native/jni/java-nio/javanio.c: new file.
* native/jni/java-nio/javanio.h: new file.
* native/jni/native-lib/cpnet.c (cpnet_getHostByName): fix for
systems without `gethostbyname_r.'
* vm/reference/gnu/java/net/VMPlainSocketImpl.java (nfd): new
field.
(<init>, <init>): new constructors.
(setOption, getOption): make instance methods; defer to native
implementation.
(connect): removed.
(bind): make an instance method; defer to native methods.
(accept): removed.
(available): removed.
(listen): make an instance method; defer to native method.
(read): removed.
(join, leave): new methods.
(write): removed.
(joinGroup, leaveGroup): new methods.
(shutdownInput, shutdownOutput): make instance methods.
(sendUrgentData): removed.
(State): new class.
* vm/reference/gnu/java/nio/VMChannel.java: make final.
(fd): removed.
(nfd): new field.
(<init>): new, public constructors.
(getVMChannel): methods removed.
(getState, getStdin, getStdout, getStderr, stdin_fd, stdout_fd,
stderr_fd): new methods.
(setBlocking): make an instance method.
(available): new method.
(read): get native fd from `nfd.'
(read): new single-byte read method.
(readScattering): get native fd from `nfd.'
(receive): new method.
(write, writeGathering): get native fd from `nfd.'
(send): new method.
(write): new single-byte write method.
(initSocket): new method.
(connect): new method.
(disconnect): new method.
(getLocalAddress): new method.
(getPeerAddress): new method.
(accept): new method.
(openFile): new method.
(position): new method.
(seek): new method.
(truncate): new method.
(lock): new method.
(unlock): new method.
(size): new method.
(map): new method.
(flush): new method.
(close): new method.
(State): new class.
(Kind): new class.
* vm/reference/gnu/java/nio/VMPipe.java (init): removed.
(pipe, pipe0): new method.
* vm/reference/java/net/VMNetworkInterface.java (name, addresses):
new fields.
(<clinit>): call `initIds.'
(initIds): new method.
(getInterfaces): removed.
(getVMInterfaces): new method.
(addAddress): new method.
* vm/reference/java/nio/channels/VMChannels.java: fix imports.
Diffstat (limited to 'gnu/java/nio/SocketChannelImpl.java')
| -rw-r--r-- | gnu/java/nio/SocketChannelImpl.java | 251 |
1 files changed, 86 insertions, 165 deletions
diff --git a/gnu/java/nio/SocketChannelImpl.java b/gnu/java/nio/SocketChannelImpl.java index 680eba2f9..459decf52 100644 --- a/gnu/java/nio/SocketChannelImpl.java +++ b/gnu/java/nio/SocketChannelImpl.java @@ -39,15 +39,20 @@ exception statement from your version. */ package gnu.java.nio; import gnu.java.net.PlainSocketImpl; +import gnu.java.net.VMPlainSocketImpl; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketAddress; +import java.net.SocketException; import java.net.SocketTimeoutException; import java.nio.ByteBuffer; +import java.nio.ReadOnlyBufferException; import java.nio.channels.AlreadyConnectedException; import java.nio.channels.ClosedChannelException; import java.nio.channels.ConnectionPendingException; @@ -61,28 +66,57 @@ import java.nio.channels.UnsupportedAddressTypeException; import java.nio.channels.spi.SelectorProvider; public final class SocketChannelImpl extends SocketChannel + implements VMChannelOwner { - private PlainSocketImpl impl; + private VMChannel channel; + //private PlainSocketImpl impl; private NIOSocket socket; private boolean connectionPending; + private boolean connected; + private InetSocketAddress connectAddress; + + public SocketChannelImpl(boolean create) throws IOException + { + // XXX consider adding security check; this is used by + // PlainSocketImpl. + this(new SelectorProviderImpl(), create); + } + + public SocketChannelImpl(VMChannel channel) throws IOException + { + this(new SelectorProviderImpl(), channel, false); + } + + SocketChannelImpl(SelectorProvider provider) throws IOException + { + this(provider, true); + } - SocketChannelImpl (SelectorProvider provider) + SocketChannelImpl(SelectorProvider provider, boolean create) + throws IOException + { + this(provider, new VMChannel(), create); + } + + SocketChannelImpl(SelectorProvider provider, VMChannel channel, boolean create) throws IOException { super (provider); - impl = new PlainSocketImpl(); - socket = new NIOSocket (impl, this); + this.channel = channel; + if (create) + channel.initSocket(true); + socket = new NIOSocket(this); configureBlocking(true); } - SocketChannelImpl (SelectorProvider provider, + /*SocketChannelImpl (SelectorProvider provider, NIOSocket socket) throws IOException { super (provider); this.impl = socket.getPlainSocketImpl(); this.socket = socket; - } + }*/ public void finalizer() { @@ -98,23 +132,28 @@ public final class SocketChannelImpl extends SocketChannel } } - PlainSocketImpl getPlainSocketImpl() - { - return impl; - } + //PlainSocketImpl getPlainSocketImpl() + //{ + // return null; // XXX + //} - protected void implCloseSelectableChannel () throws IOException + protected void implCloseSelectableChannel() throws IOException { - socket.close(); + channel.close(); } protected void implConfigureBlocking (boolean blocking) throws IOException { - socket.setSoTimeout (blocking ? 0 : NIOConstants.DEFAULT_TIMEOUT); + channel.setBlocking(blocking); } public boolean connect (SocketAddress remote) throws IOException { + return connect(remote, 0); + } + + public boolean connect (SocketAddress remote, int timeout) throws IOException + { if (!isOpen()) throw new ClosedChannelException(); @@ -126,40 +165,15 @@ public final class SocketChannelImpl extends SocketChannel if (!(remote instanceof InetSocketAddress)) throw new UnsupportedAddressTypeException(); + + connectAddress = (InetSocketAddress) remote; - if (((InetSocketAddress) remote).isUnresolved()) + if (connectAddress.isUnresolved()) throw new UnresolvedAddressException(); - try - { - socket.getPlainSocketImpl().setInChannelOperation(true); - // indicate that a channel is initiating the accept operation - // so that the socket ignores the fact that we might be in - // non-blocking mode. - - if (isBlocking()) - { - // Do blocking connect. - socket.connect (remote); - return true; - } - - // Do non-blocking connect. - try - { - socket.connect (remote, NIOConstants.DEFAULT_TIMEOUT); - return true; - } - catch (SocketTimeoutException e) - { - connectionPending = true; - return false; - } - } - finally - { - socket.getPlainSocketImpl().setInChannelOperation(false); - } + connected = channel.connect(connectAddress, timeout); + connectionPending = !connected; + return connected; } public boolean finishConnect () @@ -168,37 +182,30 @@ public final class SocketChannelImpl extends SocketChannel if (!isOpen()) throw new ClosedChannelException(); - if (!isConnected() && !connectionPending) - throw new NoConnectionPendingException(); - if (isConnected()) - return true; - - // FIXME: Handle blocking/non-blocking mode. - - Selector selector = provider().openSelector(); - register(selector, SelectionKey.OP_CONNECT); - - if (isBlocking()) { - selector.select(); // blocking until channel is connected. connectionPending = false; return true; } - - int ready = selector.selectNow(); // non-blocking - if (ready == 1) - { - connectionPending = false; - return true; - } - + + if (!connectionPending) + throw new NoConnectionPendingException(); + return false; } - public boolean isConnected () + public boolean isConnected() { - return socket.isConnected(); + try + { + InetSocketAddress remote = channel.getPeerAddress(); + return remote != null; + } + catch (IOException ioe) + { + ioe.printStackTrace(System.out); + return false; + } } public boolean isConnectionPending () @@ -216,52 +223,7 @@ public final class SocketChannelImpl extends SocketChannel if (!isConnected()) throw new NotYetConnectedException(); - byte[] data; - int offset = 0; - InputStream input = socket.getInputStream(); - int available = input.available(); - int len = dst.remaining(); - - if ((! isBlocking()) && available == 0) - return 0; - - if (dst.hasArray()) - { - offset = dst.arrayOffset() + dst.position(); - data = dst.array(); - } - else - { - data = new byte [len]; - } - - int readBytes = 0; - boolean completed = false; - - try - { - begin(); - socket.getPlainSocketImpl().setInChannelOperation(true); - readBytes = input.read (data, offset, len); - completed = true; - } - finally - { - end (completed); - socket.getPlainSocketImpl().setInChannelOperation(false); - } - - if (readBytes > 0) - if (dst.hasArray()) - { - dst.position (dst.position() + readBytes); - } - else - { - dst.put (data, offset, readBytes); - } - - return readBytes; + return channel.read(dst); } public long read (ByteBuffer[] dsts, int offset, int length) @@ -275,61 +237,19 @@ public final class SocketChannelImpl extends SocketChannel || (length < 0) || (length > (dsts.length - offset))) throw new IndexOutOfBoundsException(); - - long readBytes = 0; - - for (int index = offset; index < length; index++) - readBytes += read (dsts [index]); - - return readBytes; + + return channel.readScattering(dsts, offset, length); } - public int write (ByteBuffer src) - throws IOException + public int write(ByteBuffer src) throws IOException { if (!isConnected()) throw new NotYetConnectedException(); - - byte[] data; - int offset = 0; - int len = src.remaining(); - - if (!src.hasArray()) - { - data = new byte [len]; - src.get (data, 0, len); - } - else - { - offset = src.arrayOffset() + src.position(); - data = src.array(); - } - - OutputStream output = socket.getOutputStream(); - boolean completed = false; - - try - { - begin(); - socket.getPlainSocketImpl().setInChannelOperation(true); - output.write (data, offset, len); - completed = true; - } - finally - { - end (completed); - socket.getPlainSocketImpl().setInChannelOperation(false); - } - if (src.hasArray()) - { - src.position (src.position() + len); - } - - return len; + return channel.write(src); } - public long write (ByteBuffer[] srcs, int offset, int length) + public long write(ByteBuffer[] srcs, int offset, int length) throws IOException { if (!isConnected()) @@ -340,12 +260,13 @@ public final class SocketChannelImpl extends SocketChannel || (length < 0) || (length > (srcs.length - offset))) throw new IndexOutOfBoundsException(); - - long writtenBytes = 0; - - for (int index = offset; index < length; index++) - writtenBytes += write (srcs [index]); - return writtenBytes; + return channel.writeGathering(srcs, offset, length); + } + + public VMChannel getVMChannel() + { + // XXX security check? + return channel; } } |
