blob: 41df8132d9f125ffb6abc1eb268084a5137ee287 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any 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 SocketInheritance -child " + port;
109
110 Process p = Runtime.getRuntime().exec(cmd);
111
112 IOHandler.handle(p.getInputStream());
113 IOHandler.handle(p.getErrorStream());
114
115 // wait for child to connect
116 SocketChannel sc3 = ssc.accept();
117
118 // close sockets
119 sc1.close();
120 sc2.close();
121 sc3.close();
122 ssc.close();
123
124 // re-bind the listener - if the sockets were inherited then
125 // this will fail
126 try {
127 ssc = ServerSocketChannel.open();
128 ssc.socket().bind(new InetSocketAddress(port));
129 ssc.close();
130 } finally {
131 p.destroy();
132 }
133
134 }
135
136 public static void main(String[] args) throws Exception {
137 if (!System.getProperty("os.name").startsWith("Windows"))
138 return;
139
140 if (args.length == 0) {
141 start();
142 } else {
143 if (args[0].equals("-child")) {
144 child(Integer.parseInt(args[1]));
145 }
146 }
147 }
148}