0 import static java.io.File.createTempFile;
1 import static java.lang.Long.parseLong;
2 import static java.lang.System.getProperty;
3 import static java.lang.management.ManagementFactory.getOperatingSystemMXBean;
4 import static java.nio.file.Files.readAllBytes;
5 import static java.nio.file.Files.readSymbolicLink;
6 import static java.util.Arrays.stream;
7 import static java.util.stream.Collectors.joining;
8 import static jdk.test.lib.process.ProcessTools.createJavaProcessBuilder;
9
10 import java.io.File;
11 import java.io.IOException;
12
13 import com.sun.management.UnixOperatingSystemMXBean;
14
15 /*
16 * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
17 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
18 *
19 * This code is free software; you can redistribute it and/or modify it
20 * under the terms of the GNU General Public License version 2 only, as
21 * published by the Free Software Foundation.
22 *
23 * This code is distributed in the hope that it will be useful, but WITHOUT
24 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
25 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
26 * version 2 for more details (a copy is included in the LICENSE file that
27 * accompanied this code).
28 *
29 * You should have received a copy of the GNU General Public License version
30 * 2 along with this work; if not, write to the Free Software Foundation,
|
0 import static java.io.File.createTempFile;
1 import static java.lang.Long.parseLong;
2 import static java.lang.System.getProperty;
3 import static java.lang.management.ManagementFactory.getOperatingSystemMXBean;
4 import static java.nio.file.Files.readAllBytes;
5 import static java.nio.file.Files.readSymbolicLink;
6 import static java.util.Arrays.stream;
7 import static java.util.Optional.empty;
8 import static java.util.Optional.of;
9 import static java.util.stream.Collectors.joining;
10 import static jdk.test.lib.process.ProcessTools.createJavaProcessBuilder;
11
12 import java.io.File;
13 import java.io.FileNotFoundException;
14 import java.io.FileOutputStream;
15 import java.io.IOException;
16 import java.util.Optional;
17
18 import com.sun.management.UnixOperatingSystemMXBean;
19
20 /*
21 * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
22 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
23 *
24 * This code is free software; you can redistribute it and/or modify it
25 * under the terms of the GNU General Public License version 2 only, as
26 * published by the Free Software Foundation.
27 *
28 * This code is distributed in the hope that it will be useful, but WITHOUT
29 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
30 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
31 * version 2 for more details (a copy is included in the LICENSE file that
32 * accompanied this code).
33 *
34 * You should have received a copy of the GNU General Public License version
35 * 2 along with this work; if not, write to the Free Software Foundation,
|
106 ProcessBuilder pb = createJavaProcessBuilder(
107 "-Dtest.jdk=" + getProperty("test.jdk"),
108 VMShouldNotInheritFileDescriptors.class.getName(),
109 args[0],
110 "" + ProcessHandle.current().pid(),
111 "" + (supportsUnixMXBean()?+unixNrFD():-1));
112 pb.inheritIO(); // in future, redirect information from third VM to first VM
113 pb.start();
114
115 findOpenLogFile();
116 }
117 }
118
119 static class VMShouldNotInheritFileDescriptors {
120 // third VM
121 public static void main(String[] args) throws InterruptedException {
122 File logFile = new File(args[0]);
123 long parentPid = parseLong(args[1]);
124 long parentFDCount = parseLong(args[2]);
125
126 if(supportsUnixMXBean()){
127 long thisFDCount = unixNrFD();
128 System.out.println("This VM FD-count ("
129 + thisFDCount
130 + ") should be strictly less than parent VM FD-count ("
131 + parentFDCount
132 + ") as log file should have been closed, HOWEVER, THIS CAN NOT BE RELIED"
133 + " ON as files in /proc and /sys is opened by the JVM");
134 System.out.println(findOpenLogFile()?LEAKS_FD:RETAINS_FD);
135 } else if (getProperty("os.name").toLowerCase().contains("win")) {
136 windows(logFile, parentPid);
137 } else {
138 System.out.println(LEAKS_FD); // default fail on unknown configuration
139 }
140 System.out.println(EXIT);
141 }
142 }
143
144 static boolean supportsUnixMXBean() {
145 return getOperatingSystemMXBean() instanceof UnixOperatingSystemMXBean;
146 }
147
148 static long unixNrFD() {
149 UnixOperatingSystemMXBean osBean = (UnixOperatingSystemMXBean) getOperatingSystemMXBean();
150 return osBean.getOpenFileDescriptorCount();
151 }
152
153 static File linkTarget(File f) {
154 try {
155 return readSymbolicLink(f.toPath()).toFile();
156 } catch (IOException e) {
157 return new File("Error: could not read symbolic link (last link can not be read as it points to the /proc/self/
158 }
159 }
160
161 static boolean findOpenLogFile() {
162 File dir = new File("/proc/self/fd");
163
164 System.out.println("Open file descriptors:\n" + stream(dir.listFiles())
165 .map(f -> "###" + f.getAbsolutePath() + " -> " + linkTarget(f))
166 .collect(joining("\n")));
167
168 return stream(dir.listFiles())
169 .map(TestInheritFD::linkTarget)
170 .filter(f -> f.getName().endsWith(LOG_SUFFIX))
171 .findAny()
172 .isPresent();
173 }
174
175 static void windows(File f, long parentPid) throws InterruptedException {
176 System.out.println("waiting for pid: " + parentPid);
177 ProcessHandle.of(parentPid).ifPresent(handle -> handle.onExit().join());
178 System.out.println("trying to rename file to the same name: " + f);
179 System.out.println(f.renameTo(f)?RETAINS_FD:LEAKS_FD); // this parts communicates a closed file descriptor by print
180 }
|
111 ProcessBuilder pb = createJavaProcessBuilder(
112 "-Dtest.jdk=" + getProperty("test.jdk"),
113 VMShouldNotInheritFileDescriptors.class.getName(),
114 args[0],
115 "" + ProcessHandle.current().pid(),
116 "" + (supportsUnixMXBean()?+unixNrFD():-1));
117 pb.inheritIO(); // in future, redirect information from third VM to first VM
118 pb.start();
119
120 findOpenLogFile();
121 }
122 }
123
124 static class VMShouldNotInheritFileDescriptors {
125 // third VM
126 public static void main(String[] args) throws InterruptedException {
127 File logFile = new File(args[0]);
128 long parentPid = parseLong(args[1]);
129 long parentFDCount = parseLong(args[2]);
130
131 fakeLeakyJVM(false);
132
133 if(supportsUnixMXBean()){
134 long thisFDCount = unixNrFD();
135 System.out.println("This VM FD-count ("
136 + thisFDCount
137 + ") should be strictly less than parent VM FD-count ("
138 + parentFDCount
139 + ") as log file should have been closed, HOWEVER, THIS CAN NOT BE RELIED"
140 + " ON as files in /proc and /sys are opened by the JVM");
141 System.out.println(findOpenLogFile() ? LEAKS_FD : RETAINS_FD);
142 } else if (getProperty("os.name").toLowerCase().contains("win")) {
143 windows(logFile, parentPid);
144 } else {
145 System.out.println(LEAKS_FD); // default fail on unknown configuration
146 }
147 System.out.println(EXIT);
148 }
149 }
150
151 static boolean supportsUnixMXBean() {
152 return getOperatingSystemMXBean() instanceof UnixOperatingSystemMXBean;
153 }
154
155 static long unixNrFD() {
156 UnixOperatingSystemMXBean osBean = (UnixOperatingSystemMXBean) getOperatingSystemMXBean();
157 return osBean.getOpenFileDescriptorCount();
158 }
159
160 static Optional<String> linkTargetName(File f) {
161 try {
162 return of(readSymbolicLink(f.toPath()).toFile().getName());
163 } catch (IOException e) {
164 return empty();
165 }
166 }
167
168 @SuppressWarnings("resource")
169 static void fakeLeakyJVM(boolean fake) {
170 if (fake) {
171 try {
172 new FileOutputStream("fakeLeakyJVM" + LOG_SUFFIX, false);
173 } catch (FileNotFoundException e) {
174 }
175 }
176 }
177
178 static boolean findOpenLogFile() {
179 File dir = new File("/proc/self/fd");
180
181 System.out.println("Open file descriptors:\n" + stream(dir.listFiles())
182 .map(f -> f.getAbsolutePath() + " maps to: " + linkTargetName(f).orElse("?"))
183 .collect(joining("\n")));
184
185 return stream(dir.listFiles())
186 .map(TestInheritFD::linkTargetName)
187 .flatMap(Optional::stream)
188 .filter(fileName -> fileName.endsWith(LOG_SUFFIX))
189 .findAny()
190 .isPresent();
191 }
192
193 static void windows(File f, long parentPid) throws InterruptedException {
194 System.out.println("waiting for pid: " + parentPid);
195 ProcessHandle.of(parentPid).ifPresent(handle -> handle.onExit().join());
196 System.out.println("trying to rename file to the same name: " + f);
197 System.out.println(f.renameTo(f) ? RETAINS_FD : LEAKS_FD); // this parts communicates a closed file descriptor by p
198 }
|