From 6c3b10fb1d95fb03e2f7d988d4c772960af11c91 Mon Sep 17 00:00:00 2001 From: Roger Riggs Date: Mon, 27 Mar 2023 17:45:20 +0000 Subject: [PATCH] 8303485: Replacing os.name for operating system customization Reviewed-by: naoto, erikj, alanb --- make/modules/java.base/gensrc/GensrcMisc.gmk | 10 +- .../classes/java/lang/ProcessBuilder.java | 9 +- .../share/classes/java/util/zip/ZipFile.java | 7 +- .../classes/jdk/internal/foreign/CABI.java | 21 +-- .../jdk/internal/util/OperatingSystem.java | 124 ++++++++++++++++++ .../util/OperatingSystemProps.java.template | 46 +++++++ .../jdk/internal/util/StaticProperty.java | 22 ++++ .../classes/sun/launcher/LauncherHelper.java | 11 +- .../share/classes/sun/net/sdp/SdpSupport.java | 7 +- .../unix/classes/java/lang/ProcessImpl.java | 96 +++++--------- .../unix/classes/sun/net/PortConfig.java | 40 +++--- .../java/foreign/TestUnsupportedLinker.java | 6 +- test/jdk/jdk/internal/util/OSTest.java | 86 ++++++++++++ 13 files changed, 371 insertions(+), 114 deletions(-) create mode 100644 src/java.base/share/classes/jdk/internal/util/OperatingSystem.java create mode 100644 src/java.base/share/classes/jdk/internal/util/OperatingSystemProps.java.template create mode 100644 test/jdk/jdk/internal/util/OSTest.java diff --git a/make/modules/java.base/gensrc/GensrcMisc.gmk b/make/modules/java.base/gensrc/GensrcMisc.gmk index 3519b0216ae..b2bae11baa3 100644 --- a/make/modules/java.base/gensrc/GensrcMisc.gmk +++ b/make/modules/java.base/gensrc/GensrcMisc.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2023, 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 @@ -50,8 +50,14 @@ $(eval $(call SetupTextFileProcessing, BUILD_VERSION_JAVA, \ @@VENDOR_URL_VM_BUG@@ => $(VENDOR_URL_VM_BUG), \ )) -TARGETS += $(BUILD_VERSION_JAVA) +$(eval $(call SetupTextFileProcessing, BUILD_PLATFORMPROPERTIES_JAVA, \ + SOURCE_FILES := $(TOPDIR)/src/java.base/share/classes/jdk/internal/util/OperatingSystemProps.java.template, \ + OUTPUT_FILE := $(SUPPORT_OUTPUTDIR)/gensrc/java.base/jdk/internal/util/OperatingSystemProps.java, \ + REPLACEMENTS := \ + @@OPENJDK_TARGET_OS@@ => $(OPENJDK_TARGET_OS), \ +)) +TARGETS += $(BUILD_VERSION_JAVA) $(BUILD_PLATFORMPROPERTIES_JAVA) ################################################################################ ifneq ($(filter $(TOOLCHAIN_TYPE), gcc clang), ) diff --git a/src/java.base/share/classes/java/lang/ProcessBuilder.java b/src/java.base/share/classes/java/lang/ProcessBuilder.java index a7076ca4584..0b86dd507ac 100644 --- a/src/java.base/share/classes/java/lang/ProcessBuilder.java +++ b/src/java.base/share/classes/java/lang/ProcessBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2023, 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 @@ -25,6 +25,7 @@ package java.lang; +import jdk.internal.util.OperatingSystem; import java.io.File; import java.io.FileDescriptor; import java.io.IOException; @@ -35,7 +36,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; import jdk.internal.event.ProcessStartEvent; -import sun.security.action.GetPropertyAction; /** * This class is used to create operating system processes. @@ -469,9 +469,8 @@ public final class ProcessBuilder * @since 1.7 */ public abstract static class Redirect { - private static final File NULL_FILE = new File( - (GetPropertyAction.privilegedGetProperty("os.name") - .startsWith("Windows") ? "NUL" : "/dev/null") + private static final File NULL_FILE = + new File((OperatingSystem.isWindows() ? "NUL" : "/dev/null") ); /** diff --git a/src/java.base/share/classes/java/util/zip/ZipFile.java b/src/java.base/share/classes/java/util/zip/ZipFile.java index f6b3588c738..e1c02759cb1 100644 --- a/src/java.base/share/classes/java/util/zip/ZipFile.java +++ b/src/java.base/share/classes/java/util/zip/ZipFile.java @@ -63,7 +63,7 @@ import java.util.stream.StreamSupport; import jdk.internal.access.JavaUtilZipFileAccess; import jdk.internal.access.JavaUtilJarAccess; import jdk.internal.access.SharedSecrets; -import jdk.internal.misc.VM; +import jdk.internal.util.OperatingSystem; import jdk.internal.perf.PerfCounter; import jdk.internal.ref.CleanerFactory; import jdk.internal.vm.annotation.Stable; @@ -1085,8 +1085,6 @@ public class ZipFile implements ZipConstants, Closeable { } } - private static boolean isWindows; - static { SharedSecrets.setJavaUtilZipFileAccess( new JavaUtilZipFileAccess() { @@ -1133,7 +1131,6 @@ public class ZipFile implements ZipConstants, Closeable { } ); - isWindows = VM.getSavedProperty("os.name").contains("Windows"); } private static class Source { @@ -1321,7 +1318,7 @@ public class ZipFile implements ZipConstants, Closeable { this.zc = zc; this.key = key; if (toDelete) { - if (isWindows) { + if (OperatingSystem.isWindows()) { this.zfile = SharedSecrets.getJavaIORandomAccessFileAccess() .openAndDelete(key.file, "r"); } else { diff --git a/src/java.base/share/classes/jdk/internal/foreign/CABI.java b/src/java.base/share/classes/jdk/internal/foreign/CABI.java index fa1661ff5a6..a6dfba99533 100644 --- a/src/java.base/share/classes/jdk/internal/foreign/CABI.java +++ b/src/java.base/share/classes/jdk/internal/foreign/CABI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2023, 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 @@ -25,8 +25,10 @@ */ package jdk.internal.foreign; +import jdk.internal.util.OperatingSystem; +import jdk.internal.util.StaticProperty; + import static java.lang.foreign.ValueLayout.ADDRESS; -import static sun.security.action.GetPropertyAction.privilegedGetProperty; public enum CABI { SYS_V, @@ -38,32 +40,30 @@ public enum CABI { private static final CABI ABI; private static final String ARCH; - private static final String OS; private static final long ADDRESS_SIZE; static { - ARCH = privilegedGetProperty("os.arch"); - OS = privilegedGetProperty("os.name"); + ARCH = StaticProperty.osArch(); ADDRESS_SIZE = ADDRESS.bitSize(); // might be running in a 32-bit VM on a 64-bit platform. // addressSize will be correctly 32 if ((ARCH.equals("amd64") || ARCH.equals("x86_64")) && ADDRESS_SIZE == 64) { - if (OS.startsWith("Windows")) { + if (OperatingSystem.isWindows()) { ABI = WIN_64; } else { ABI = SYS_V; } } else if (ARCH.equals("aarch64")) { - if (OS.startsWith("Mac")) { + if (OperatingSystem.isMacOS()) { ABI = MAC_OS_AARCH_64; - } else if (OS.startsWith("Windows")) { + } else if (OperatingSystem.isWindows()) { ABI = WIN_AARCH_64; } else { // The Linux ABI follows the standard AAPCS ABI ABI = LINUX_AARCH_64; } } else if (ARCH.equals("riscv64")) { - if (OS.startsWith("Linux")) { + if (OperatingSystem.isLinux()) { ABI = LINUX_RISCV_64; } else { // unsupported @@ -78,7 +78,8 @@ public enum CABI { public static CABI current() { if (ABI == null) { throw new UnsupportedOperationException( - "Unsupported os, arch, or address size: " + OS + ", " + ARCH + ", " + ADDRESS_SIZE); + "Unsupported os, arch, or address size: " + OperatingSystem.current() + + ", " + ARCH + ", " + ADDRESS_SIZE); } return ABI; } diff --git a/src/java.base/share/classes/jdk/internal/util/OperatingSystem.java b/src/java.base/share/classes/jdk/internal/util/OperatingSystem.java new file mode 100644 index 00000000000..ad90483a65e --- /dev/null +++ b/src/java.base/share/classes/jdk/internal/util/OperatingSystem.java @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2023, 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. + */ +package jdk.internal.util; + +import jdk.internal.util.OperatingSystemProps; +import jdk.internal.vm.annotation.ForceInline; + +/** + * Enumeration of operating system types and testing for the current OS. + * The enumeration can be used to dispatch to OS specific code or values. + * Checking if a specific operating system is current uses a simple + * static method for each operating system. + *

+ * For example, + * {@snippet lang = "java": + * if (OperatingSystem.isWindows()) { + * // Windows only code. + * } else if (OperatingSystem.isLinux()) { + * // Linux only code + * } + *} + * + * Alternatively, compare with the {@linkplain #current() current} operating system. + * For example, + * {@snippet lang = "java": + * if (OperatingSystem.current() == OperatingSystem.WINDOWS) { + * // Windows only code. + * } + *} + * Dispatch based on the current operating system or choose a value. + * For example, + * {@snippet lang = "java": + * int port() { + * return switch(OperatingSystem.current()) { + * case LINUX->32768; + * case AIX->32768; + * case MACOS->49152; + * case WINDOWS->49152; + * }; + * } + *} + */ +public enum OperatingSystem { + + /** + * Operating systems based on the Linux kernel. + */ + LINUX, + /** + * The Mac OS X Operating system. + */ + MACOS, + /** + * The Windows Operating system. + */ + WINDOWS, + /** + * The AIX Operating system. + */ + AIX, + ; + + // Cache a copy of the array for lightweight indexing + private static final OperatingSystem[] osValues = OperatingSystem.values(); + + /** + * {@return {@code true} if built for the Linux operating system} + */ + @ForceInline + public static boolean isLinux() { + return OperatingSystemProps.TARGET_OS_IS_LINUX; + } + + /** + * {@return {@code true} if built for the Mac OS X operating system} + */ + @ForceInline + public static boolean isMacOS() { + return OperatingSystemProps.TARGET_OS_IS_MACOSX; + } + + /** + * {@return {@code true} if built for the Windows operating system} + */ + @ForceInline + public static boolean isWindows() { + return OperatingSystemProps.TARGET_OS_IS_WINDOWS; + } + + /** + * {@return {@code true} if built for the AIX operating system} + */ + @ForceInline + public static boolean isAix() { + return OperatingSystemProps.TARGET_OS_IS_AIX; + } + + /** + * {@return the current operating system} + */ + public static OperatingSystem current() { + return osValues[OperatingSystemProps.CURRENT_OS_ORDINAL]; + } +} diff --git a/src/java.base/share/classes/jdk/internal/util/OperatingSystemProps.java.template b/src/java.base/share/classes/jdk/internal/util/OperatingSystemProps.java.template new file mode 100644 index 00000000000..b7178675e2c --- /dev/null +++ b/src/java.base/share/classes/jdk/internal/util/OperatingSystemProps.java.template @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2023, 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. + */ +package jdk.internal.util; + +/** + * The corresponding source file is generated by GensrcMisc.gmk for java.base. + * @see OperatingSystem + */ +class OperatingSystemProps { + + // Unique integers named to match the build system naming of the build target + // The values must match the ordinals of the respective enum + private static final int TARGET_OS_linux = 0; + private static final int TARGET_OS_macosx = 1; + private static final int TARGET_OS_windows = 2; + private static final int TARGET_OS_aix = 3; + + // Index/ordinal of the current OperatingSystem enum as substituted by the build + static final int CURRENT_OS_ORDINAL = TARGET_OS_@@OPENJDK_TARGET_OS@@; + + // Precomputed booleans for each Operating System + static final boolean TARGET_OS_IS_LINUX = TARGET_OS_@@OPENJDK_TARGET_OS@@ == TARGET_OS_linux; + static final boolean TARGET_OS_IS_MACOSX = TARGET_OS_@@OPENJDK_TARGET_OS@@ == TARGET_OS_macosx; + static final boolean TARGET_OS_IS_WINDOWS = TARGET_OS_@@OPENJDK_TARGET_OS@@ == TARGET_OS_windows; + static final boolean TARGET_OS_IS_AIX = TARGET_OS_@@OPENJDK_TARGET_OS@@ == TARGET_OS_aix; +} diff --git a/src/java.base/share/classes/jdk/internal/util/StaticProperty.java b/src/java.base/share/classes/jdk/internal/util/StaticProperty.java index 10d062f1ab8..92004802f84 100644 --- a/src/java.base/share/classes/jdk/internal/util/StaticProperty.java +++ b/src/java.base/share/classes/jdk/internal/util/StaticProperty.java @@ -54,6 +54,8 @@ public final class StaticProperty { private static final String JAVA_PROPERTIES_DATE; private static final String SUN_JNU_ENCODING; private static final String JAVA_LOCALE_USE_OLD_ISO_CODES; + private static final String OS_NAME; + private static final String OS_ARCH; private StaticProperty() {} @@ -73,6 +75,8 @@ public final class StaticProperty { JAVA_PROPERTIES_DATE = getProperty(props, "java.properties.date", null); SUN_JNU_ENCODING = getProperty(props, "sun.jnu.encoding"); JAVA_LOCALE_USE_OLD_ISO_CODES = getProperty(props, "java.locale.useOldISOCodes", ""); + OS_NAME = getProperty(props, "os.name"); + OS_ARCH = getProperty(props, "os.arch"); } private static String getProperty(Properties props, String key) { @@ -243,4 +247,22 @@ public final class StaticProperty { public static String javaLocaleUseOldISOCodes() { return JAVA_LOCALE_USE_OLD_ISO_CODES; } + + /** + * {@return the {@code os.name} system property} + * {@link SecurityManager#checkPropertyAccess} is NOT checked + * in this method. This property is not considered security sensitive. + */ + public static String osName() { + return OS_NAME; + } + + /** + * {@return the {@code os.arch} system property} + * {@link SecurityManager#checkPropertyAccess} is NOT checked + * in this method. This property is not considered security sensitive. + */ + public static String osArch() { + return OS_ARCH; + } } diff --git a/src/java.base/share/classes/sun/launcher/LauncherHelper.java b/src/java.base/share/classes/sun/launcher/LauncherHelper.java index 22a889a3025..76609edc249 100644 --- a/src/java.base/share/classes/sun/launcher/LauncherHelper.java +++ b/src/java.base/share/classes/sun/launcher/LauncherHelper.java @@ -77,6 +77,7 @@ import java.util.jar.Manifest; import java.util.stream.Collectors; import java.util.stream.Stream; +import jdk.internal.util.OperatingSystem; import jdk.internal.misc.VM; import jdk.internal.module.ModuleBootstrap; import jdk.internal.module.Modules; @@ -168,7 +169,7 @@ public final class LauncherHelper { printLocale(); break; case "system": - if (System.getProperty("os.name").contains("Linux")) { + if (OperatingSystem.isLinux()) { printSystemMetrics(); break; } @@ -176,7 +177,7 @@ public final class LauncherHelper { printVmSettings(initialHeapSize, maxHeapSize, stackSize); printProperties(); printLocale(); - if (System.getProperty("os.name").contains("Linux")) { + if (OperatingSystem.isLinux()) { printSystemMetrics(); } break; @@ -532,7 +533,7 @@ public final class LauncherHelper { initOutput(printToStderr); ostream.println(getLocalizedMessage("java.launcher.X.usage", File.pathSeparator)); - if (System.getProperty("os.name").contains("OS X")) { + if (OperatingSystem.isMacOS()) { ostream.println(getLocalizedMessage("java.launcher.X.macosx.usage", File.pathSeparator)); } @@ -745,7 +746,7 @@ public final class LauncherHelper { Class c = null; try { c = Class.forName(m, mainClass); - if (c == null && System.getProperty("os.name", "").contains("OS X") + if (c == null && OperatingSystem.isMacOS() && Normalizer.isNormalized(mainClass, Normalizer.Form.NFD)) { String cn = Normalizer.normalize(mainClass, Normalizer.Form.NFC); @@ -789,7 +790,7 @@ public final class LauncherHelper { try { mainClass = Class.forName(cn, false, scl); } catch (NoClassDefFoundError | ClassNotFoundException cnfe) { - if (System.getProperty("os.name", "").contains("OS X") + if (OperatingSystem.isMacOS() && Normalizer.isNormalized(cn, Normalizer.Form.NFD)) { try { // On Mac OS X since all names with diacritical marks are diff --git a/src/java.base/share/classes/sun/net/sdp/SdpSupport.java b/src/java.base/share/classes/sun/net/sdp/SdpSupport.java index eab38bcbe53..5aa1ecaed8a 100644 --- a/src/java.base/share/classes/sun/net/sdp/SdpSupport.java +++ b/src/java.base/share/classes/sun/net/sdp/SdpSupport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2023, 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 @@ -30,7 +30,7 @@ import java.io.FileDescriptor; import jdk.internal.access.SharedSecrets; import jdk.internal.access.JavaIOFileDescriptorAccess; -import sun.security.action.GetPropertyAction; +import jdk.internal.util.OperatingSystem; /** @@ -39,8 +39,7 @@ import sun.security.action.GetPropertyAction; */ public final class SdpSupport { - private static final String os = GetPropertyAction.privilegedGetProperty("os.name"); - private static final boolean isSupported = os.equals("Linux"); + private static final boolean isSupported = OperatingSystem.isLinux(); private static final JavaIOFileDescriptorAccess fdAccess = SharedSecrets.getJavaIOFileDescriptorAccess(); diff --git a/src/java.base/unix/classes/java/lang/ProcessImpl.java b/src/java.base/unix/classes/java/lang/ProcessImpl.java index 898ec9f398c..3b302b23cd3 100644 --- a/src/java.base/unix/classes/java/lang/ProcessImpl.java +++ b/src/java.base/unix/classes/java/lang/ProcessImpl.java @@ -37,19 +37,17 @@ import java.io.InputStream; import java.io.OutputStream; import java.nio.charset.Charset; import java.util.Arrays; -import java.util.EnumSet; import java.util.Locale; -import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; import java.security.AccessController; -import java.security.PrivilegedAction; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; import jdk.internal.access.JavaIOFileDescriptorAccess; import jdk.internal.access.SharedSecrets; +import jdk.internal.util.OperatingSystem; import jdk.internal.util.StaticProperty; import sun.security.action.GetPropertyAction; @@ -92,65 +90,39 @@ final class ProcessImpl extends Process { VFORK } - private static enum Platform { - - LINUX(LaunchMechanism.POSIX_SPAWN, LaunchMechanism.VFORK, LaunchMechanism.FORK), - - BSD(LaunchMechanism.POSIX_SPAWN, LaunchMechanism.FORK), - - AIX(LaunchMechanism.POSIX_SPAWN, LaunchMechanism.FORK); - - final LaunchMechanism defaultLaunchMechanism; - final Set validLaunchMechanisms; - - Platform(LaunchMechanism ... launchMechanisms) { - this.defaultLaunchMechanism = launchMechanisms[0]; - this.validLaunchMechanisms = - EnumSet.copyOf(Arrays.asList(launchMechanisms)); + /** + * {@return the default or requested launch mechanism} + * @throws Error if the requested launch mechanism is not found or valid + */ + private static LaunchMechanism launchMechanism() { + String s = GetPropertyAction.privilegedGetProperty("jdk.lang.Process.launchMechanism"); + if (s == null) { + return LaunchMechanism.POSIX_SPAWN; } - @SuppressWarnings("removal") - LaunchMechanism launchMechanism() { - return AccessController.doPrivileged( - (PrivilegedAction) () -> { - String s = System.getProperty( - "jdk.lang.Process.launchMechanism"); - LaunchMechanism lm; - if (s == null) { - lm = defaultLaunchMechanism; - s = lm.name().toLowerCase(Locale.ROOT); - } else { - try { - lm = LaunchMechanism.valueOf( - s.toUpperCase(Locale.ROOT)); - } catch (IllegalArgumentException e) { - lm = null; - } + try { + // Should be value of a LaunchMechanism enum + LaunchMechanism lm = LaunchMechanism.valueOf(s.toUpperCase(Locale.ROOT)); + switch (OperatingSystem.current()) { + case LINUX: + return lm; // All options are valid for Linux + case AIX: + case MACOS: + if (lm != LaunchMechanism.VFORK) { + return lm; // All but VFORK are valid } - if (lm == null || !validLaunchMechanisms.contains(lm)) { - throw new Error( - s + " is not a supported " + - "process launch mechanism on this platform." - ); - } - return lm; - } - ); + break; + case WINDOWS: + // fall through to throw to Error + } + } catch (IllegalArgumentException e) { } - static Platform get() { - String osName = GetPropertyAction.privilegedGetProperty("os.name"); - - if (osName.equals("Linux")) { return LINUX; } - if (osName.contains("OS X")) { return BSD; } - if (osName.equals("AIX")) { return AIX; } - - throw new Error(osName + " is not a supported OS platform."); - } + throw new Error(s + " is not a supported " + + "process launch mechanism on this platform: " + OperatingSystem.current()); } - private static final Platform platform = Platform.get(); - private static final LaunchMechanism launchMechanism = platform.launchMechanism(); + private static final LaunchMechanism launchMechanism = launchMechanism(); private static final byte[] helperpath = toCString(StaticProperty.javaHome() + "/lib/jspawnhelper"); private static byte[] toCString(String s) { @@ -354,9 +326,9 @@ final class ProcessImpl extends Process { * @throws IOException */ void initStreams(int[] fds, boolean forceNullOutputStream) throws IOException { - switch (platform) { + switch (OperatingSystem.current()) { case LINUX: - case BSD: + case MACOS: stdin = (fds[0] == -1) ? ProcessBuilder.NullOutputStream.INSTANCE : new ProcessPipeOutputStream(fds[0]); @@ -428,7 +400,9 @@ final class ProcessImpl extends Process { }); break; - default: throw new AssertionError("Unsupported platform: " + platform); + default: + throw new AssertionError("Unsupported platform: " + + OperatingSystem.current()); } } @@ -484,9 +458,9 @@ final class ProcessImpl extends Process { } private void destroy(boolean force) { - switch (platform) { + switch (OperatingSystem.current()) { case LINUX: - case BSD: + case MACOS: case AIX: // There is a risk that pid will be recycled, causing us to // kill the wrong process! So we only terminate processes @@ -506,7 +480,7 @@ final class ProcessImpl extends Process { try { stderr.close(); } catch (IOException ignored) {} break; - default: throw new AssertionError("Unsupported platform: " + platform); + default: throw new AssertionError("Unsupported platform: " + OperatingSystem.current()); } } diff --git a/src/java.base/unix/classes/sun/net/PortConfig.java b/src/java.base/unix/classes/sun/net/PortConfig.java index 78055581e12..4e9deeb90fb 100644 --- a/src/java.base/unix/classes/sun/net/PortConfig.java +++ b/src/java.base/unix/classes/sun/net/PortConfig.java @@ -25,7 +25,7 @@ package sun.net; -import sun.security.action.GetPropertyAction; +import jdk.internal.util.OperatingSystem; /** * Determines the ephemeral port range in use on this system. @@ -42,24 +42,26 @@ public final class PortConfig { static { jdk.internal.loader.BootLoader.loadLibrary("net"); - String os = GetPropertyAction.privilegedGetProperty("os.name"); - if (os.startsWith("Linux")) { - defaultLower = 32768; - defaultUpper = 61000; - } else if (os.contains("OS X")) { - defaultLower = 49152; - defaultUpper = 65535; - } else if (os.startsWith("AIX")) { - // The ephemeral port is OS version dependent on AIX: - // http://publib.boulder.ibm.com/infocenter/aix/v7r1/topic/com.ibm.aix.rsct315.admin/bl503_ephport.htm - // However, on AIX 5.3 / 6.1 / 7.1 we always see the - // settings below by using: - // /usr/sbin/no -a | fgrep ephemeral - defaultLower = 32768; - defaultUpper = 65535; - } else { - throw new InternalError( - "sun.net.PortConfig: unknown OS"); + switch (OperatingSystem.current()) { + case LINUX: + defaultLower = 32768; + defaultUpper = 61000; + break; + case MACOS: + defaultLower = 49152; + defaultUpper = 65535; + break; + case AIX: + // The ephemeral port is OS version dependent on AIX: + // http://publib.boulder.ibm.com/infocenter/aix/v7r1/topic/com.ibm.aix.rsct315.admin/bl503_ephport.htm + // However, on AIX 5.3 / 6.1 / 7.1 we always see the + // settings below by using: + // /usr/sbin/no -a | fgrep ephemeral + defaultLower = 32768; + defaultUpper = 65535; + break; + default: + throw new InternalError("sun.net.PortConfig: unsupported OS: " + OperatingSystem.current()); } int v = getLower0(); diff --git a/test/jdk/java/foreign/TestUnsupportedLinker.java b/test/jdk/java/foreign/TestUnsupportedLinker.java index d16ba1646b2..750ff0fd00e 100644 --- a/test/jdk/java/foreign/TestUnsupportedLinker.java +++ b/test/jdk/java/foreign/TestUnsupportedLinker.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2023, 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 @@ -24,8 +24,8 @@ /* * @test * @enablePreview - * - * @run testng/othervm -Dos.arch=unknown -Dos.name=unknown --enable-native-access=ALL-UNNAMED TestUnsupportedLinker + * @summary test with unknown architecture override + * @run testng/othervm -Dos.arch=unknown --enable-native-access=ALL-UNNAMED TestUnsupportedLinker */ import java.lang.foreign.Linker; diff --git a/test/jdk/jdk/internal/util/OSTest.java b/test/jdk/jdk/internal/util/OSTest.java new file mode 100644 index 00000000000..92a4781bb20 --- /dev/null +++ b/test/jdk/jdk/internal/util/OSTest.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2022, 2023, 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. + */ + + +import java.util.Locale; +import java.util.stream.Stream; + +import jdk.internal.util.OperatingSystem; + +import static jdk.internal.util.OperatingSystem.AIX; +import static jdk.internal.util.OperatingSystem.LINUX; +import static jdk.internal.util.OperatingSystem.MACOS; +import static jdk.internal.util.OperatingSystem.WINDOWS; + +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; + +/** + * @test + * @summary test OperatingSystem enum + * @modules java.base/jdk.internal.util + * @run junit OSTest + */ + +public class OSTest { + /** + * Test consistency of System property "os.name" with OperatingSystem.current(). + */ + @Test + public void os_nameVsCurrent() { + String osName = System.getProperty("os.name").substring(0, 3).toLowerCase(Locale.ROOT); + OperatingSystem os = switch (osName) { + case "win" -> WINDOWS; + case "lin" -> LINUX; + case "mac" -> MACOS; + case "aix" -> AIX; + default -> fail("Unknown os.name: " + osName); + }; + assertEquals(OperatingSystem.current(), os, "mismatch in OperatingSystem.current vs " + osName); + } + + /** + * Test various OperatingSystem enum values vs boolean isXXX() methods. + * @return a stream of arguments for parameterized test + */ + private static Stream osParams() { + return Stream.of( + Arguments.of(LINUX, OperatingSystem.isLinux()), + Arguments.of(WINDOWS, OperatingSystem.isWindows()), + Arguments.of(MACOS, OperatingSystem.isMacOS()), + Arguments.of(AIX, OperatingSystem.isAix()) + ); + } + + @ParameterizedTest + @MethodSource("osParams") + public void isXXX(OperatingSystem os, boolean isXXX) { + OperatingSystem current = OperatingSystem.current(); + assertEquals(os == current, isXXX, + "Mismatch " + os + " == " + current + " vs is" + os); + } + }