SocketInheritance.java revision 2546:eb84b89ef3ff
1/* 2 * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24/* 25 * @test 26 * @summary Sockets shouldn't be inherited when creating a child process 27 */ 28import java.nio.ByteBuffer; 29import java.nio.channels.*; 30import java.net.*; 31import java.io.*; 32 33public class SocketInheritance { 34 35 /* 36 * Simple helper class to direct process output to the parent 37 * System.out 38 */ 39 static class IOHandler implements Runnable { 40 InputStream in; 41 42 IOHandler(InputStream in) { 43 this.in = in; 44 } 45 46 static void handle(InputStream in) { 47 IOHandler handler = new IOHandler(in); 48 Thread thr = new Thread(handler); 49 thr.setDaemon(true); 50 thr.start(); 51 } 52 53 public void run() { 54 try { 55 byte b[] = new byte[100]; 56 for (;;) { 57 int n = in.read(b); 58 if (n < 0) return; 59 System.out.write(b, 0, n); 60 } 61 } catch (IOException ioe) { } 62 } 63 64 } 65 66 // connect to the given port 67 static SocketChannel connect(int port) throws IOException { 68 InetAddress lh = InetAddress.getByName("127.0.0.1"); 69 InetSocketAddress isa = new InetSocketAddress(lh, port); 70 return SocketChannel.open(isa); 71 } 72 73 // simple child process that handshakes with the parent and then 74 // waits indefinitely until it is destroyed 75 static void child(int port) { 76 try { 77 connect(port).close(); 78 } catch (IOException x) { 79 x.printStackTrace(); 80 return; 81 } 82 83 for (;;) { 84 try { 85 Thread.sleep(10*1000); 86 } catch (InterruptedException x) { } 87 } 88 } 89 90 91 // Creates a loopback connection. 92 // Forks process which should not inherit the sockets. 93 // Close the sockets, and attempt to re-bind the listener. 94 95 static void start() throws Exception { 96 97 // setup loopback connection 98 ServerSocketChannel ssc = ServerSocketChannel.open(); 99 ssc.socket().bind( new InetSocketAddress(0) ); 100 101 int port = ssc.socket().getLocalPort(); 102 103 SocketChannel sc1 = connect(port); 104 SocketChannel sc2 = ssc.accept(); 105 106 // launch the child 107 String cmd = System.getProperty("java.home") + File.separator + "bin" + 108 File.separator + "java"; 109 String testClasses = System.getProperty("test.classes"); 110 if (testClasses != null) 111 cmd += " -cp " + testClasses; 112 cmd += " SocketInheritance -child " + port; 113 114 Process p = Runtime.getRuntime().exec(cmd); 115 116 IOHandler.handle(p.getInputStream()); 117 IOHandler.handle(p.getErrorStream()); 118 119 // wait for child to connect 120 SocketChannel sc3 = ssc.accept(); 121 122 // close sockets 123 sc1.close(); 124 sc2.close(); 125 sc3.close(); 126 ssc.close(); 127 128 // re-bind the listener - if the sockets were inherited then 129 // this will fail 130 try { 131 ssc = ServerSocketChannel.open(); 132 ssc.socket().bind(new InetSocketAddress(port)); 133 ssc.close(); 134 } finally { 135 p.destroy(); 136 } 137 138 } 139 140 public static void main(String[] args) throws Exception { 141 if (!System.getProperty("os.name").startsWith("Windows")) 142 return; 143 144 if (args.length == 0) { 145 start(); 146 } else { 147 if (args[0].equals("-child")) { 148 child(Integer.parseInt(args[1])); 149 } 150 } 151 } 152} 153