/* * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code 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 * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ /* * @test * @bug 8067105 * @summary Socket returned by ServerSocket.accept() is inherited by child process on Windows * @author Chris Hegarty */ import java.io.*; import java.net.*; import java.nio.channels.ServerSocketChannel; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; public class AcceptInheritHandle { enum ServerSocketProducer { JAVA_NET(() -> { try { return new ServerSocket(); } catch(IOException x) { throw new UncheckedIOException(x); } }), NIO_CHANNELS(() -> { try { return ServerSocketChannel.open().socket(); } catch (IOException x) { throw new UncheckedIOException(x); } }); final Supplier<ServerSocket> supplier; ServerSocketProducer(Supplier<ServerSocket> supplier) { this.supplier = supplier; } Supplier<ServerSocket> supplier () { return supplier; } } static final String JAVA = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java"; static final String CLASSPATH = System.getProperty("java.class.path"); public static void main(String[] args) throws Exception { if (args.length == 1) server(ServerSocketProducer.valueOf(args[0])); else mainEntry(); } static void mainEntry() throws Exception { testJavaNetServerSocket(); testNioServerSocketChannel(); } static void testJavaNetServerSocket() throws Exception { test(ServerSocketProducer.JAVA_NET); test(ServerSocketProducer.JAVA_NET, "-Djava.net.preferIPv4Stack=true"); } static void testNioServerSocketChannel() throws Exception { test(ServerSocketProducer.NIO_CHANNELS); } static void test(ServerSocketProducer ssp, String... sysProps) throws Exception { System.out.println("\nStarting test for " + ssp.name()); List<String> commands = new ArrayList<>(); commands.add(JAVA); for (String prop : sysProps) commands.add(prop); commands.add("-cp"); commands.add(CLASSPATH); commands.add("AcceptInheritHandle"); commands.add(ssp.name()); System.out.println("Executing: "+ commands); ProcessBuilder pb = new ProcessBuilder(commands); pb.redirectError(ProcessBuilder.Redirect.INHERIT); Process serverProcess = pb.start(); DataInputStream dis = new DataInputStream(serverProcess.getInputStream()); int port = dis.readInt(); System.out.println("Server process listening on " + port + ", connecting..."); Socket socket = new Socket("localhost", port); String s = dis.readUTF(); System.out.println("Server process said " + s); serverProcess.destroy(); serverProcess.waitFor(30, TimeUnit.SECONDS); System.out.println("serverProcess exitCode:" + serverProcess.exitValue()); try { socket.setSoTimeout(10 * 1000); socket.getInputStream().read(); } catch (SocketTimeoutException x) { // failed throw new RuntimeException("Failed: should get reset, not " + x); } catch (SocketException x) { System.out.println("Expected:" + x); } } static void server(ServerSocketProducer producer) throws Exception { try (ServerSocket ss = producer.supplier().get()) { ss.bind(new InetSocketAddress(0)); int port = ss.getLocalPort(); DataOutputStream dos = new DataOutputStream(System.out); dos.writeInt(port); dos.flush(); ss.accept(); // do not close Runtime.getRuntime().exec("sleep 20"); Thread.sleep(3 * 1000); dos.writeUTF("kill me!"); dos.flush(); Thread.sleep(30 * 1000); } } }