001: /*
002: * Copyright 2002-2004 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: /*
027: * @(#)PipeImpl.java 1.14 07/05/05
028: */
029:
030: package sun.nio.ch;
031:
032: import java.io.IOException;
033: import java.net.InetAddress;
034: import java.net.InetSocketAddress;
035: import java.nio.*;
036: import java.nio.channels.*;
037: import java.nio.channels.spi.*;
038: import java.security.AccessController;
039: import java.security.PrivilegedExceptionAction;
040: import java.security.PrivilegedActionException;
041: import java.util.Random;
042:
043: /**
044: * A simple Pipe implementation based on a socket connection.
045: */
046:
047: class PipeImpl extends Pipe {
048:
049: // Source and sink channels
050: private SourceChannel source;
051: private SinkChannel sink;
052:
053: // Random object for handshake values
054: private static final Random rnd;
055:
056: static {
057: Util.load();
058: byte[] someBytes = new byte[8];
059: boolean resultOK = IOUtil.randomBytes(someBytes);
060: if (resultOK) {
061: rnd = new Random(ByteBuffer.wrap(someBytes).getLong());
062: } else {
063: rnd = new Random();
064: }
065: }
066:
067: private class Initializer implements PrivilegedExceptionAction {
068:
069: private final SelectorProvider sp;
070:
071: private Initializer(SelectorProvider sp) {
072: this .sp = sp;
073: }
074:
075: public Object run() throws IOException {
076: ServerSocketChannel ssc = null;
077: SocketChannel sc1 = null;
078: SocketChannel sc2 = null;
079:
080: try {
081: // loopback address
082: InetAddress lb = InetAddress.getByName("127.0.0.1");
083: assert (lb.isLoopbackAddress());
084:
085: // bind ServerSocketChannel to a port on the loopback address
086: ssc = ServerSocketChannel.open();
087: ssc.socket().bind(new InetSocketAddress(lb, 0));
088:
089: // Establish connection (assumes connections are eagerly
090: // accepted)
091: InetSocketAddress sa = new InetSocketAddress(lb, ssc
092: .socket().getLocalPort());
093: sc1 = SocketChannel.open(sa);
094:
095: ByteBuffer bb = ByteBuffer.allocate(8);
096: long secret = rnd.nextLong();
097: bb.putLong(secret).flip();
098: sc1.write(bb);
099:
100: // Get a connection and verify it is legitimate
101: for (;;) {
102: sc2 = ssc.accept();
103: bb.clear();
104: sc2.read(bb);
105: bb.rewind();
106: if (bb.getLong() == secret)
107: break;
108: sc2.close();
109: }
110:
111: // Create source and sink channels
112: source = new SourceChannelImpl(sp, sc1);
113: sink = new SinkChannelImpl(sp, sc2);
114: } catch (IOException e) {
115: try {
116: if (sc1 != null)
117: sc1.close();
118: if (sc2 != null)
119: sc2.close();
120: } catch (IOException e2) {
121: }
122: IOException x = new IOException("Unable to establish"
123: + " loopback connection");
124: x.initCause(e);
125: throw x;
126: } finally {
127: try {
128: if (ssc != null)
129: ssc.close();
130: } catch (IOException e2) {
131: }
132: }
133: return null;
134: }
135: }
136:
137: PipeImpl(final SelectorProvider sp) throws IOException {
138: try {
139: AccessController.doPrivileged(new Initializer(sp));
140: } catch (PrivilegedActionException x) {
141: throw (IOException) x.getCause();
142: }
143: }
144:
145: public SourceChannel source() {
146: return source;
147: }
148:
149: public SinkChannel sink() {
150: return sink;
151: }
152:
153: }
|