--- old/jdk/make/Tools.gmk 2015-01-23 17:25:12.077252958 +0100 +++ new/jdk/make/Tools.gmk 2015-01-23 17:25:11.873244484 +0100 @@ -34,28 +34,23 @@ include NativeCompilation.gmk include SetupJavaCompilers.gmk -# The exception handling of swing beaninfo which have the own tool directory -ifeq (, $(BUILD_TOOLS_JDK)) - $(eval $(call SetupJavaCompilation,BUILD_TOOLS_JDK, \ - SETUP := GENERATE_OLDBYTECODE, \ - ADD_JAVAC_FLAGS := "-Xbootclasspath/p:$(BUILDTOOLS_OUTPUTDIR)/interim_jimage_classes", \ - SRC := $(JDK_TOPDIR)/make/src/classes, \ - BIN := $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes, \ - COPY := boot.modules ext.modules)) -endif +################################################################################ + +$(eval $(call SetupJavaCompilation,BUILD_TOOLS_JDK, \ + SETUP := GENERATE_OLDBYTECODE, \ + ADD_JAVAC_FLAGS := "-Xbootclasspath/p:$(BUILDTOOLS_OUTPUTDIR)/interim_jimage_classes", \ + SRC := $(JDK_TOPDIR)/make/src/classes, \ + BIN := $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes, \ + COPY := boot.modules ext.modules)) + +$(eval $(call SetupCopyFiles,COPY_NIMBUS_TEMPLATES, \ + SRC := $(JDK_TOPDIR)/src/java.desktop/share/classes/javax/swing/plaf/nimbus, \ + DEST := $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes/build/tools/generatenimbus/resources, \ + FILES := $(wildcard $(JDK_TOPDIR)/src/java.desktop/share/classes/javax/swing/plaf/nimbus/*.template))) -$(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes/build/tools/generatenimbus/resources/%.template: \ - $(JDK_TOPDIR)/src/java.desktop/share/classes/javax/swing/plaf/nimbus/%.template - $(call install-file) - -BUILD_TOOLS_JDK += $(foreach i, $(wildcard $(JDK_TOPDIR)/src/java.desktop/share/classes/javax/swing/plaf/nimbus/*.template), $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes/build/tools/generatenimbus/resources/$(notdir $i)) - -# Resource used by CheckDeps tool -$(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes/build/tools/deps/refs.allowed: \ - $(JDK_TOPDIR)/make/data/checkdeps/refs.allowed - $(call install-file) +BUILD_TOOLS_JDK += $(COPY_NIMBUS_TEMPLATES) -BUILD_TOOLS_JDK += $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes/build/tools/deps/refs.allowed +################################################################################ # Add a checksum ("jsum") to the end of a text file. Prevents trivial tampering with class lists. TOOL_ADDJSUM = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \ @@ -130,10 +125,6 @@ TOOL_CLDRCONVERTER = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \ build.tools.cldrconverter.CLDRConverter -TOOL_CHECKDEPS = $(JAVA_SMALL) -Xbootclasspath/p:$(INTERIM_LANGTOOLS_JAR) \ - -cp "$(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes$(PATH_SEP)$(JDK_OUTPUTDIR)" \ - build.tools.deps.CheckDeps - TOOL_GENMODULESXML = $(JAVA_SMALL) -Xbootclasspath/p:$(INTERIM_LANGTOOLS_JAR) \ -cp "$(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes$(PATH_SEP)$(JDK_OUTPUTDIR)" \ build.tools.module.GenJdepsModulesXml @@ -161,25 +152,25 @@ # Tools needed on solaris because OBJCOPY is broken. ifeq ($(OPENJDK_TARGET_OS), solaris) -$(eval $(call SetupNativeCompilation,ADD_GNU_DEBUGLINK, \ - SRC := $(JDK_TOPDIR)/make/src/native/add_gnu_debuglink, \ - LANG := C, \ - CC := $(BUILD_CC), \ - LDEXE := $(BUILD_LD), \ - LDFLAGS := -lelf, \ - OBJECT_DIR := $(BUILDTOOLS_OUTPUTDIR)/objs/add_gnu_debuglink, \ - OUTPUT_DIR := $(BUILDTOOLS_OUTPUTDIR)/bin, \ - PROGRAM := add_gnu_debuglink)) - -$(eval $(call SetupNativeCompilation,FIX_EMPTY_SEC_HDR_FLAGS, \ - SRC := $(JDK_TOPDIR)/make/src/native/fix_empty_sec_hdr_flags, \ - LANG := C, \ - CC := $(BUILD_CC), \ - LDEXE := $(BUILD_LD), \ - LDFLAGS := -lelf, \ - OBJECT_DIR := $(BUILDTOOLS_OUTPUTDIR)/objs/fix_empty_sec_hdr_flags, \ - OUTPUT_DIR := $(BUILDTOOLS_OUTPUTDIR)/bin, \ - PROGRAM := fix_empty_sec_hdr_flags)) + $(eval $(call SetupNativeCompilation,ADD_GNU_DEBUGLINK, \ + SRC := $(JDK_TOPDIR)/make/src/native/add_gnu_debuglink, \ + LANG := C, \ + CC := $(BUILD_CC), \ + LDEXE := $(BUILD_LD), \ + LDFLAGS := -lelf, \ + OBJECT_DIR := $(BUILDTOOLS_OUTPUTDIR)/objs/add_gnu_debuglink, \ + OUTPUT_DIR := $(BUILDTOOLS_OUTPUTDIR)/bin, \ + PROGRAM := add_gnu_debuglink)) + + $(eval $(call SetupNativeCompilation,FIX_EMPTY_SEC_HDR_FLAGS, \ + SRC := $(JDK_TOPDIR)/make/src/native/fix_empty_sec_hdr_flags, \ + LANG := C, \ + CC := $(BUILD_CC), \ + LDEXE := $(BUILD_LD), \ + LDFLAGS := -lelf, \ + OBJECT_DIR := $(BUILDTOOLS_OUTPUTDIR)/objs/fix_empty_sec_hdr_flags, \ + OUTPUT_DIR := $(BUILDTOOLS_OUTPUTDIR)/bin, \ + PROGRAM := fix_empty_sec_hdr_flags)) endif $(BUILD_TOOLS_JDK): $(BUILD_INTERIM_JIMAGE) --- old/jdk/make/lib/CoreLibraries.gmk 2015-01-23 17:25:12.653276883 +0100 +++ new/jdk/make/lib/CoreLibraries.gmk 2015-01-23 17:25:12.441268077 +0100 @@ -74,8 +74,6 @@ ########################################################################################## -BUILD_LIBVERIFY_SRC := check_code.c check_format.c - ifeq ($(OPENJDK_TARGET_OS), solaris) ifneq ($(OPENJDK_TARGET_CPU), x86_64) BUILD_LIBVERIFY_REORDER := $(JDK_TOPDIR)/make/mapfiles/libverify/reorder-$(OPENJDK_TARGET_CPU) @@ -116,10 +114,6 @@ LIBJAVA_SRC_DIRS := $(call FindSrcDirsForLib, java.base, java) -ifeq ($(OPENJDK_TARGET_OS), macosx) - LIBJAVA_EXCLUDE_FILES += $(JDK_TOPDIR)/src/java.base/unix/native/libjava/HostLocaleProviderAdapter_md.c -endif - LIBJAVA_CFLAGS := $(addprefix -I, $(LIBJAVA_SRC_DIRS)) \ -I$(JDK_TOPDIR)/src/java.base/share/native/libfdlibm \ -I$(SUPPORT_OUTPUTDIR)/headers/java.base \ @@ -134,9 +128,7 @@ LIBJAVA_CFLAGS += -DJDK_UPDATE_VERSION='"$(JDK_UPDATE_VERSION)"' endif -ifneq ($(OPENJDK_TARGET_OS), macosx) - LIBJAVA_EXCLUDE_FILES += java_props_macosx.c -else +ifeq ($(OPENJDK_TARGET_OS), macosx) BUILD_LIBJAVA_java_props_md.c_CFLAGS := -x objective-c BUILD_LIBJAVA_java_props_macosx.c_CFLAGS := -x objective-c endif @@ -151,8 +143,6 @@ LIBRARY := java, \ OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ SRC := $(LIBJAVA_SRC_DIRS), \ - EXCLUDES := fdlibm/src zip prefs, \ - EXCLUDE_FILES := $(LIBJAVA_EXCLUDE_FILES), \ LANG := C, \ OPTIMIZATION := HIGH, \ CFLAGS := $(CFLAGS_JDKLIB) \ @@ -247,19 +237,10 @@ ########################################################################################## -BUILD_LIBJLI_SRC_DIRS := $(JDK_TOPDIR)/src/java.base/share/native/libjli \ - $(JDK_TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS_TYPE)/native/libjli +LIBJLI_SRC_DIRS := $(call FindSrcDirsForLib, java.base, jli) LIBJLI_CFLAGS := $(CFLAGS_JDKLIB) -BUILD_LIBJLI_FILES := \ - java.c \ - splashscreen_stubs.c \ - parse_manifest.c \ - version_comp.c \ - wildcard.c \ - jli_util.c - ifeq ($(JVM_VARIANT_ZERO), true) ERGO_FAMILY := zero else @@ -269,68 +250,55 @@ ERGO_FAMILY := $(OPENJDK_TARGET_CPU_ARCH) endif endif +LIBJLI_ALL_ERGO := $(wildcard $(addsuffix /ergo_*.c, $(LIBJLI_SRC_DIRS))) +LIBJLI_EXCLUDE_ERGO := $(filter-out %/ergo_$(ERGO_FAMILY).c, $(LIBJLI_ALL_ERGO)) +# If all specialized ergo files are excluded, use generic ergo +ifeq ($(LIBJLI_ALL_ERGO), $(LIBJLI_EXCLUDE_ERGO)) + LIBJLI_CFLAGS += -DUSE_GENERIC_ERGO +endif +LIBJLI_EXCLUDE_FILES += $(notdir $(LIBJLI_EXCLUDE_ERGO)) ifeq ($(OPENJDK_TARGET_OS), macosx) - BUILD_LIBJLI_SRC_DIRS += $(JDK_TOPDIR)/src/java.base/macosx/native/libjli - BUILD_LIBJLI_FILES += java_md_common.c java_md_macosx.c + LIBJLI_EXCLUDE_FILES += java_md_solinux.c ergo.c BUILD_LIBJLI_java_md_macosx.c_CFLAGS := -x objective-c BUILD_LIBJLI_STATIC_java_md_macosx.c_CFLAGS := -x objective-c + + LIBJLI_CFLAGS += -DPACKAGE_PATH=\"$(PACKAGE_PATH)\" endif ifeq ($(OPENJDK_TARGET_OS), windows) - BUILD_LIBJLI_FILES += java_md.c \ - cmdtoargs.c # Staticically link with c runtime on windows. LIBJLI_CFLAGS := $(filter-out -MD, $(LIBJLI_CFLAGS)) -else ifneq ($(OPENJDK_TARGET_OS), macosx) - - BUILD_LIBJLI_FILES += java_md_common.c - BUILD_LIBJLI_FILES += java_md_solinux.c ergo.c - - ERGO_ARCH_FILE = ergo_$(ERGO_FAMILY).c - - # if the architecture specific ergo file exists then - # use it, else use the generic definitions from ergo.c - ifneq ($(wildcard $(JDK_TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS_TYPE)/native/libjli/$(ERGO_ARCH_FILE)), ) - BUILD_LIBJLI_FILES += $(ERGO_ARCH_FILE) - else # !ERGO_ARCH_FILE - LIBJLI_CFLAGS += -DUSE_GENERIC_ERGO - endif # ERGO_ARCH_FILE -endif #WINDOWS + LIBJLI_OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE) +else + LIBJLI_OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE)/jli +endif -LIBJLI_CFLAGS += $(foreach dir, $(BUILD_LIBJLI_SRC_DIRS), -I$(dir)) +LIBJLI_CFLAGS += $(addprefix -I, $(LIBJLI_SRC_DIRS)) # Append defines depending on target platform LIBJLI_CFLAGS += $(OPENJDK_TARGET_CPU_JLI_CFLAGS) -ifeq ($(OPENJDK_TARGET_OS), macosx) - LIBJLI_CFLAGS += -DPACKAGE_PATH=\"$(PACKAGE_PATH)\" -endif - ifneq ($(USE_EXTERNAL_LIBZ), true) - BUILD_LIBJLI_SRC_DIRS += $(JDK_TOPDIR)/src/java.base/share/native/libzip/zlib-1.2.8 LIBJLI_CFLAGS += $(ZLIB_CPPFLAGS) - BUILD_LIBJLI_FILES += \ - inflate.c \ - inftrees.c \ - inffast.c \ - zadler32.c \ - zcrc32.c \ - zutil.c -endif - -ifeq ($(OPENJDK_TARGET_OS), windows) - LIBJLI_OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE) -else - LIBJLI_OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE)/jli + LIBJLI_EXTRA_FILES += \ + $(addprefix $(JDK_TOPDIR)/src/java.base/share/native/libzip/zlib-1.2.8/, \ + inflate.c \ + inftrees.c \ + inffast.c \ + zadler32.c \ + zcrc32.c \ + zutil.c \ + ) endif $(eval $(call SetupNativeCompilation,BUILD_LIBJLI, \ LIBRARY := jli, \ OUTPUT_DIR := $(LIBJLI_OUTPUT_DIR), \ - SRC := $(BUILD_LIBJLI_SRC_DIRS), \ - INCLUDE_FILES := $(BUILD_LIBJLI_FILES), \ + SRC := $(LIBJLI_SRC_DIRS), \ + EXCLUDE_FILES := $(LIBJLI_EXCLUDE_FILES), \ + EXTRA_FILES := $(LIBJLI_EXTRA_FILES), \ LANG := C, \ OPTIMIZATION := HIGH, \ CFLAGS := $(LIBJLI_CFLAGS), \ @@ -376,8 +344,9 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBJLI_STATIC, \ STATIC_LIBRARY := jli_static, \ OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE), \ - SRC := $(BUILD_LIBJLI_SRC_DIRS), \ - INCLUDE_FILES := $(BUILD_LIBJLI_FILES), \ + SRC := $(LIBJLI_SRC_DIRS), \ + EXCLUDE_FILES := $(LIBJLI_EXCLUDE_FILES), \ + EXTRA_FILES := $(LIBJLI_EXTRA_FILES), \ LANG := C, \ OPTIMIZATION := HIGH, \ CFLAGS := $(STATIC_LIBRARY_FLAGS) $(LIBJLI_CFLAGS), \ @@ -395,8 +364,9 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBJLI_STATIC, \ LIBRARY := jli_static, \ OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE), \ - SRC := $(BUILD_LIBJLI_SRC_DIRS), \ - INCLUDE_FILES := $(BUILD_LIBJLI_FILES), \ + SRC := $(LIBJLI_SRC_DIRS), \ + EXCLUDE_FILES := $(LIBJLI_EXCLUDE_FILES), \ + EXTRA_FILES := $(LIBJLI_EXTRA_FILES), \ LANG := C, \ OPTIMIZATION := HIGH, \ CFLAGS := $(CFLAGS_JDKLIB) $(LIBJLI_CFLAGS), \ @@ -411,16 +381,17 @@ else ifeq ($(OPENJDK_TARGET_OS), aix) # AIX also requires a static libjli because the compiler doesn't support '-rpath' - $(eval $(call SetupNativeCompilation,BUILD_LIBJLI_STATIC,\ - STATIC_LIBRARY:=jli_static,\ - OUTPUT_DIR:=$(SUPPORT_OUTPUTDIR)/native/$(MODULE),\ - SRC:=$(BUILD_LIBJLI_SRC_DIRS),\ - INCLUDE_FILES:=$(BUILD_LIBJLI_FILES),\ - LANG:=C,\ - OPTIMIZATION:=HIGH, \ - CFLAGS:=$(STATIC_LIBRARY_FLAGS) $(LIBJLI_CFLAGS),\ - ARFLAGS:=$(ARFLAGS),\ - OBJECT_DIR:=$(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libjli_static)) + $(eval $(call SetupNativeCompilation,BUILD_LIBJLI_STATIC, \ + STATIC_LIBRARY := jli_static, \ + OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE), \ + SRC := $(LIBJLI_SRC_DIRS), \ + EXCLUDE_FILES := $(LIBJLI_EXCLUDE_FILES), \ + EXTRA_FILES := $(LIBJLI_EXTRA_FILES), \ + LANG := C, \ + OPTIMIZATION := HIGH, \ + CFLAGS := $(STATIC_LIBRARY_FLAGS) $(LIBJLI_CFLAGS), \ + ARFLAGS := $(ARFLAGS), \ + OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libjli_static)) TARGETS += $(BUILD_LIBJLI_STATIC) --- old/jdk/make/lib/Lib-jdk.attach.gmk 2015-01-23 17:25:13.241301307 +0100 +++ new/jdk/make/lib/Lib-jdk.attach.gmk 2015-01-23 17:25:13.037292834 +0100 @@ -31,7 +31,7 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBATTACH, \ LIBRARY := attach, \ OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(JDK_TOPDIR)/src/jdk.attach/$(OPENJDK_TARGET_OS)/native/libattach, \ + SRC := $(call FindSrcDirsForLib, jdk.attach, attach), \ LANG := C, \ OPTIMIZATION := LOW, \ CFLAGS := $(CFLAGS_JDKLIB) $(CFLAGS_WARNINGS_ARE_ERRORS) \ --- old/jdk/make/lib/Lib-jdk.security.auth.gmk 2015-01-23 17:25:13.829325731 +0100 +++ new/jdk/make/lib/Lib-jdk.security.auth.gmk 2015-01-23 17:25:13.609316593 +0100 @@ -28,9 +28,7 @@ ################################################################################ LIBJAAS_MAPFILE := -ifneq ($(OPENJDK_TARGET_OS), solaris) - LIBJAAS_EXCLUDE_FILES := Solaris.c -else +ifeq ($(OPENJDK_TARGET_OS), solaris) # only on solaris...wonder why LIBJAAS_MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libjaas/mapfile-vers endif @@ -43,7 +41,7 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBJAAS, \ LIBRARY := $(LIBJAAS_NAME), \ OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(JDK_TOPDIR)/src/jdk.security.auth/$(OPENJDK_TARGET_OS_TYPE)/native/libjaas, \ + SRC := $(call FindSrcDirsForLib, jdk.security.auth, jaas), \ LANG := C, \ OPTIMIZATION := LOW, \ CFLAGS := $(CFLAGS_JDKLIB) -I$(SUPPORT_OUTPUTDIR)/headers/jdk.security.auth, \ @@ -53,7 +51,6 @@ LDFLAGS_windows := netapi32.lib user32.lib mpr.lib advapi32.lib, \ LDFLAGS_SUFFIX_windows := $(LDFLAGS_JDKLIB_SUFFIX), \ LDFLAGS_SUFFIX_solaris := -lc, \ - EXCLUDE_FILES := $(LIBJAAS_EXCLUDE_FILES), \ VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \ RC_FLAGS := $(RC_FLAGS) \ -D "JDK_FNAME=$(LIBJAAS_NAME).dll" \ --- old/jdk/make/lib/NetworkingLibraries.gmk 2015-01-23 17:25:14.405349656 +0100 +++ new/jdk/make/lib/NetworkingLibraries.gmk 2015-01-23 17:25:14.201341182 +0100 @@ -23,39 +23,16 @@ # questions. # -LIBNET_SRC_DIRS := $(JDK_TOPDIR)/src/java.base/share/native/libnet \ - $(JDK_TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS_TYPE)/native/libnet -LIBNET_CFLAGS += -I$(SUPPORT_OUTPUTDIR)/headers/java.base \ - $(LIBJAVA_HEADER_FLAGS) - -LIBNET_CFLAGS += $(foreach dir, $(LIBNET_SRC_DIRS), -I$(dir)) - -LIBNET_EXCLUDE_FILES := -ifneq ($(OPENJDK_TARGET_OS), solaris) - LIBNET_EXCLUDE_FILES += solaris_close.c -endif - -ifneq ($(OPENJDK_TARGET_OS), linux) - LIBNET_EXCLUDE_FILES += linux_close.c -endif - -ifneq ($(OPENJDK_TARGET_OS), macosx) - LIBNET_EXCLUDE_FILES += bsd_close.c -endif - -ifeq ($(OPENJDK_TARGET_OS), aix) - LIBNET_SRC_DIRS += $(JDK_TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS)/native/libnet/java/net/ -endif +LIBNET_SRC_DIRS := $(call FindSrcDirsForLib, java.base, net) $(eval $(call SetupNativeCompilation,BUILD_LIBNET, \ LIBRARY := net, \ OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ SRC := $(LIBNET_SRC_DIRS), \ - EXCLUDE_FILES := $(LIBNET_EXCLUDE_FILES), \ LANG := C, \ OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKLIB) \ - $(LIBNET_CFLAGS), \ + CFLAGS := $(CFLAGS_JDKLIB) -I$(SUPPORT_OUTPUTDIR)/headers/java.base \ + $(LIBJAVA_HEADER_FLAGS) $(addprefix -I, $(LIBNET_SRC_DIRS)), \ MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libnet/mapfile-vers, \ LDFLAGS := $(LDFLAGS_JDKLIB) \ $(call SET_SHARED_LIBRARY_ORIGIN), \ --- old/jdk/make/lib/NioLibraries.gmk 2015-01-23 17:25:14.981373583 +0100 +++ new/jdk/make/lib/NioLibraries.gmk 2015-01-23 17:25:14.769364776 +0100 @@ -65,7 +65,6 @@ OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ SRC := $(BUILD_LIBNIO_SRC), \ EXCLUDE_FILES := $(BUILD_LIBNIO_EXFILES), \ - EXCLUDES := sctp, \ LANG := C, \ OPTIMIZATION := HIGH, \ CFLAGS := $(CFLAGS_JDKLIB) \ --- old/jdk/src/java.base/aix/native/libnet/java/net/aix_close.c 2015-01-23 17:25:15.653401495 +0100 +++ /dev/null 2015-01-08 08:58:23.458195824 +0100 @@ -1,491 +0,0 @@ -/* - * Copyright (c) 2001, 2013, 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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. - */ - -/* - * This file contains implementations of NET_... functions. The NET_.. functions are - * wrappers for common file- and socket functions plus provisions for non-blocking IO. - * - * (basically, the layers remember all file descriptors waiting for a particular fd; - * all threads waiting on a certain fd can be woken up by sending them a signal; this - * is done e.g. when the fd is closed.) - * - * This was originally copied from the linux_close.c implementation. - * - * Side Note: This coding needs initialization. Under Linux this is done - * automatically via __attribute((constructor)), on AIX this is done manually - * (see aix_close_init). - * - */ - -/* - AIX needs a workaround for I/O cancellation, see: - http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp?topic=/com.ibm.aix.basetechref/doc/basetrf1/close.htm - ... - The close subroutine is blocked until all subroutines which use the file - descriptor return to usr space. For example, when a thread is calling close - and another thread is calling select with the same file descriptor, the - close subroutine does not return until the select call returns. - ... -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Stack allocated by thread when doing blocking operation - */ -typedef struct threadEntry { - pthread_t thr; /* this thread */ - struct threadEntry *next; /* next thread */ - int intr; /* interrupted */ -} threadEntry_t; - -/* - * Heap allocated during initialized - one entry per fd - */ -typedef struct { - pthread_mutex_t lock; /* fd lock */ - threadEntry_t *threads; /* threads blocked on fd */ -} fdEntry_t; - -/* - * Signal to unblock thread - */ -static int sigWakeup = (SIGRTMAX - 1); - -/* - * The fd table and the number of file descriptors - */ -static fdEntry_t *fdTable = NULL; -static int fdCount = 0; - -/* - * Null signal handler - */ -static void sig_wakeup(int sig) { -} - -/* - * Initialization routine (executed when library is loaded) - * Allocate fd tables and sets up signal handler. - * - * On AIX we don't have __attribute((constructor)) so we need to initialize - * manually (from JNI_OnLoad() in 'src/share/native/java/net/net_util.c') - */ -void aix_close_init() { - struct rlimit nbr_files; - sigset_t sigset; - struct sigaction sa; - - /* Check already initialized */ - if (fdCount > 0 && fdTable != NULL) { - return; - } - - /* - * Allocate table based on the maximum number of - * file descriptors. - */ - if (-1 == getrlimit(RLIMIT_NOFILE, &nbr_files)) { - fprintf(stderr, "library initialization failed - " - "unable to get max # of allocated fds\n"); - abort(); - } - fdCount = nbr_files.rlim_max; - /* - * We have a conceptual problem here, when the number of files is - * unlimited. As a kind of workaround, we ensure the table is big - * enough for handle even a large number of files. Since SAP itself - * recommends a limit of 32000 files, we just use 64000 as 'infinity'. - */ - if (nbr_files.rlim_max == RLIM_INFINITY) { - fdCount = 64000; - } - fdTable = (fdEntry_t *)calloc(fdCount, sizeof(fdEntry_t)); - if (fdTable == NULL) { - fprintf(stderr, "library initialization failed - " - "unable to allocate file descriptor table - out of memory"); - abort(); - } - - { - int i; - for (i=0; i < fdCount; i++) { - pthread_mutex_init(&fdTable[i].lock, NULL); - } - } - - /* - * Setup the signal handler - */ - sa.sa_handler = sig_wakeup; - sa.sa_flags = 0; - sigemptyset(&sa.sa_mask); - sigaction(sigWakeup, &sa, NULL); - - sigemptyset(&sigset); - sigaddset(&sigset, sigWakeup); - sigprocmask(SIG_UNBLOCK, &sigset, NULL); -} - -/* - * Return the fd table for this fd or NULL is fd out - * of range. - */ -static inline fdEntry_t *getFdEntry(int fd) -{ - if (fd < 0 || fd >= fdCount) { - return NULL; - } - return &fdTable[fd]; -} - -/* - * Start a blocking operation :- - * Insert thread onto thread list for the fd. - */ -static inline void startOp(fdEntry_t *fdEntry, threadEntry_t *self) -{ - self->thr = pthread_self(); - self->intr = 0; - - pthread_mutex_lock(&(fdEntry->lock)); - { - self->next = fdEntry->threads; - fdEntry->threads = self; - } - pthread_mutex_unlock(&(fdEntry->lock)); -} - -/* - * End a blocking operation :- - * Remove thread from thread list for the fd - * If fd has been interrupted then set errno to EBADF - */ -static inline void endOp - (fdEntry_t *fdEntry, threadEntry_t *self) -{ - int orig_errno = errno; - pthread_mutex_lock(&(fdEntry->lock)); - { - threadEntry_t *curr, *prev=NULL; - curr = fdEntry->threads; - while (curr != NULL) { - if (curr == self) { - if (curr->intr) { - orig_errno = EBADF; - } - if (prev == NULL) { - fdEntry->threads = curr->next; - } else { - prev->next = curr->next; - } - break; - } - prev = curr; - curr = curr->next; - } - } - pthread_mutex_unlock(&(fdEntry->lock)); - errno = orig_errno; -} - -/* - * Close or dup2 a file descriptor ensuring that all threads blocked on - * the file descriptor are notified via a wakeup signal. - * - * fd1 < 0 => close(fd2) - * fd1 >= 0 => dup2(fd1, fd2) - * - * Returns -1 with errno set if operation fails. - */ -static int closefd(int fd1, int fd2) { - int rv, orig_errno; - fdEntry_t *fdEntry = getFdEntry(fd2); - if (fdEntry == NULL) { - errno = EBADF; - return -1; - } - - /* - * Lock the fd to hold-off additional I/O on this fd. - */ - pthread_mutex_lock(&(fdEntry->lock)); - - { - /* On fast machines we see that we enter dup2 before the - * accepting thread had a chance to get and process the signal. - * So in case we woke a thread up, give it some time to cope. - * Also see https://bugs.openjdk.java.net/browse/JDK-8006395 */ - int num_woken = 0; - - /* - * Send a wakeup signal to all threads blocked on this - * file descriptor. - */ - threadEntry_t *curr = fdEntry->threads; - while (curr != NULL) { - curr->intr = 1; - pthread_kill( curr->thr, sigWakeup ); - num_woken ++; - curr = curr->next; - } - - if (num_woken > 0) { - usleep(num_woken * 50); - } - - /* - * And close/dup the file descriptor - * (restart if interrupted by signal) - */ - do { - if (fd1 < 0) { - rv = close(fd2); - } else { - rv = dup2(fd1, fd2); - } - } while (rv == -1 && errno == EINTR); - } - - /* - * Unlock without destroying errno - */ - orig_errno = errno; - pthread_mutex_unlock(&(fdEntry->lock)); - errno = orig_errno; - - return rv; -} - -/* - * Wrapper for dup2 - same semantics as dup2 system call except - * that any threads blocked in an I/O system call on fd2 will be - * preempted and return -1/EBADF; - */ -int NET_Dup2(int fd, int fd2) { - if (fd < 0) { - errno = EBADF; - return -1; - } - return closefd(fd, fd2); -} - -/* - * Wrapper for close - same semantics as close system call - * except that any threads blocked in an I/O on fd will be - * preempted and the I/O system call will return -1/EBADF. - */ -int NET_SocketClose(int fd) { - return closefd(-1, fd); -} - -/************** Basic I/O operations here ***************/ - -/* - * Macro to perform a blocking IO operation. Restarts - * automatically if interrupted by signal (other than - * our wakeup signal) - */ -#define BLOCKING_IO_RETURN_INT(FD, FUNC) { \ - int ret; \ - threadEntry_t self; \ - fdEntry_t *fdEntry = getFdEntry(FD); \ - if (fdEntry == NULL) { \ - errno = EBADF; \ - return -1; \ - } \ - do { \ - startOp(fdEntry, &self); \ - ret = FUNC; \ - endOp(fdEntry, &self); \ - } while (ret == -1 && errno == EINTR); \ - return ret; \ -} - -int NET_Read(int s, void* buf, size_t len) { - BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, 0) ); -} - -int NET_ReadV(int s, const struct iovec * vector, int count) { - BLOCKING_IO_RETURN_INT( s, readv(s, vector, count) ); -} - -int NET_RecvFrom(int s, void *buf, int len, unsigned int flags, - struct sockaddr *from, int *fromlen) { - socklen_t socklen = *fromlen; - BLOCKING_IO_RETURN_INT( s, recvfrom(s, buf, len, flags, from, &socklen) ); - *fromlen = socklen; -} - -int NET_Send(int s, void *msg, int len, unsigned int flags) { - BLOCKING_IO_RETURN_INT( s, send(s, msg, len, flags) ); -} - -int NET_WriteV(int s, const struct iovec * vector, int count) { - BLOCKING_IO_RETURN_INT( s, writev(s, vector, count) ); -} - -int NET_SendTo(int s, const void *msg, int len, unsigned int - flags, const struct sockaddr *to, int tolen) { - BLOCKING_IO_RETURN_INT( s, sendto(s, msg, len, flags, to, tolen) ); -} - -int NET_Accept(int s, struct sockaddr *addr, int *addrlen) { - socklen_t socklen = *addrlen; - BLOCKING_IO_RETURN_INT( s, accept(s, addr, &socklen) ); - *addrlen = socklen; -} - -int NET_Connect(int s, struct sockaddr *addr, int addrlen) { - int crc = -1, prc = -1; - threadEntry_t self; - fdEntry_t* fdEntry = getFdEntry(s); - - if (fdEntry == NULL) { - errno = EBADF; - return -1; - } - - /* On AIX, when the system call connect() is interrupted, the connection - * is not aborted and it will be established asynchronously by the kernel. - * Hence, no need to restart connect() when EINTR is received - */ - startOp(fdEntry, &self); - crc = connect(s, addr, addrlen); - endOp(fdEntry, &self); - - if (crc == -1 && errno == EINTR) { - struct pollfd s_pollfd; - int sockopt_arg = 0; - socklen_t len; - - s_pollfd.fd = s; - s_pollfd.events = POLLOUT | POLLERR; - - /* poll the file descriptor */ - do { - startOp(fdEntry, &self); - prc = poll(&s_pollfd, 1, -1); - endOp(fdEntry, &self); - } while (prc == -1 && errno == EINTR); - - if (prc < 0) - return prc; - - len = sizeof(sockopt_arg); - - /* Check whether the connection has been established */ - if (getsockopt(s, SOL_SOCKET, SO_ERROR, &sockopt_arg, &len) == -1) - return -1; - - if (sockopt_arg != 0 ) { - errno = sockopt_arg; - return -1; - } - } else { - return crc; - } - - /* At this point, fd is connected. Set successful return code */ - return 0; -} - -int NET_Poll(struct pollfd *ufds, unsigned int nfds, int timeout) { - BLOCKING_IO_RETURN_INT( ufds[0].fd, poll(ufds, nfds, timeout) ); -} - -/* - * Wrapper for poll(s, timeout). - * Auto restarts with adjusted timeout if interrupted by - * signal other than our wakeup signal. - */ -int NET_Timeout(int s, long timeout) { - long prevtime = 0, newtime; - struct timeval t; - fdEntry_t *fdEntry = getFdEntry(s); - - /* - * Check that fd hasn't been closed. - */ - if (fdEntry == NULL) { - errno = EBADF; - return -1; - } - - /* - * Pick up current time as may need to adjust timeout - */ - if (timeout > 0) { - gettimeofday(&t, NULL); - prevtime = t.tv_sec * 1000 + t.tv_usec / 1000; - } - - for(;;) { - struct pollfd pfd; - int rv; - threadEntry_t self; - - /* - * Poll the fd. If interrupted by our wakeup signal - * errno will be set to EBADF. - */ - pfd.fd = s; - pfd.events = POLLIN | POLLERR; - - startOp(fdEntry, &self); - rv = poll(&pfd, 1, timeout); - endOp(fdEntry, &self); - - /* - * If interrupted then adjust timeout. If timeout - * has expired return 0 (indicating timeout expired). - */ - if (rv < 0 && errno == EINTR) { - if (timeout > 0) { - gettimeofday(&t, NULL); - newtime = t.tv_sec * 1000 + t.tv_usec / 1000; - timeout -= newtime - prevtime; - if (timeout <= 0) { - return 0; - } - prevtime = newtime; - } - } else { - return rv; - } - - } -} --- /dev/null 2015-01-08 08:58:23.458195824 +0100 +++ new/jdk/src/java.base/aix/native/libnet/aix_close.c 2015-01-23 17:25:15.345388701 +0100 @@ -0,0 +1,491 @@ +/* + * Copyright (c) 2001, 2013, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +/* + * This file contains implementations of NET_... functions. The NET_.. functions are + * wrappers for common file- and socket functions plus provisions for non-blocking IO. + * + * (basically, the layers remember all file descriptors waiting for a particular fd; + * all threads waiting on a certain fd can be woken up by sending them a signal; this + * is done e.g. when the fd is closed.) + * + * This was originally copied from the linux_close.c implementation. + * + * Side Note: This coding needs initialization. Under Linux this is done + * automatically via __attribute((constructor)), on AIX this is done manually + * (see aix_close_init). + * + */ + +/* + AIX needs a workaround for I/O cancellation, see: + http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp?topic=/com.ibm.aix.basetechref/doc/basetrf1/close.htm + ... + The close subroutine is blocked until all subroutines which use the file + descriptor return to usr space. For example, when a thread is calling close + and another thread is calling select with the same file descriptor, the + close subroutine does not return until the select call returns. + ... +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Stack allocated by thread when doing blocking operation + */ +typedef struct threadEntry { + pthread_t thr; /* this thread */ + struct threadEntry *next; /* next thread */ + int intr; /* interrupted */ +} threadEntry_t; + +/* + * Heap allocated during initialized - one entry per fd + */ +typedef struct { + pthread_mutex_t lock; /* fd lock */ + threadEntry_t *threads; /* threads blocked on fd */ +} fdEntry_t; + +/* + * Signal to unblock thread + */ +static int sigWakeup = (SIGRTMAX - 1); + +/* + * The fd table and the number of file descriptors + */ +static fdEntry_t *fdTable = NULL; +static int fdCount = 0; + +/* + * Null signal handler + */ +static void sig_wakeup(int sig) { +} + +/* + * Initialization routine (executed when library is loaded) + * Allocate fd tables and sets up signal handler. + * + * On AIX we don't have __attribute((constructor)) so we need to initialize + * manually (from JNI_OnLoad() in 'src/share/native/java/net/net_util.c') + */ +void aix_close_init() { + struct rlimit nbr_files; + sigset_t sigset; + struct sigaction sa; + + /* Check already initialized */ + if (fdCount > 0 && fdTable != NULL) { + return; + } + + /* + * Allocate table based on the maximum number of + * file descriptors. + */ + if (-1 == getrlimit(RLIMIT_NOFILE, &nbr_files)) { + fprintf(stderr, "library initialization failed - " + "unable to get max # of allocated fds\n"); + abort(); + } + fdCount = nbr_files.rlim_max; + /* + * We have a conceptual problem here, when the number of files is + * unlimited. As a kind of workaround, we ensure the table is big + * enough for handle even a large number of files. Since SAP itself + * recommends a limit of 32000 files, we just use 64000 as 'infinity'. + */ + if (nbr_files.rlim_max == RLIM_INFINITY) { + fdCount = 64000; + } + fdTable = (fdEntry_t *)calloc(fdCount, sizeof(fdEntry_t)); + if (fdTable == NULL) { + fprintf(stderr, "library initialization failed - " + "unable to allocate file descriptor table - out of memory"); + abort(); + } + + { + int i; + for (i=0; i < fdCount; i++) { + pthread_mutex_init(&fdTable[i].lock, NULL); + } + } + + /* + * Setup the signal handler + */ + sa.sa_handler = sig_wakeup; + sa.sa_flags = 0; + sigemptyset(&sa.sa_mask); + sigaction(sigWakeup, &sa, NULL); + + sigemptyset(&sigset); + sigaddset(&sigset, sigWakeup); + sigprocmask(SIG_UNBLOCK, &sigset, NULL); +} + +/* + * Return the fd table for this fd or NULL is fd out + * of range. + */ +static inline fdEntry_t *getFdEntry(int fd) +{ + if (fd < 0 || fd >= fdCount) { + return NULL; + } + return &fdTable[fd]; +} + +/* + * Start a blocking operation :- + * Insert thread onto thread list for the fd. + */ +static inline void startOp(fdEntry_t *fdEntry, threadEntry_t *self) +{ + self->thr = pthread_self(); + self->intr = 0; + + pthread_mutex_lock(&(fdEntry->lock)); + { + self->next = fdEntry->threads; + fdEntry->threads = self; + } + pthread_mutex_unlock(&(fdEntry->lock)); +} + +/* + * End a blocking operation :- + * Remove thread from thread list for the fd + * If fd has been interrupted then set errno to EBADF + */ +static inline void endOp + (fdEntry_t *fdEntry, threadEntry_t *self) +{ + int orig_errno = errno; + pthread_mutex_lock(&(fdEntry->lock)); + { + threadEntry_t *curr, *prev=NULL; + curr = fdEntry->threads; + while (curr != NULL) { + if (curr == self) { + if (curr->intr) { + orig_errno = EBADF; + } + if (prev == NULL) { + fdEntry->threads = curr->next; + } else { + prev->next = curr->next; + } + break; + } + prev = curr; + curr = curr->next; + } + } + pthread_mutex_unlock(&(fdEntry->lock)); + errno = orig_errno; +} + +/* + * Close or dup2 a file descriptor ensuring that all threads blocked on + * the file descriptor are notified via a wakeup signal. + * + * fd1 < 0 => close(fd2) + * fd1 >= 0 => dup2(fd1, fd2) + * + * Returns -1 with errno set if operation fails. + */ +static int closefd(int fd1, int fd2) { + int rv, orig_errno; + fdEntry_t *fdEntry = getFdEntry(fd2); + if (fdEntry == NULL) { + errno = EBADF; + return -1; + } + + /* + * Lock the fd to hold-off additional I/O on this fd. + */ + pthread_mutex_lock(&(fdEntry->lock)); + + { + /* On fast machines we see that we enter dup2 before the + * accepting thread had a chance to get and process the signal. + * So in case we woke a thread up, give it some time to cope. + * Also see https://bugs.openjdk.java.net/browse/JDK-8006395 */ + int num_woken = 0; + + /* + * Send a wakeup signal to all threads blocked on this + * file descriptor. + */ + threadEntry_t *curr = fdEntry->threads; + while (curr != NULL) { + curr->intr = 1; + pthread_kill( curr->thr, sigWakeup ); + num_woken ++; + curr = curr->next; + } + + if (num_woken > 0) { + usleep(num_woken * 50); + } + + /* + * And close/dup the file descriptor + * (restart if interrupted by signal) + */ + do { + if (fd1 < 0) { + rv = close(fd2); + } else { + rv = dup2(fd1, fd2); + } + } while (rv == -1 && errno == EINTR); + } + + /* + * Unlock without destroying errno + */ + orig_errno = errno; + pthread_mutex_unlock(&(fdEntry->lock)); + errno = orig_errno; + + return rv; +} + +/* + * Wrapper for dup2 - same semantics as dup2 system call except + * that any threads blocked in an I/O system call on fd2 will be + * preempted and return -1/EBADF; + */ +int NET_Dup2(int fd, int fd2) { + if (fd < 0) { + errno = EBADF; + return -1; + } + return closefd(fd, fd2); +} + +/* + * Wrapper for close - same semantics as close system call + * except that any threads blocked in an I/O on fd will be + * preempted and the I/O system call will return -1/EBADF. + */ +int NET_SocketClose(int fd) { + return closefd(-1, fd); +} + +/************** Basic I/O operations here ***************/ + +/* + * Macro to perform a blocking IO operation. Restarts + * automatically if interrupted by signal (other than + * our wakeup signal) + */ +#define BLOCKING_IO_RETURN_INT(FD, FUNC) { \ + int ret; \ + threadEntry_t self; \ + fdEntry_t *fdEntry = getFdEntry(FD); \ + if (fdEntry == NULL) { \ + errno = EBADF; \ + return -1; \ + } \ + do { \ + startOp(fdEntry, &self); \ + ret = FUNC; \ + endOp(fdEntry, &self); \ + } while (ret == -1 && errno == EINTR); \ + return ret; \ +} + +int NET_Read(int s, void* buf, size_t len) { + BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, 0) ); +} + +int NET_ReadV(int s, const struct iovec * vector, int count) { + BLOCKING_IO_RETURN_INT( s, readv(s, vector, count) ); +} + +int NET_RecvFrom(int s, void *buf, int len, unsigned int flags, + struct sockaddr *from, int *fromlen) { + socklen_t socklen = *fromlen; + BLOCKING_IO_RETURN_INT( s, recvfrom(s, buf, len, flags, from, &socklen) ); + *fromlen = socklen; +} + +int NET_Send(int s, void *msg, int len, unsigned int flags) { + BLOCKING_IO_RETURN_INT( s, send(s, msg, len, flags) ); +} + +int NET_WriteV(int s, const struct iovec * vector, int count) { + BLOCKING_IO_RETURN_INT( s, writev(s, vector, count) ); +} + +int NET_SendTo(int s, const void *msg, int len, unsigned int + flags, const struct sockaddr *to, int tolen) { + BLOCKING_IO_RETURN_INT( s, sendto(s, msg, len, flags, to, tolen) ); +} + +int NET_Accept(int s, struct sockaddr *addr, int *addrlen) { + socklen_t socklen = *addrlen; + BLOCKING_IO_RETURN_INT( s, accept(s, addr, &socklen) ); + *addrlen = socklen; +} + +int NET_Connect(int s, struct sockaddr *addr, int addrlen) { + int crc = -1, prc = -1; + threadEntry_t self; + fdEntry_t* fdEntry = getFdEntry(s); + + if (fdEntry == NULL) { + errno = EBADF; + return -1; + } + + /* On AIX, when the system call connect() is interrupted, the connection + * is not aborted and it will be established asynchronously by the kernel. + * Hence, no need to restart connect() when EINTR is received + */ + startOp(fdEntry, &self); + crc = connect(s, addr, addrlen); + endOp(fdEntry, &self); + + if (crc == -1 && errno == EINTR) { + struct pollfd s_pollfd; + int sockopt_arg = 0; + socklen_t len; + + s_pollfd.fd = s; + s_pollfd.events = POLLOUT | POLLERR; + + /* poll the file descriptor */ + do { + startOp(fdEntry, &self); + prc = poll(&s_pollfd, 1, -1); + endOp(fdEntry, &self); + } while (prc == -1 && errno == EINTR); + + if (prc < 0) + return prc; + + len = sizeof(sockopt_arg); + + /* Check whether the connection has been established */ + if (getsockopt(s, SOL_SOCKET, SO_ERROR, &sockopt_arg, &len) == -1) + return -1; + + if (sockopt_arg != 0 ) { + errno = sockopt_arg; + return -1; + } + } else { + return crc; + } + + /* At this point, fd is connected. Set successful return code */ + return 0; +} + +int NET_Poll(struct pollfd *ufds, unsigned int nfds, int timeout) { + BLOCKING_IO_RETURN_INT( ufds[0].fd, poll(ufds, nfds, timeout) ); +} + +/* + * Wrapper for poll(s, timeout). + * Auto restarts with adjusted timeout if interrupted by + * signal other than our wakeup signal. + */ +int NET_Timeout(int s, long timeout) { + long prevtime = 0, newtime; + struct timeval t; + fdEntry_t *fdEntry = getFdEntry(s); + + /* + * Check that fd hasn't been closed. + */ + if (fdEntry == NULL) { + errno = EBADF; + return -1; + } + + /* + * Pick up current time as may need to adjust timeout + */ + if (timeout > 0) { + gettimeofday(&t, NULL); + prevtime = t.tv_sec * 1000 + t.tv_usec / 1000; + } + + for(;;) { + struct pollfd pfd; + int rv; + threadEntry_t self; + + /* + * Poll the fd. If interrupted by our wakeup signal + * errno will be set to EBADF. + */ + pfd.fd = s; + pfd.events = POLLIN | POLLERR; + + startOp(fdEntry, &self); + rv = poll(&pfd, 1, timeout); + endOp(fdEntry, &self); + + /* + * If interrupted then adjust timeout. If timeout + * has expired return 0 (indicating timeout expired). + */ + if (rv < 0 && errno == EINTR) { + if (timeout > 0) { + gettimeofday(&t, NULL); + newtime = t.tv_sec * 1000 + t.tv_usec / 1000; + timeout -= newtime - prevtime; + if (timeout <= 0) { + return 0; + } + prevtime = newtime; + } + } else { + return rv; + } + + } +} --- old/jdk/src/java.base/unix/native/libnet/linux_close.c 2015-01-23 17:25:16.141421766 +0100 +++ /dev/null 2015-01-08 08:58:23.458195824 +0100 @@ -1,371 +0,0 @@ -/* - * Copyright (c) 2001, 2013, 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Stack allocated by thread when doing blocking operation - */ -typedef struct threadEntry { - pthread_t thr; /* this thread */ - struct threadEntry *next; /* next thread */ - int intr; /* interrupted */ -} threadEntry_t; - -/* - * Heap allocated during initialized - one entry per fd - */ -typedef struct { - pthread_mutex_t lock; /* fd lock */ - threadEntry_t *threads; /* threads blocked on fd */ -} fdEntry_t; - -/* - * Signal to unblock thread - */ -static int sigWakeup = (__SIGRTMAX - 2); - -/* - * The fd table and the number of file descriptors - */ -static fdEntry_t *fdTable; -static int fdCount; - -/* - * Null signal handler - */ -static void sig_wakeup(int sig) { -} - -/* - * Initialization routine (executed when library is loaded) - * Allocate fd tables and sets up signal handler. - */ -static void __attribute((constructor)) init() { - struct rlimit nbr_files; - sigset_t sigset; - struct sigaction sa; - - /* - * Allocate table based on the maximum number of - * file descriptors. - */ - getrlimit(RLIMIT_NOFILE, &nbr_files); - fdCount = nbr_files.rlim_max; - fdTable = (fdEntry_t *)calloc(fdCount, sizeof(fdEntry_t)); - if (fdTable == NULL) { - fprintf(stderr, "library initialization failed - " - "unable to allocate file descriptor table - out of memory"); - abort(); - } - - /* - * Setup the signal handler - */ - sa.sa_handler = sig_wakeup; - sa.sa_flags = 0; - sigemptyset(&sa.sa_mask); - sigaction(sigWakeup, &sa, NULL); - - sigemptyset(&sigset); - sigaddset(&sigset, sigWakeup); - sigprocmask(SIG_UNBLOCK, &sigset, NULL); -} - -/* - * Return the fd table for this fd or NULL is fd out - * of range. - */ -static inline fdEntry_t *getFdEntry(int fd) -{ - if (fd < 0 || fd >= fdCount) { - return NULL; - } - return &fdTable[fd]; -} - -/* - * Start a blocking operation :- - * Insert thread onto thread list for the fd. - */ -static inline void startOp(fdEntry_t *fdEntry, threadEntry_t *self) -{ - self->thr = pthread_self(); - self->intr = 0; - - pthread_mutex_lock(&(fdEntry->lock)); - { - self->next = fdEntry->threads; - fdEntry->threads = self; - } - pthread_mutex_unlock(&(fdEntry->lock)); -} - -/* - * End a blocking operation :- - * Remove thread from thread list for the fd - * If fd has been interrupted then set errno to EBADF - */ -static inline void endOp - (fdEntry_t *fdEntry, threadEntry_t *self) -{ - int orig_errno = errno; - pthread_mutex_lock(&(fdEntry->lock)); - { - threadEntry_t *curr, *prev=NULL; - curr = fdEntry->threads; - while (curr != NULL) { - if (curr == self) { - if (curr->intr) { - orig_errno = EBADF; - } - if (prev == NULL) { - fdEntry->threads = curr->next; - } else { - prev->next = curr->next; - } - break; - } - prev = curr; - curr = curr->next; - } - } - pthread_mutex_unlock(&(fdEntry->lock)); - errno = orig_errno; -} - -/* - * Close or dup2 a file descriptor ensuring that all threads blocked on - * the file descriptor are notified via a wakeup signal. - * - * fd1 < 0 => close(fd2) - * fd1 >= 0 => dup2(fd1, fd2) - * - * Returns -1 with errno set if operation fails. - */ -static int closefd(int fd1, int fd2) { - int rv, orig_errno; - fdEntry_t *fdEntry = getFdEntry(fd2); - if (fdEntry == NULL) { - errno = EBADF; - return -1; - } - - /* - * Lock the fd to hold-off additional I/O on this fd. - */ - pthread_mutex_lock(&(fdEntry->lock)); - - { - /* - * And close/dup the file descriptor - * (restart if interrupted by signal) - */ - do { - if (fd1 < 0) { - rv = close(fd2); - } else { - rv = dup2(fd1, fd2); - } - } while (rv == -1 && errno == EINTR); - - /* - * Send a wakeup signal to all threads blocked on this - * file descriptor. - */ - threadEntry_t *curr = fdEntry->threads; - while (curr != NULL) { - curr->intr = 1; - pthread_kill( curr->thr, sigWakeup ); - curr = curr->next; - } - } - - /* - * Unlock without destroying errno - */ - orig_errno = errno; - pthread_mutex_unlock(&(fdEntry->lock)); - errno = orig_errno; - - return rv; -} - -/* - * Wrapper for dup2 - same semantics as dup2 system call except - * that any threads blocked in an I/O system call on fd2 will be - * preempted and return -1/EBADF; - */ -int NET_Dup2(int fd, int fd2) { - if (fd < 0) { - errno = EBADF; - return -1; - } - return closefd(fd, fd2); -} - -/* - * Wrapper for close - same semantics as close system call - * except that any threads blocked in an I/O on fd will be - * preempted and the I/O system call will return -1/EBADF. - */ -int NET_SocketClose(int fd) { - return closefd(-1, fd); -} - -/************** Basic I/O operations here ***************/ - -/* - * Macro to perform a blocking IO operation. Restarts - * automatically if interrupted by signal (other than - * our wakeup signal) - */ -#define BLOCKING_IO_RETURN_INT(FD, FUNC) { \ - int ret; \ - threadEntry_t self; \ - fdEntry_t *fdEntry = getFdEntry(FD); \ - if (fdEntry == NULL) { \ - errno = EBADF; \ - return -1; \ - } \ - do { \ - startOp(fdEntry, &self); \ - ret = FUNC; \ - endOp(fdEntry, &self); \ - } while (ret == -1 && errno == EINTR); \ - return ret; \ -} - -int NET_Read(int s, void* buf, size_t len) { - BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, 0) ); -} - -int NET_ReadV(int s, const struct iovec * vector, int count) { - BLOCKING_IO_RETURN_INT( s, readv(s, vector, count) ); -} - -int NET_RecvFrom(int s, void *buf, int len, unsigned int flags, - struct sockaddr *from, socklen_t *fromlen) { - BLOCKING_IO_RETURN_INT( s, recvfrom(s, buf, len, flags, from, fromlen) ); -} - -int NET_Send(int s, void *msg, int len, unsigned int flags) { - BLOCKING_IO_RETURN_INT( s, send(s, msg, len, flags) ); -} - -int NET_WriteV(int s, const struct iovec * vector, int count) { - BLOCKING_IO_RETURN_INT( s, writev(s, vector, count) ); -} - -int NET_SendTo(int s, const void *msg, int len, unsigned int - flags, const struct sockaddr *to, int tolen) { - BLOCKING_IO_RETURN_INT( s, sendto(s, msg, len, flags, to, tolen) ); -} - -int NET_Accept(int s, struct sockaddr *addr, socklen_t *addrlen) { - BLOCKING_IO_RETURN_INT( s, accept(s, addr, addrlen) ); -} - -int NET_Connect(int s, struct sockaddr *addr, int addrlen) { - BLOCKING_IO_RETURN_INT( s, connect(s, addr, addrlen) ); -} - -int NET_Poll(struct pollfd *ufds, unsigned int nfds, int timeout) { - BLOCKING_IO_RETURN_INT( ufds[0].fd, poll(ufds, nfds, timeout) ); -} - -/* - * Wrapper for poll(s, timeout). - * Auto restarts with adjusted timeout if interrupted by - * signal other than our wakeup signal. - */ -int NET_Timeout(int s, long timeout) { - long prevtime = 0, newtime; - struct timeval t; - fdEntry_t *fdEntry = getFdEntry(s); - - /* - * Check that fd hasn't been closed. - */ - if (fdEntry == NULL) { - errno = EBADF; - return -1; - } - - /* - * Pick up current time as may need to adjust timeout - */ - if (timeout > 0) { - gettimeofday(&t, NULL); - prevtime = t.tv_sec * 1000 + t.tv_usec / 1000; - } - - for(;;) { - struct pollfd pfd; - int rv; - threadEntry_t self; - - /* - * Poll the fd. If interrupted by our wakeup signal - * errno will be set to EBADF. - */ - pfd.fd = s; - pfd.events = POLLIN | POLLERR; - - startOp(fdEntry, &self); - rv = poll(&pfd, 1, timeout); - endOp(fdEntry, &self); - - /* - * If interrupted then adjust timeout. If timeout - * has expired return 0 (indicating timeout expired). - */ - if (rv < 0 && errno == EINTR) { - if (timeout > 0) { - gettimeofday(&t, NULL); - newtime = t.tv_sec * 1000 + t.tv_usec / 1000; - timeout -= newtime - prevtime; - if (timeout <= 0) { - return 0; - } - prevtime = newtime; - } - } else { - return rv; - } - - } -} --- /dev/null 2015-01-08 08:58:23.458195824 +0100 +++ new/jdk/src/java.base/linux/native/libnet/linux_close.c 2015-01-23 17:25:15.841409303 +0100 @@ -0,0 +1,371 @@ +/* + * Copyright (c) 2001, 2013, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Stack allocated by thread when doing blocking operation + */ +typedef struct threadEntry { + pthread_t thr; /* this thread */ + struct threadEntry *next; /* next thread */ + int intr; /* interrupted */ +} threadEntry_t; + +/* + * Heap allocated during initialized - one entry per fd + */ +typedef struct { + pthread_mutex_t lock; /* fd lock */ + threadEntry_t *threads; /* threads blocked on fd */ +} fdEntry_t; + +/* + * Signal to unblock thread + */ +static int sigWakeup = (__SIGRTMAX - 2); + +/* + * The fd table and the number of file descriptors + */ +static fdEntry_t *fdTable; +static int fdCount; + +/* + * Null signal handler + */ +static void sig_wakeup(int sig) { +} + +/* + * Initialization routine (executed when library is loaded) + * Allocate fd tables and sets up signal handler. + */ +static void __attribute((constructor)) init() { + struct rlimit nbr_files; + sigset_t sigset; + struct sigaction sa; + + /* + * Allocate table based on the maximum number of + * file descriptors. + */ + getrlimit(RLIMIT_NOFILE, &nbr_files); + fdCount = nbr_files.rlim_max; + fdTable = (fdEntry_t *)calloc(fdCount, sizeof(fdEntry_t)); + if (fdTable == NULL) { + fprintf(stderr, "library initialization failed - " + "unable to allocate file descriptor table - out of memory"); + abort(); + } + + /* + * Setup the signal handler + */ + sa.sa_handler = sig_wakeup; + sa.sa_flags = 0; + sigemptyset(&sa.sa_mask); + sigaction(sigWakeup, &sa, NULL); + + sigemptyset(&sigset); + sigaddset(&sigset, sigWakeup); + sigprocmask(SIG_UNBLOCK, &sigset, NULL); +} + +/* + * Return the fd table for this fd or NULL is fd out + * of range. + */ +static inline fdEntry_t *getFdEntry(int fd) +{ + if (fd < 0 || fd >= fdCount) { + return NULL; + } + return &fdTable[fd]; +} + +/* + * Start a blocking operation :- + * Insert thread onto thread list for the fd. + */ +static inline void startOp(fdEntry_t *fdEntry, threadEntry_t *self) +{ + self->thr = pthread_self(); + self->intr = 0; + + pthread_mutex_lock(&(fdEntry->lock)); + { + self->next = fdEntry->threads; + fdEntry->threads = self; + } + pthread_mutex_unlock(&(fdEntry->lock)); +} + +/* + * End a blocking operation :- + * Remove thread from thread list for the fd + * If fd has been interrupted then set errno to EBADF + */ +static inline void endOp + (fdEntry_t *fdEntry, threadEntry_t *self) +{ + int orig_errno = errno; + pthread_mutex_lock(&(fdEntry->lock)); + { + threadEntry_t *curr, *prev=NULL; + curr = fdEntry->threads; + while (curr != NULL) { + if (curr == self) { + if (curr->intr) { + orig_errno = EBADF; + } + if (prev == NULL) { + fdEntry->threads = curr->next; + } else { + prev->next = curr->next; + } + break; + } + prev = curr; + curr = curr->next; + } + } + pthread_mutex_unlock(&(fdEntry->lock)); + errno = orig_errno; +} + +/* + * Close or dup2 a file descriptor ensuring that all threads blocked on + * the file descriptor are notified via a wakeup signal. + * + * fd1 < 0 => close(fd2) + * fd1 >= 0 => dup2(fd1, fd2) + * + * Returns -1 with errno set if operation fails. + */ +static int closefd(int fd1, int fd2) { + int rv, orig_errno; + fdEntry_t *fdEntry = getFdEntry(fd2); + if (fdEntry == NULL) { + errno = EBADF; + return -1; + } + + /* + * Lock the fd to hold-off additional I/O on this fd. + */ + pthread_mutex_lock(&(fdEntry->lock)); + + { + /* + * And close/dup the file descriptor + * (restart if interrupted by signal) + */ + do { + if (fd1 < 0) { + rv = close(fd2); + } else { + rv = dup2(fd1, fd2); + } + } while (rv == -1 && errno == EINTR); + + /* + * Send a wakeup signal to all threads blocked on this + * file descriptor. + */ + threadEntry_t *curr = fdEntry->threads; + while (curr != NULL) { + curr->intr = 1; + pthread_kill( curr->thr, sigWakeup ); + curr = curr->next; + } + } + + /* + * Unlock without destroying errno + */ + orig_errno = errno; + pthread_mutex_unlock(&(fdEntry->lock)); + errno = orig_errno; + + return rv; +} + +/* + * Wrapper for dup2 - same semantics as dup2 system call except + * that any threads blocked in an I/O system call on fd2 will be + * preempted and return -1/EBADF; + */ +int NET_Dup2(int fd, int fd2) { + if (fd < 0) { + errno = EBADF; + return -1; + } + return closefd(fd, fd2); +} + +/* + * Wrapper for close - same semantics as close system call + * except that any threads blocked in an I/O on fd will be + * preempted and the I/O system call will return -1/EBADF. + */ +int NET_SocketClose(int fd) { + return closefd(-1, fd); +} + +/************** Basic I/O operations here ***************/ + +/* + * Macro to perform a blocking IO operation. Restarts + * automatically if interrupted by signal (other than + * our wakeup signal) + */ +#define BLOCKING_IO_RETURN_INT(FD, FUNC) { \ + int ret; \ + threadEntry_t self; \ + fdEntry_t *fdEntry = getFdEntry(FD); \ + if (fdEntry == NULL) { \ + errno = EBADF; \ + return -1; \ + } \ + do { \ + startOp(fdEntry, &self); \ + ret = FUNC; \ + endOp(fdEntry, &self); \ + } while (ret == -1 && errno == EINTR); \ + return ret; \ +} + +int NET_Read(int s, void* buf, size_t len) { + BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, 0) ); +} + +int NET_ReadV(int s, const struct iovec * vector, int count) { + BLOCKING_IO_RETURN_INT( s, readv(s, vector, count) ); +} + +int NET_RecvFrom(int s, void *buf, int len, unsigned int flags, + struct sockaddr *from, socklen_t *fromlen) { + BLOCKING_IO_RETURN_INT( s, recvfrom(s, buf, len, flags, from, fromlen) ); +} + +int NET_Send(int s, void *msg, int len, unsigned int flags) { + BLOCKING_IO_RETURN_INT( s, send(s, msg, len, flags) ); +} + +int NET_WriteV(int s, const struct iovec * vector, int count) { + BLOCKING_IO_RETURN_INT( s, writev(s, vector, count) ); +} + +int NET_SendTo(int s, const void *msg, int len, unsigned int + flags, const struct sockaddr *to, int tolen) { + BLOCKING_IO_RETURN_INT( s, sendto(s, msg, len, flags, to, tolen) ); +} + +int NET_Accept(int s, struct sockaddr *addr, socklen_t *addrlen) { + BLOCKING_IO_RETURN_INT( s, accept(s, addr, addrlen) ); +} + +int NET_Connect(int s, struct sockaddr *addr, int addrlen) { + BLOCKING_IO_RETURN_INT( s, connect(s, addr, addrlen) ); +} + +int NET_Poll(struct pollfd *ufds, unsigned int nfds, int timeout) { + BLOCKING_IO_RETURN_INT( ufds[0].fd, poll(ufds, nfds, timeout) ); +} + +/* + * Wrapper for poll(s, timeout). + * Auto restarts with adjusted timeout if interrupted by + * signal other than our wakeup signal. + */ +int NET_Timeout(int s, long timeout) { + long prevtime = 0, newtime; + struct timeval t; + fdEntry_t *fdEntry = getFdEntry(s); + + /* + * Check that fd hasn't been closed. + */ + if (fdEntry == NULL) { + errno = EBADF; + return -1; + } + + /* + * Pick up current time as may need to adjust timeout + */ + if (timeout > 0) { + gettimeofday(&t, NULL); + prevtime = t.tv_sec * 1000 + t.tv_usec / 1000; + } + + for(;;) { + struct pollfd pfd; + int rv; + threadEntry_t self; + + /* + * Poll the fd. If interrupted by our wakeup signal + * errno will be set to EBADF. + */ + pfd.fd = s; + pfd.events = POLLIN | POLLERR; + + startOp(fdEntry, &self); + rv = poll(&pfd, 1, timeout); + endOp(fdEntry, &self); + + /* + * If interrupted then adjust timeout. If timeout + * has expired return 0 (indicating timeout expired). + */ + if (rv < 0 && errno == EINTR) { + if (timeout > 0) { + gettimeofday(&t, NULL); + newtime = t.tv_sec * 1000 + t.tv_usec / 1000; + timeout -= newtime - prevtime; + if (timeout <= 0) { + return 0; + } + prevtime = newtime; + } + } else { + return rv; + } + + } +} --- old/jdk/src/java.base/unix/native/libjava/java_props_macosx.c 2015-01-23 17:25:16.637442368 +0100 +++ /dev/null 2015-01-08 08:58:23.458195824 +0100 @@ -1,349 +0,0 @@ -/* - * Copyright (c) 1998, 2013, 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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. - */ - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "java_props_macosx.h" - - -// need dlopen/dlsym trick to avoid pulling in JavaRuntimeSupport before libjava.dylib is loaded -static void *getJRSFramework() { - static void *jrsFwk = NULL; - if (jrsFwk == NULL) { - jrsFwk = dlopen("/System/Library/Frameworks/JavaVM.framework/Frameworks/JavaRuntimeSupport.framework/JavaRuntimeSupport", RTLD_LAZY | RTLD_LOCAL); - } - return jrsFwk; -} - -char *getPosixLocale(int cat) { - char *lc = setlocale(cat, NULL); - if ((lc == NULL) || (strcmp(lc, "C") == 0)) { - lc = getenv("LANG"); - } - if (lc == NULL) return NULL; - return strdup(lc); -} - -#define LOCALEIDLENGTH 128 -char *getMacOSXLocale(int cat) { - switch (cat) { - case LC_MESSAGES: - { - void *jrsFwk = getJRSFramework(); - if (jrsFwk == NULL) return NULL; - - char *(*JRSCopyPrimaryLanguage)() = dlsym(jrsFwk, "JRSCopyPrimaryLanguage"); - char *primaryLanguage = JRSCopyPrimaryLanguage ? JRSCopyPrimaryLanguage() : NULL; - if (primaryLanguage == NULL) return NULL; - - char *(*JRSCopyCanonicalLanguageForPrimaryLanguage)(char *) = dlsym(jrsFwk, "JRSCopyCanonicalLanguageForPrimaryLanguage"); - char *canonicalLanguage = JRSCopyCanonicalLanguageForPrimaryLanguage ? JRSCopyCanonicalLanguageForPrimaryLanguage(primaryLanguage) : NULL; - free (primaryLanguage); - - return canonicalLanguage; - } - break; - default: - { - char localeString[LOCALEIDLENGTH]; - if (CFStringGetCString(CFLocaleGetIdentifier(CFLocaleCopyCurrent()), - localeString, LOCALEIDLENGTH, CFStringGetSystemEncoding())) { - return strdup(localeString); - } - } - break; - } - - return NULL; -} - -char *setupMacOSXLocale(int cat) { - char * ret = getMacOSXLocale(cat); - - if (cat == LC_MESSAGES && ret != NULL) { - void *jrsFwk = getJRSFramework(); - if (jrsFwk != NULL) { - void (*JRSSetDefaultLocalization)(char *) = dlsym(jrsFwk, "JRSSetDefaultLocalization"); - if (JRSSetDefaultLocalization) JRSSetDefaultLocalization(ret); - } - } - - if (ret == NULL) { - return getPosixLocale(cat); - } else { - return ret; - } -} - -int isInAquaSession() { - // environment variable to bypass the aqua session check - char *ev = getenv("AWT_FORCE_HEADFUL"); - if (ev && (strncasecmp(ev, "true", 4) == 0)) { - // if "true" then tell the caller we're in an Aqua session without actually checking - return 1; - } - // Is the WindowServer available? - SecuritySessionId session_id; - SessionAttributeBits session_info; - OSStatus status = SessionGetInfo(callerSecuritySession, &session_id, &session_info); - if (status == noErr) { - if (session_info & sessionHasGraphicAccess) { - return 1; - } - } - return 0; -} - -void setOSNameAndVersion(java_props_t *sprops) { - /* Don't rely on JRSCopyOSName because there's no guarantee the value will - * remain the same, or even if the JRS functions will continue to be part of - * Mac OS X. So hardcode os_name, and fill in os_version if we can. - */ - sprops->os_name = strdup("Mac OS X"); - - void *jrsFwk = getJRSFramework(); - if (jrsFwk != NULL) { - char *(*copyOSVersion)() = dlsym(jrsFwk, "JRSCopyOSVersion"); - if (copyOSVersion != NULL) { - sprops->os_version = copyOSVersion(); - return; - } - } - sprops->os_version = strdup("Unknown"); -} - - -static Boolean getProxyInfoForProtocol(CFDictionaryRef inDict, CFStringRef inEnabledKey, CFStringRef inHostKey, CFStringRef inPortKey, CFStringRef *outProxyHost, int *ioProxyPort) { - /* See if the proxy is enabled. */ - CFNumberRef cf_enabled = CFDictionaryGetValue(inDict, inEnabledKey); - if (cf_enabled == NULL) { - return false; - } - - int isEnabled = false; - if (!CFNumberGetValue(cf_enabled, kCFNumberIntType, &isEnabled)) { - return isEnabled; - } - - if (!isEnabled) return false; - *outProxyHost = CFDictionaryGetValue(inDict, inHostKey); - - // If cf_host is null, that means the checkbox is set, - // but no host was entered. We'll treat that as NOT ENABLED. - // If cf_port is null or cf_port isn't a number, that means - // no port number was entered. Treat this as ENABLED with the - // protocol's default port. - if (*outProxyHost == NULL) { - return false; - } - - if (CFStringGetLength(*outProxyHost) == 0) { - return false; - } - - int newPort = 0; - CFNumberRef cf_port = NULL; - if ((cf_port = CFDictionaryGetValue(inDict, inPortKey)) != NULL && - CFNumberGetValue(cf_port, kCFNumberIntType, &newPort) && - newPort > 0) { - *ioProxyPort = newPort; - } else { - // bad port or no port - leave *ioProxyPort unchanged - } - - return true; -} - -static char *createUTF8CString(const CFStringRef theString) { - if (theString == NULL) return NULL; - - const CFIndex stringLength = CFStringGetLength(theString); - const CFIndex bufSize = CFStringGetMaximumSizeForEncoding(stringLength, kCFStringEncodingUTF8) + 1; - char *returnVal = (char *)malloc(bufSize); - - if (CFStringGetCString(theString, returnVal, bufSize, kCFStringEncodingUTF8)) { - return returnVal; - } - - free(returnVal); - return NULL; -} - -// Return TRUE if str is a syntactically valid IP address. -// Using inet_pton() instead of inet_aton() for IPv6 support. -// len is only a hint; cstr must still be nul-terminated -static int looksLikeIPAddress(char *cstr, size_t len) { - if (len == 0 || (len == 1 && cstr[0] == '.')) return FALSE; - - char dst[16]; // big enough for INET6 - return (1 == inet_pton(AF_INET, cstr, dst) || - 1 == inet_pton(AF_INET6, cstr, dst)); -} - - - -// Convert Mac OS X proxy exception entry to Java syntax. -// See Radar #3441134 for details. -// Returns NULL if this exception should be ignored by Java. -// May generate a string with multiple exceptions separated by '|'. -static char * createConvertedException(CFStringRef cf_original) { - // This is done with char* instead of CFString because inet_pton() - // needs a C string. - char *c_exception = createUTF8CString(cf_original); - if (!c_exception) return NULL; - - int c_len = strlen(c_exception); - - // 1. sanitize exception prefix - if (c_len >= 1 && 0 == strncmp(c_exception, ".", 1)) { - memmove(c_exception, c_exception+1, c_len); - c_len -= 1; - } else if (c_len >= 2 && 0 == strncmp(c_exception, "*.", 2)) { - memmove(c_exception, c_exception+2, c_len-1); - c_len -= 2; - } - - // 2. pre-reject other exception wildcards - if (strchr(c_exception, '*')) { - free(c_exception); - return NULL; - } - - // 3. no IP wildcarding - if (looksLikeIPAddress(c_exception, c_len)) { - return c_exception; - } - - // 4. allow domain suffixes - // c_exception is now "str\0" - change to "str|*.str\0" - c_exception = reallocf(c_exception, c_len+3+c_len+1); - if (!c_exception) return NULL; - - strncpy(c_exception+c_len, "|*.", 3); - strncpy(c_exception+c_len+3, c_exception, c_len); - c_exception[c_len+3+c_len] = '\0'; - return c_exception; -} - -/* - * Method for fetching the user.home path and storing it in the property list. - * For signed .apps running in the Mac App Sandbox, user.home is set to the - * app's sandbox container. - */ -void setUserHome(java_props_t *sprops) { - if (sprops == NULL) { return; } - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - sprops->user_home = createUTF8CString((CFStringRef)NSHomeDirectory()); - [pool drain]; -} - -/* - * Method for fetching proxy info and storing it in the property list. - */ -void setProxyProperties(java_props_t *sProps) { - if (sProps == NULL) return; - - char buf[16]; /* Used for %d of an int - 16 is plenty */ - CFStringRef - cf_httpHost = NULL, - cf_httpsHost = NULL, - cf_ftpHost = NULL, - cf_socksHost = NULL, - cf_gopherHost = NULL; - int - httpPort = 80, // Default proxy port values - httpsPort = 443, - ftpPort = 21, - socksPort = 1080, - gopherPort = 70; - - CFDictionaryRef dict = SCDynamicStoreCopyProxies(NULL); - if (dict == NULL) return; - - /* Read the proxy exceptions list */ - CFArrayRef cf_list = CFDictionaryGetValue(dict, kSCPropNetProxiesExceptionsList); - - CFMutableStringRef cf_exceptionList = NULL; - if (cf_list != NULL) { - CFIndex len = CFArrayGetCount(cf_list), idx; - - cf_exceptionList = CFStringCreateMutable(NULL, 0); - for (idx = (CFIndex)0; idx < len; idx++) { - CFStringRef cf_ehost; - if ((cf_ehost = CFArrayGetValueAtIndex(cf_list, idx))) { - /* Convert this exception from Mac OS X syntax to Java syntax. - See Radar #3441134 for details. This may generate a string - with multiple Java exceptions separated by '|'. */ - char *c_exception = createConvertedException(cf_ehost); - if (c_exception) { - /* Append the host to the list of exclusions. */ - if (CFStringGetLength(cf_exceptionList) > 0) { - CFStringAppendCString(cf_exceptionList, "|", kCFStringEncodingMacRoman); - } - CFStringAppendCString(cf_exceptionList, c_exception, kCFStringEncodingMacRoman); - free(c_exception); - } - } - } - } - - if (cf_exceptionList != NULL) { - if (CFStringGetLength(cf_exceptionList) > 0) { - sProps->exceptionList = createUTF8CString(cf_exceptionList); - } - CFRelease(cf_exceptionList); - } - -#define CHECK_PROXY(protocol, PROTOCOL) \ - sProps->protocol##ProxyEnabled = \ - getProxyInfoForProtocol(dict, kSCPropNetProxies##PROTOCOL##Enable, \ - kSCPropNetProxies##PROTOCOL##Proxy, \ - kSCPropNetProxies##PROTOCOL##Port, \ - &cf_##protocol##Host, &protocol##Port); \ - if (sProps->protocol##ProxyEnabled) { \ - sProps->protocol##Host = createUTF8CString(cf_##protocol##Host); \ - snprintf(buf, sizeof(buf), "%d", protocol##Port); \ - sProps->protocol##Port = malloc(strlen(buf) + 1); \ - strcpy(sProps->protocol##Port, buf); \ - } - - CHECK_PROXY(http, HTTP); - CHECK_PROXY(https, HTTPS); - CHECK_PROXY(ftp, FTP); - CHECK_PROXY(socks, SOCKS); - CHECK_PROXY(gopher, Gopher); - -#undef CHECK_PROXY - - CFRelease(dict); -} --- /dev/null 2015-01-08 08:58:23.458195824 +0100 +++ new/jdk/src/java.base/macosx/native/libjava/java_props_macosx.c 2015-01-23 17:25:16.337429907 +0100 @@ -0,0 +1,349 @@ +/* + * Copyright (c) 1998, 2013, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "java_props_macosx.h" + + +// need dlopen/dlsym trick to avoid pulling in JavaRuntimeSupport before libjava.dylib is loaded +static void *getJRSFramework() { + static void *jrsFwk = NULL; + if (jrsFwk == NULL) { + jrsFwk = dlopen("/System/Library/Frameworks/JavaVM.framework/Frameworks/JavaRuntimeSupport.framework/JavaRuntimeSupport", RTLD_LAZY | RTLD_LOCAL); + } + return jrsFwk; +} + +char *getPosixLocale(int cat) { + char *lc = setlocale(cat, NULL); + if ((lc == NULL) || (strcmp(lc, "C") == 0)) { + lc = getenv("LANG"); + } + if (lc == NULL) return NULL; + return strdup(lc); +} + +#define LOCALEIDLENGTH 128 +char *getMacOSXLocale(int cat) { + switch (cat) { + case LC_MESSAGES: + { + void *jrsFwk = getJRSFramework(); + if (jrsFwk == NULL) return NULL; + + char *(*JRSCopyPrimaryLanguage)() = dlsym(jrsFwk, "JRSCopyPrimaryLanguage"); + char *primaryLanguage = JRSCopyPrimaryLanguage ? JRSCopyPrimaryLanguage() : NULL; + if (primaryLanguage == NULL) return NULL; + + char *(*JRSCopyCanonicalLanguageForPrimaryLanguage)(char *) = dlsym(jrsFwk, "JRSCopyCanonicalLanguageForPrimaryLanguage"); + char *canonicalLanguage = JRSCopyCanonicalLanguageForPrimaryLanguage ? JRSCopyCanonicalLanguageForPrimaryLanguage(primaryLanguage) : NULL; + free (primaryLanguage); + + return canonicalLanguage; + } + break; + default: + { + char localeString[LOCALEIDLENGTH]; + if (CFStringGetCString(CFLocaleGetIdentifier(CFLocaleCopyCurrent()), + localeString, LOCALEIDLENGTH, CFStringGetSystemEncoding())) { + return strdup(localeString); + } + } + break; + } + + return NULL; +} + +char *setupMacOSXLocale(int cat) { + char * ret = getMacOSXLocale(cat); + + if (cat == LC_MESSAGES && ret != NULL) { + void *jrsFwk = getJRSFramework(); + if (jrsFwk != NULL) { + void (*JRSSetDefaultLocalization)(char *) = dlsym(jrsFwk, "JRSSetDefaultLocalization"); + if (JRSSetDefaultLocalization) JRSSetDefaultLocalization(ret); + } + } + + if (ret == NULL) { + return getPosixLocale(cat); + } else { + return ret; + } +} + +int isInAquaSession() { + // environment variable to bypass the aqua session check + char *ev = getenv("AWT_FORCE_HEADFUL"); + if (ev && (strncasecmp(ev, "true", 4) == 0)) { + // if "true" then tell the caller we're in an Aqua session without actually checking + return 1; + } + // Is the WindowServer available? + SecuritySessionId session_id; + SessionAttributeBits session_info; + OSStatus status = SessionGetInfo(callerSecuritySession, &session_id, &session_info); + if (status == noErr) { + if (session_info & sessionHasGraphicAccess) { + return 1; + } + } + return 0; +} + +void setOSNameAndVersion(java_props_t *sprops) { + /* Don't rely on JRSCopyOSName because there's no guarantee the value will + * remain the same, or even if the JRS functions will continue to be part of + * Mac OS X. So hardcode os_name, and fill in os_version if we can. + */ + sprops->os_name = strdup("Mac OS X"); + + void *jrsFwk = getJRSFramework(); + if (jrsFwk != NULL) { + char *(*copyOSVersion)() = dlsym(jrsFwk, "JRSCopyOSVersion"); + if (copyOSVersion != NULL) { + sprops->os_version = copyOSVersion(); + return; + } + } + sprops->os_version = strdup("Unknown"); +} + + +static Boolean getProxyInfoForProtocol(CFDictionaryRef inDict, CFStringRef inEnabledKey, CFStringRef inHostKey, CFStringRef inPortKey, CFStringRef *outProxyHost, int *ioProxyPort) { + /* See if the proxy is enabled. */ + CFNumberRef cf_enabled = CFDictionaryGetValue(inDict, inEnabledKey); + if (cf_enabled == NULL) { + return false; + } + + int isEnabled = false; + if (!CFNumberGetValue(cf_enabled, kCFNumberIntType, &isEnabled)) { + return isEnabled; + } + + if (!isEnabled) return false; + *outProxyHost = CFDictionaryGetValue(inDict, inHostKey); + + // If cf_host is null, that means the checkbox is set, + // but no host was entered. We'll treat that as NOT ENABLED. + // If cf_port is null or cf_port isn't a number, that means + // no port number was entered. Treat this as ENABLED with the + // protocol's default port. + if (*outProxyHost == NULL) { + return false; + } + + if (CFStringGetLength(*outProxyHost) == 0) { + return false; + } + + int newPort = 0; + CFNumberRef cf_port = NULL; + if ((cf_port = CFDictionaryGetValue(inDict, inPortKey)) != NULL && + CFNumberGetValue(cf_port, kCFNumberIntType, &newPort) && + newPort > 0) { + *ioProxyPort = newPort; + } else { + // bad port or no port - leave *ioProxyPort unchanged + } + + return true; +} + +static char *createUTF8CString(const CFStringRef theString) { + if (theString == NULL) return NULL; + + const CFIndex stringLength = CFStringGetLength(theString); + const CFIndex bufSize = CFStringGetMaximumSizeForEncoding(stringLength, kCFStringEncodingUTF8) + 1; + char *returnVal = (char *)malloc(bufSize); + + if (CFStringGetCString(theString, returnVal, bufSize, kCFStringEncodingUTF8)) { + return returnVal; + } + + free(returnVal); + return NULL; +} + +// Return TRUE if str is a syntactically valid IP address. +// Using inet_pton() instead of inet_aton() for IPv6 support. +// len is only a hint; cstr must still be nul-terminated +static int looksLikeIPAddress(char *cstr, size_t len) { + if (len == 0 || (len == 1 && cstr[0] == '.')) return FALSE; + + char dst[16]; // big enough for INET6 + return (1 == inet_pton(AF_INET, cstr, dst) || + 1 == inet_pton(AF_INET6, cstr, dst)); +} + + + +// Convert Mac OS X proxy exception entry to Java syntax. +// See Radar #3441134 for details. +// Returns NULL if this exception should be ignored by Java. +// May generate a string with multiple exceptions separated by '|'. +static char * createConvertedException(CFStringRef cf_original) { + // This is done with char* instead of CFString because inet_pton() + // needs a C string. + char *c_exception = createUTF8CString(cf_original); + if (!c_exception) return NULL; + + int c_len = strlen(c_exception); + + // 1. sanitize exception prefix + if (c_len >= 1 && 0 == strncmp(c_exception, ".", 1)) { + memmove(c_exception, c_exception+1, c_len); + c_len -= 1; + } else if (c_len >= 2 && 0 == strncmp(c_exception, "*.", 2)) { + memmove(c_exception, c_exception+2, c_len-1); + c_len -= 2; + } + + // 2. pre-reject other exception wildcards + if (strchr(c_exception, '*')) { + free(c_exception); + return NULL; + } + + // 3. no IP wildcarding + if (looksLikeIPAddress(c_exception, c_len)) { + return c_exception; + } + + // 4. allow domain suffixes + // c_exception is now "str\0" - change to "str|*.str\0" + c_exception = reallocf(c_exception, c_len+3+c_len+1); + if (!c_exception) return NULL; + + strncpy(c_exception+c_len, "|*.", 3); + strncpy(c_exception+c_len+3, c_exception, c_len); + c_exception[c_len+3+c_len] = '\0'; + return c_exception; +} + +/* + * Method for fetching the user.home path and storing it in the property list. + * For signed .apps running in the Mac App Sandbox, user.home is set to the + * app's sandbox container. + */ +void setUserHome(java_props_t *sprops) { + if (sprops == NULL) { return; } + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + sprops->user_home = createUTF8CString((CFStringRef)NSHomeDirectory()); + [pool drain]; +} + +/* + * Method for fetching proxy info and storing it in the property list. + */ +void setProxyProperties(java_props_t *sProps) { + if (sProps == NULL) return; + + char buf[16]; /* Used for %d of an int - 16 is plenty */ + CFStringRef + cf_httpHost = NULL, + cf_httpsHost = NULL, + cf_ftpHost = NULL, + cf_socksHost = NULL, + cf_gopherHost = NULL; + int + httpPort = 80, // Default proxy port values + httpsPort = 443, + ftpPort = 21, + socksPort = 1080, + gopherPort = 70; + + CFDictionaryRef dict = SCDynamicStoreCopyProxies(NULL); + if (dict == NULL) return; + + /* Read the proxy exceptions list */ + CFArrayRef cf_list = CFDictionaryGetValue(dict, kSCPropNetProxiesExceptionsList); + + CFMutableStringRef cf_exceptionList = NULL; + if (cf_list != NULL) { + CFIndex len = CFArrayGetCount(cf_list), idx; + + cf_exceptionList = CFStringCreateMutable(NULL, 0); + for (idx = (CFIndex)0; idx < len; idx++) { + CFStringRef cf_ehost; + if ((cf_ehost = CFArrayGetValueAtIndex(cf_list, idx))) { + /* Convert this exception from Mac OS X syntax to Java syntax. + See Radar #3441134 for details. This may generate a string + with multiple Java exceptions separated by '|'. */ + char *c_exception = createConvertedException(cf_ehost); + if (c_exception) { + /* Append the host to the list of exclusions. */ + if (CFStringGetLength(cf_exceptionList) > 0) { + CFStringAppendCString(cf_exceptionList, "|", kCFStringEncodingMacRoman); + } + CFStringAppendCString(cf_exceptionList, c_exception, kCFStringEncodingMacRoman); + free(c_exception); + } + } + } + } + + if (cf_exceptionList != NULL) { + if (CFStringGetLength(cf_exceptionList) > 0) { + sProps->exceptionList = createUTF8CString(cf_exceptionList); + } + CFRelease(cf_exceptionList); + } + +#define CHECK_PROXY(protocol, PROTOCOL) \ + sProps->protocol##ProxyEnabled = \ + getProxyInfoForProtocol(dict, kSCPropNetProxies##PROTOCOL##Enable, \ + kSCPropNetProxies##PROTOCOL##Proxy, \ + kSCPropNetProxies##PROTOCOL##Port, \ + &cf_##protocol##Host, &protocol##Port); \ + if (sProps->protocol##ProxyEnabled) { \ + sProps->protocol##Host = createUTF8CString(cf_##protocol##Host); \ + snprintf(buf, sizeof(buf), "%d", protocol##Port); \ + sProps->protocol##Port = malloc(strlen(buf) + 1); \ + strcpy(sProps->protocol##Port, buf); \ + } + + CHECK_PROXY(http, HTTP); + CHECK_PROXY(https, HTTPS); + CHECK_PROXY(ftp, FTP); + CHECK_PROXY(socks, SOCKS); + CHECK_PROXY(gopher, Gopher); + +#undef CHECK_PROXY + + CFRelease(dict); +} --- old/jdk/src/java.base/unix/native/libjava/java_props_macosx.h 2015-01-23 17:25:17.121462472 +0100 +++ /dev/null 2015-01-08 08:58:23.458195824 +0100 @@ -1,32 +0,0 @@ -/* - * Copyright (c) 1998, 2013, 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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. - */ - -#include "java_props.h" - -char *setupMacOSXLocale(int cat); -void setOSNameAndVersion(java_props_t *sprops); -void setUserHome(java_props_t *sprops); -void setProxyProperties(java_props_t *sProps); -int isInAquaSession(); --- /dev/null 2015-01-08 08:58:23.458195824 +0100 +++ new/jdk/src/java.base/macosx/native/libjava/java_props_macosx.h 2015-01-23 17:25:16.829450343 +0100 @@ -0,0 +1,32 @@ +/* + * Copyright (c) 1998, 2013, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +#include "java_props.h" + +char *setupMacOSXLocale(int cat); +void setOSNameAndVersion(java_props_t *sprops); +void setUserHome(java_props_t *sprops); +void setProxyProperties(java_props_t *sProps); +int isInAquaSession(); --- old/jdk/src/java.base/unix/native/libnet/bsd_close.c 2015-01-23 17:25:17.605482577 +0100 +++ /dev/null 2015-01-08 08:58:23.458195824 +0100 @@ -1,421 +0,0 @@ -/* - * Copyright (c) 2001, 2012, 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Stack allocated by thread when doing blocking operation - */ -typedef struct threadEntry { - pthread_t thr; /* this thread */ - struct threadEntry *next; /* next thread */ - int intr; /* interrupted */ -} threadEntry_t; - -/* - * Heap allocated during initialized - one entry per fd - */ -typedef struct { - pthread_mutex_t lock; /* fd lock */ - threadEntry_t *threads; /* threads blocked on fd */ -} fdEntry_t; - -/* - * Signal to unblock thread - */ -static int sigWakeup = SIGIO; - -/* - * The fd table and the number of file descriptors - */ -static fdEntry_t *fdTable; -static int fdCount; - -/* - * This limit applies if getlimit() returns unlimited. - * Unfortunately, this means if someone wants a higher limit - * then they have to set an explicit limit, higher than this, - * which is probably counter-intuitive. - */ -#define MAX_FD_COUNT 4096 - -/* - * Null signal handler - */ -static void sig_wakeup(int sig) { -} - -/* - * Initialization routine (executed when library is loaded) - * Allocate fd tables and sets up signal handler. - */ -static void __attribute((constructor)) init() { - struct rlimit nbr_files; - sigset_t sigset; - struct sigaction sa; - int i; - - /* - * Allocate table based on the maximum number of - * file descriptors. - */ - getrlimit(RLIMIT_NOFILE, &nbr_files); - if (nbr_files.rlim_max == RLIM_INFINITY) { - fdCount = MAX_FD_COUNT; - } else { - fdCount = nbr_files.rlim_max; - } - fdTable = (fdEntry_t *)calloc(fdCount, sizeof(fdEntry_t)); - if (fdTable == NULL) { - fprintf(stderr, "library initialization failed - " - "unable to allocate file descriptor table - out of memory"); - abort(); - } - for (i=0; i= fdCount) { - return NULL; - } - return &fdTable[fd]; -} - -/* - * Start a blocking operation :- - * Insert thread onto thread list for the fd. - */ -static inline void startOp(fdEntry_t *fdEntry, threadEntry_t *self) -{ - self->thr = pthread_self(); - self->intr = 0; - - pthread_mutex_lock(&(fdEntry->lock)); - { - self->next = fdEntry->threads; - fdEntry->threads = self; - } - pthread_mutex_unlock(&(fdEntry->lock)); -} - -/* - * End a blocking operation :- - * Remove thread from thread list for the fd - * If fd has been interrupted then set errno to EBADF - */ -static inline void endOp - (fdEntry_t *fdEntry, threadEntry_t *self) -{ - int orig_errno = errno; - pthread_mutex_lock(&(fdEntry->lock)); - { - threadEntry_t *curr, *prev=NULL; - curr = fdEntry->threads; - while (curr != NULL) { - if (curr == self) { - if (curr->intr) { - orig_errno = EBADF; - } - if (prev == NULL) { - fdEntry->threads = curr->next; - } else { - prev->next = curr->next; - } - break; - } - prev = curr; - curr = curr->next; - } - } - pthread_mutex_unlock(&(fdEntry->lock)); - errno = orig_errno; -} - -/* - * Close or dup2 a file descriptor ensuring that all threads blocked on - * the file descriptor are notified via a wakeup signal. - * - * fd1 < 0 => close(fd2) - * fd1 >= 0 => dup2(fd1, fd2) - * - * Returns -1 with errno set if operation fails. - */ -static int closefd(int fd1, int fd2) { - int rv, orig_errno; - fdEntry_t *fdEntry = getFdEntry(fd2); - if (fdEntry == NULL) { - errno = EBADF; - return -1; - } - - /* - * Lock the fd to hold-off additional I/O on this fd. - */ - pthread_mutex_lock(&(fdEntry->lock)); - - { - /* - * Send a wakeup signal to all threads blocked on this - * file descriptor. - */ - threadEntry_t *curr = fdEntry->threads; - while (curr != NULL) { - curr->intr = 1; - pthread_kill( curr->thr, sigWakeup ); - curr = curr->next; - } - - /* - * And close/dup the file descriptor - * (restart if interrupted by signal) - */ - do { - if (fd1 < 0) { - rv = close(fd2); - } else { - rv = dup2(fd1, fd2); - } - } while (rv == -1 && errno == EINTR); - - } - - /* - * Unlock without destroying errno - */ - orig_errno = errno; - pthread_mutex_unlock(&(fdEntry->lock)); - errno = orig_errno; - - return rv; -} - -/* - * Wrapper for dup2 - same semantics as dup2 system call except - * that any threads blocked in an I/O system call on fd2 will be - * preempted and return -1/EBADF; - */ -int NET_Dup2(int fd, int fd2) { - if (fd < 0) { - errno = EBADF; - return -1; - } - return closefd(fd, fd2); -} - -/* - * Wrapper for close - same semantics as close system call - * except that any threads blocked in an I/O on fd will be - * preempted and the I/O system call will return -1/EBADF. - */ -int NET_SocketClose(int fd) { - return closefd(-1, fd); -} - -/************** Basic I/O operations here ***************/ - -/* - * Macro to perform a blocking IO operation. Restarts - * automatically if interrupted by signal (other than - * our wakeup signal) - */ -#define BLOCKING_IO_RETURN_INT(FD, FUNC) { \ - int ret; \ - threadEntry_t self; \ - fdEntry_t *fdEntry = getFdEntry(FD); \ - if (fdEntry == NULL) { \ - errno = EBADF; \ - return -1; \ - } \ - do { \ - startOp(fdEntry, &self); \ - ret = FUNC; \ - endOp(fdEntry, &self); \ - } while (ret == -1 && errno == EINTR); \ - return ret; \ -} - -int NET_Read(int s, void* buf, size_t len) { - BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, 0) ); -} - -int NET_ReadV(int s, const struct iovec * vector, int count) { - BLOCKING_IO_RETURN_INT( s, readv(s, vector, count) ); -} - -int NET_RecvFrom(int s, void *buf, int len, unsigned int flags, - struct sockaddr *from, socklen_t *fromlen) { - BLOCKING_IO_RETURN_INT( s, recvfrom(s, buf, len, flags, from, fromlen) ); -} - -int NET_Send(int s, void *msg, int len, unsigned int flags) { - BLOCKING_IO_RETURN_INT( s, send(s, msg, len, flags) ); -} - -int NET_WriteV(int s, const struct iovec * vector, int count) { - BLOCKING_IO_RETURN_INT( s, writev(s, vector, count) ); -} - -int NET_SendTo(int s, const void *msg, int len, unsigned int - flags, const struct sockaddr *to, int tolen) { - BLOCKING_IO_RETURN_INT( s, sendto(s, msg, len, flags, to, tolen) ); -} - -int NET_Accept(int s, struct sockaddr *addr, socklen_t *addrlen) { - BLOCKING_IO_RETURN_INT( s, accept(s, addr, addrlen) ); -} - -int NET_Connect(int s, struct sockaddr *addr, int addrlen) { - BLOCKING_IO_RETURN_INT( s, connect(s, addr, addrlen) ); -} - -int NET_Poll(struct pollfd *ufds, unsigned int nfds, int timeout) { - BLOCKING_IO_RETURN_INT( ufds[0].fd, poll(ufds, nfds, timeout) ); -} - -/* - * Wrapper for select(s, timeout). We are using select() on Mac OS due to Bug 7131399. - * Auto restarts with adjusted timeout if interrupted by - * signal other than our wakeup signal. - */ -int NET_Timeout(int s, long timeout) { - long prevtime = 0, newtime; - struct timeval t, *tp = &t; - fd_set fds; - fd_set* fdsp = NULL; - int allocated = 0; - threadEntry_t self; - fdEntry_t *fdEntry = getFdEntry(s); - - /* - * Check that fd hasn't been closed. - */ - if (fdEntry == NULL) { - errno = EBADF; - return -1; - } - - /* - * Pick up current time as may need to adjust timeout - */ - if (timeout > 0) { - /* Timed */ - struct timeval now; - gettimeofday(&now, NULL); - prevtime = now.tv_sec * 1000 + now.tv_usec / 1000; - t.tv_sec = timeout / 1000; - t.tv_usec = (timeout % 1000) * 1000; - } else if (timeout < 0) { - /* Blocking */ - tp = 0; - } else { - /* Poll */ - t.tv_sec = 0; - t.tv_usec = 0; - } - - if (s < FD_SETSIZE) { - fdsp = &fds; - FD_ZERO(fdsp); - } else { - int length = (howmany(s+1, NFDBITS)) * sizeof(int); - fdsp = (fd_set *) calloc(1, length); - if (fdsp == NULL) { - return -1; // errno will be set to ENOMEM - } - allocated = 1; - } - FD_SET(s, fdsp); - - for(;;) { - int rv; - - /* - * call select on the fd. If interrupted by our wakeup signal - * errno will be set to EBADF. - */ - - startOp(fdEntry, &self); - rv = select(s+1, fdsp, 0, 0, tp); - endOp(fdEntry, &self); - - /* - * If interrupted then adjust timeout. If timeout - * has expired return 0 (indicating timeout expired). - */ - if (rv < 0 && errno == EINTR) { - if (timeout > 0) { - struct timeval now; - gettimeofday(&now, NULL); - newtime = now.tv_sec * 1000 + now.tv_usec / 1000; - timeout -= newtime - prevtime; - if (timeout <= 0) { - if (allocated != 0) - free(fdsp); - return 0; - } - prevtime = newtime; - t.tv_sec = timeout / 1000; - t.tv_usec = (timeout % 1000) * 1000; - } - } else { - if (allocated != 0) - free(fdsp); - return rv; - } - - } -} --- /dev/null 2015-01-08 08:58:23.458195824 +0100 +++ new/jdk/src/java.base/macosx/native/libnet/bsd_close.c 2015-01-23 17:25:17.313470448 +0100 @@ -0,0 +1,421 @@ +/* + * Copyright (c) 2001, 2012, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Stack allocated by thread when doing blocking operation + */ +typedef struct threadEntry { + pthread_t thr; /* this thread */ + struct threadEntry *next; /* next thread */ + int intr; /* interrupted */ +} threadEntry_t; + +/* + * Heap allocated during initialized - one entry per fd + */ +typedef struct { + pthread_mutex_t lock; /* fd lock */ + threadEntry_t *threads; /* threads blocked on fd */ +} fdEntry_t; + +/* + * Signal to unblock thread + */ +static int sigWakeup = SIGIO; + +/* + * The fd table and the number of file descriptors + */ +static fdEntry_t *fdTable; +static int fdCount; + +/* + * This limit applies if getlimit() returns unlimited. + * Unfortunately, this means if someone wants a higher limit + * then they have to set an explicit limit, higher than this, + * which is probably counter-intuitive. + */ +#define MAX_FD_COUNT 4096 + +/* + * Null signal handler + */ +static void sig_wakeup(int sig) { +} + +/* + * Initialization routine (executed when library is loaded) + * Allocate fd tables and sets up signal handler. + */ +static void __attribute((constructor)) init() { + struct rlimit nbr_files; + sigset_t sigset; + struct sigaction sa; + int i; + + /* + * Allocate table based on the maximum number of + * file descriptors. + */ + getrlimit(RLIMIT_NOFILE, &nbr_files); + if (nbr_files.rlim_max == RLIM_INFINITY) { + fdCount = MAX_FD_COUNT; + } else { + fdCount = nbr_files.rlim_max; + } + fdTable = (fdEntry_t *)calloc(fdCount, sizeof(fdEntry_t)); + if (fdTable == NULL) { + fprintf(stderr, "library initialization failed - " + "unable to allocate file descriptor table - out of memory"); + abort(); + } + for (i=0; i= fdCount) { + return NULL; + } + return &fdTable[fd]; +} + +/* + * Start a blocking operation :- + * Insert thread onto thread list for the fd. + */ +static inline void startOp(fdEntry_t *fdEntry, threadEntry_t *self) +{ + self->thr = pthread_self(); + self->intr = 0; + + pthread_mutex_lock(&(fdEntry->lock)); + { + self->next = fdEntry->threads; + fdEntry->threads = self; + } + pthread_mutex_unlock(&(fdEntry->lock)); +} + +/* + * End a blocking operation :- + * Remove thread from thread list for the fd + * If fd has been interrupted then set errno to EBADF + */ +static inline void endOp + (fdEntry_t *fdEntry, threadEntry_t *self) +{ + int orig_errno = errno; + pthread_mutex_lock(&(fdEntry->lock)); + { + threadEntry_t *curr, *prev=NULL; + curr = fdEntry->threads; + while (curr != NULL) { + if (curr == self) { + if (curr->intr) { + orig_errno = EBADF; + } + if (prev == NULL) { + fdEntry->threads = curr->next; + } else { + prev->next = curr->next; + } + break; + } + prev = curr; + curr = curr->next; + } + } + pthread_mutex_unlock(&(fdEntry->lock)); + errno = orig_errno; +} + +/* + * Close or dup2 a file descriptor ensuring that all threads blocked on + * the file descriptor are notified via a wakeup signal. + * + * fd1 < 0 => close(fd2) + * fd1 >= 0 => dup2(fd1, fd2) + * + * Returns -1 with errno set if operation fails. + */ +static int closefd(int fd1, int fd2) { + int rv, orig_errno; + fdEntry_t *fdEntry = getFdEntry(fd2); + if (fdEntry == NULL) { + errno = EBADF; + return -1; + } + + /* + * Lock the fd to hold-off additional I/O on this fd. + */ + pthread_mutex_lock(&(fdEntry->lock)); + + { + /* + * Send a wakeup signal to all threads blocked on this + * file descriptor. + */ + threadEntry_t *curr = fdEntry->threads; + while (curr != NULL) { + curr->intr = 1; + pthread_kill( curr->thr, sigWakeup ); + curr = curr->next; + } + + /* + * And close/dup the file descriptor + * (restart if interrupted by signal) + */ + do { + if (fd1 < 0) { + rv = close(fd2); + } else { + rv = dup2(fd1, fd2); + } + } while (rv == -1 && errno == EINTR); + + } + + /* + * Unlock without destroying errno + */ + orig_errno = errno; + pthread_mutex_unlock(&(fdEntry->lock)); + errno = orig_errno; + + return rv; +} + +/* + * Wrapper for dup2 - same semantics as dup2 system call except + * that any threads blocked in an I/O system call on fd2 will be + * preempted and return -1/EBADF; + */ +int NET_Dup2(int fd, int fd2) { + if (fd < 0) { + errno = EBADF; + return -1; + } + return closefd(fd, fd2); +} + +/* + * Wrapper for close - same semantics as close system call + * except that any threads blocked in an I/O on fd will be + * preempted and the I/O system call will return -1/EBADF. + */ +int NET_SocketClose(int fd) { + return closefd(-1, fd); +} + +/************** Basic I/O operations here ***************/ + +/* + * Macro to perform a blocking IO operation. Restarts + * automatically if interrupted by signal (other than + * our wakeup signal) + */ +#define BLOCKING_IO_RETURN_INT(FD, FUNC) { \ + int ret; \ + threadEntry_t self; \ + fdEntry_t *fdEntry = getFdEntry(FD); \ + if (fdEntry == NULL) { \ + errno = EBADF; \ + return -1; \ + } \ + do { \ + startOp(fdEntry, &self); \ + ret = FUNC; \ + endOp(fdEntry, &self); \ + } while (ret == -1 && errno == EINTR); \ + return ret; \ +} + +int NET_Read(int s, void* buf, size_t len) { + BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, 0) ); +} + +int NET_ReadV(int s, const struct iovec * vector, int count) { + BLOCKING_IO_RETURN_INT( s, readv(s, vector, count) ); +} + +int NET_RecvFrom(int s, void *buf, int len, unsigned int flags, + struct sockaddr *from, socklen_t *fromlen) { + BLOCKING_IO_RETURN_INT( s, recvfrom(s, buf, len, flags, from, fromlen) ); +} + +int NET_Send(int s, void *msg, int len, unsigned int flags) { + BLOCKING_IO_RETURN_INT( s, send(s, msg, len, flags) ); +} + +int NET_WriteV(int s, const struct iovec * vector, int count) { + BLOCKING_IO_RETURN_INT( s, writev(s, vector, count) ); +} + +int NET_SendTo(int s, const void *msg, int len, unsigned int + flags, const struct sockaddr *to, int tolen) { + BLOCKING_IO_RETURN_INT( s, sendto(s, msg, len, flags, to, tolen) ); +} + +int NET_Accept(int s, struct sockaddr *addr, socklen_t *addrlen) { + BLOCKING_IO_RETURN_INT( s, accept(s, addr, addrlen) ); +} + +int NET_Connect(int s, struct sockaddr *addr, int addrlen) { + BLOCKING_IO_RETURN_INT( s, connect(s, addr, addrlen) ); +} + +int NET_Poll(struct pollfd *ufds, unsigned int nfds, int timeout) { + BLOCKING_IO_RETURN_INT( ufds[0].fd, poll(ufds, nfds, timeout) ); +} + +/* + * Wrapper for select(s, timeout). We are using select() on Mac OS due to Bug 7131399. + * Auto restarts with adjusted timeout if interrupted by + * signal other than our wakeup signal. + */ +int NET_Timeout(int s, long timeout) { + long prevtime = 0, newtime; + struct timeval t, *tp = &t; + fd_set fds; + fd_set* fdsp = NULL; + int allocated = 0; + threadEntry_t self; + fdEntry_t *fdEntry = getFdEntry(s); + + /* + * Check that fd hasn't been closed. + */ + if (fdEntry == NULL) { + errno = EBADF; + return -1; + } + + /* + * Pick up current time as may need to adjust timeout + */ + if (timeout > 0) { + /* Timed */ + struct timeval now; + gettimeofday(&now, NULL); + prevtime = now.tv_sec * 1000 + now.tv_usec / 1000; + t.tv_sec = timeout / 1000; + t.tv_usec = (timeout % 1000) * 1000; + } else if (timeout < 0) { + /* Blocking */ + tp = 0; + } else { + /* Poll */ + t.tv_sec = 0; + t.tv_usec = 0; + } + + if (s < FD_SETSIZE) { + fdsp = &fds; + FD_ZERO(fdsp); + } else { + int length = (howmany(s+1, NFDBITS)) * sizeof(int); + fdsp = (fd_set *) calloc(1, length); + if (fdsp == NULL) { + return -1; // errno will be set to ENOMEM + } + allocated = 1; + } + FD_SET(s, fdsp); + + for(;;) { + int rv; + + /* + * call select on the fd. If interrupted by our wakeup signal + * errno will be set to EBADF. + */ + + startOp(fdEntry, &self); + rv = select(s+1, fdsp, 0, 0, tp); + endOp(fdEntry, &self); + + /* + * If interrupted then adjust timeout. If timeout + * has expired return 0 (indicating timeout expired). + */ + if (rv < 0 && errno == EINTR) { + if (timeout > 0) { + struct timeval now; + gettimeofday(&now, NULL); + newtime = now.tv_sec * 1000 + now.tv_usec / 1000; + timeout -= newtime - prevtime; + if (timeout <= 0) { + if (allocated != 0) + free(fdsp); + return 0; + } + prevtime = newtime; + t.tv_sec = timeout / 1000; + t.tv_usec = (timeout % 1000) * 1000; + } + } else { + if (allocated != 0) + free(fdsp); + return rv; + } + + } +} --- old/jdk/src/java.base/unix/native/libnet/solaris_close.c 2015-01-23 17:25:18.101503179 +0100 +++ /dev/null 2015-01-08 08:58:23.458195824 +0100 @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2014, 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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. - */ - -#include -#include -#include -#include - -/* Support for restartable system calls on Solaris. */ - -#define RESTARTABLE_RETURN_INT(_cmd) do { \ - int _result; \ - if (1) { \ - do { \ - _result = _cmd; \ - } while((_result == -1) && (errno == EINTR)); \ - return _result; \ - } \ -} while(0) - -int NET_Read(int s, void* buf, size_t len) { - RESTARTABLE_RETURN_INT(recv(s, buf, len, 0)); -} - -int NET_RecvFrom(int s, void *buf, int len, unsigned int flags, - struct sockaddr *from, socklen_t *fromlen) { - RESTARTABLE_RETURN_INT(recvfrom(s, buf, len, flags, from, fromlen)); -} - -int NET_ReadV(int s, const struct iovec * vector, int count) { - RESTARTABLE_RETURN_INT(readv(s, vector, count)); -} - -int NET_WriteV(int s, const struct iovec * vector, int count) { - RESTARTABLE_RETURN_INT(writev(s, vector, count)); -} - -int NET_Send(int s, void *msg, int len, unsigned int flags) { - RESTARTABLE_RETURN_INT(send(s, msg, len, flags)); -} - -int NET_SendTo(int s, const void *msg, int len, unsigned int flags, - const struct sockaddr *to, int tolen) { - RESTARTABLE_RETURN_INT(sendto(s, msg, len, flags, to, tolen)); -} - -int NET_Connect(int s, struct sockaddr *addr, int addrlen) { - RESTARTABLE_RETURN_INT(connect(s, addr, addrlen)); -} - -int NET_Accept(int s, struct sockaddr *addr, socklen_t *addrlen) { - RESTARTABLE_RETURN_INT(accept(s, addr, addrlen)); -} - -int NET_SocketClose(int fd) { - return close(fd); -} - -int NET_Dup2(int fd, int fd2) { - return dup2(fd, fd2); -} - -int NET_Poll(struct pollfd *ufds, unsigned int nfds, int timeout) { - RESTARTABLE_RETURN_INT(poll(ufds, nfds, timeout)); -} - -int NET_Timeout(int s, long timeout) { - int result; - struct timeval t; - long prevtime, newtime; - struct pollfd pfd; - pfd.fd = s; - pfd.events = POLLIN; - - if (timeout > 0) { - gettimeofday(&t, NULL); - prevtime = (t.tv_sec * 1000) + t.tv_usec / 1000; - } - - for(;;) { - result = poll(&pfd, 1, timeout); - if (result < 0 && errno == EINTR) { - if (timeout > 0) { - gettimeofday(&t, NULL); - newtime = (t.tv_sec * 1000) + t.tv_usec /1000; - timeout -= newtime - prevtime; - if (timeout <= 0) - return 0; - prevtime = newtime; - } - } else { - return result; - } - } -} --- /dev/null 2015-01-08 08:58:23.458195824 +0100 +++ new/jdk/src/java.base/solaris/native/libnet/solaris_close.c 2015-01-23 17:25:17.801490717 +0100 @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2014, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +#include +#include +#include +#include + +/* Support for restartable system calls on Solaris. */ + +#define RESTARTABLE_RETURN_INT(_cmd) do { \ + int _result; \ + if (1) { \ + do { \ + _result = _cmd; \ + } while((_result == -1) && (errno == EINTR)); \ + return _result; \ + } \ +} while(0) + +int NET_Read(int s, void* buf, size_t len) { + RESTARTABLE_RETURN_INT(recv(s, buf, len, 0)); +} + +int NET_RecvFrom(int s, void *buf, int len, unsigned int flags, + struct sockaddr *from, socklen_t *fromlen) { + RESTARTABLE_RETURN_INT(recvfrom(s, buf, len, flags, from, fromlen)); +} + +int NET_ReadV(int s, const struct iovec * vector, int count) { + RESTARTABLE_RETURN_INT(readv(s, vector, count)); +} + +int NET_WriteV(int s, const struct iovec * vector, int count) { + RESTARTABLE_RETURN_INT(writev(s, vector, count)); +} + +int NET_Send(int s, void *msg, int len, unsigned int flags) { + RESTARTABLE_RETURN_INT(send(s, msg, len, flags)); +} + +int NET_SendTo(int s, const void *msg, int len, unsigned int flags, + const struct sockaddr *to, int tolen) { + RESTARTABLE_RETURN_INT(sendto(s, msg, len, flags, to, tolen)); +} + +int NET_Connect(int s, struct sockaddr *addr, int addrlen) { + RESTARTABLE_RETURN_INT(connect(s, addr, addrlen)); +} + +int NET_Accept(int s, struct sockaddr *addr, socklen_t *addrlen) { + RESTARTABLE_RETURN_INT(accept(s, addr, addrlen)); +} + +int NET_SocketClose(int fd) { + return close(fd); +} + +int NET_Dup2(int fd, int fd2) { + return dup2(fd, fd2); +} + +int NET_Poll(struct pollfd *ufds, unsigned int nfds, int timeout) { + RESTARTABLE_RETURN_INT(poll(ufds, nfds, timeout)); +} + +int NET_Timeout(int s, long timeout) { + int result; + struct timeval t; + long prevtime, newtime; + struct pollfd pfd; + pfd.fd = s; + pfd.events = POLLIN; + + if (timeout > 0) { + gettimeofday(&t, NULL); + prevtime = (t.tv_sec * 1000) + t.tv_usec / 1000; + } + + for(;;) { + result = poll(&pfd, 1, timeout); + if (result < 0 && errno == EINTR) { + if (timeout > 0) { + gettimeofday(&t, NULL); + newtime = (t.tv_sec * 1000) + t.tv_usec /1000; + timeout -= newtime - prevtime; + if (timeout <= 0) + return 0; + prevtime = newtime; + } + } else { + return result; + } + } +} --- old/jdk/src/jdk.security.auth/unix/native/libjaas/Solaris.c 2015-01-23 17:25:18.593523615 +0100 +++ /dev/null 2015-01-08 08:58:23.458195824 +0100 @@ -1,135 +0,0 @@ -/* - * Copyright (c) 2000, 2013, 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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. - */ - -#include -#include "com_sun_security_auth_module_SolarisSystem.h" -#include -#include -#include -#include -#include -#include - -static void throwIllegalArgumentException(JNIEnv *env, const char *msg) { - jclass clazz = (*env)->FindClass(env, "java/lang/IllegalArgumentException"); - if (clazz != NULL) - (*env)->ThrowNew(env, clazz, msg); -} - -JNIEXPORT void JNICALL -Java_com_sun_security_auth_module_SolarisSystem_getSolarisInfo - (JNIEnv *env, jobject obj) { - - int i; - char pwd_buf[1024]; - struct passwd pwd; - jsize numSuppGroups = getgroups(0, NULL); - jfieldID fid; - jstring jstr; - jlongArray jgroups; - jlong *jgroupsAsArray; - gid_t *groups; - jclass cls; - - groups = (gid_t *)calloc(numSuppGroups, sizeof(gid_t)); - - if (groups == NULL) { - jclass cls = (*env)->FindClass(env,"java/lang/OutOfMemoryError"); - if (cls != NULL) - (*env)->ThrowNew(env, cls, NULL); - return; - } - - cls = (*env)->GetObjectClass(env, obj); - - memset(pwd_buf, 0, sizeof(pwd_buf)); - if (getpwuid_r(getuid(), &pwd, pwd_buf, sizeof(pwd_buf)) != NULL && - getgroups(numSuppGroups, groups) != -1) { - - /* - * set username - */ - fid = (*env)->GetFieldID(env, cls, "username", "Ljava/lang/String;"); - if (fid == 0) { - (*env)->ExceptionClear(env); - throwIllegalArgumentException(env, "invalid field: username"); - goto cleanupAndReturn; - } - jstr = (*env)->NewStringUTF(env, pwd.pw_name); - if (jstr == NULL) { - goto cleanupAndReturn; - } - (*env)->SetObjectField(env, obj, fid, jstr); - - /* - * set uid - */ - fid = (*env)->GetFieldID(env, cls, "uid", "J"); - if (fid == 0) { - (*env)->ExceptionClear(env); - throwIllegalArgumentException(env, "invalid field: uid"); - goto cleanupAndReturn; - } - (*env)->SetLongField(env, obj, fid, pwd.pw_uid); - - /* - * set gid - */ - fid = (*env)->GetFieldID(env, cls, "gid", "J"); - if (fid == 0) { - (*env)->ExceptionClear(env); - throwIllegalArgumentException(env, "invalid field: gid"); - goto cleanupAndReturn; - } - (*env)->SetLongField(env, obj, fid, pwd.pw_gid); - - /* - * set supplementary groups - */ - fid = (*env)->GetFieldID(env, cls, "groups", "[J"); - if (fid == 0) { - (*env)->ExceptionClear(env); - throwIllegalArgumentException(env, "invalid field: groups"); - goto cleanupAndReturn; - } - - jgroups = (*env)->NewLongArray(env, numSuppGroups); - if (jgroups == NULL) { - goto cleanupAndReturn; - } - jgroupsAsArray = (*env)->GetLongArrayElements(env, jgroups, 0); - if (jgroupsAsArray == NULL) { - goto cleanupAndReturn; - } - for (i = 0; i < numSuppGroups; i++) - jgroupsAsArray[i] = groups[i]; - (*env)->ReleaseLongArrayElements(env, jgroups, jgroupsAsArray, 0); - (*env)->SetObjectField(env, obj, fid, jgroups); - } -cleanupAndReturn: - free(groups); - - return; -} --- /dev/null 2015-01-08 08:58:23.458195824 +0100 +++ new/jdk/src/jdk.security.auth/solaris/native/libjaas/Solaris.c 2015-01-23 17:25:18.297511320 +0100 @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2000, 2013, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +#include +#include "com_sun_security_auth_module_SolarisSystem.h" +#include +#include +#include +#include +#include +#include + +static void throwIllegalArgumentException(JNIEnv *env, const char *msg) { + jclass clazz = (*env)->FindClass(env, "java/lang/IllegalArgumentException"); + if (clazz != NULL) + (*env)->ThrowNew(env, clazz, msg); +} + +JNIEXPORT void JNICALL +Java_com_sun_security_auth_module_SolarisSystem_getSolarisInfo + (JNIEnv *env, jobject obj) { + + int i; + char pwd_buf[1024]; + struct passwd pwd; + jsize numSuppGroups = getgroups(0, NULL); + jfieldID fid; + jstring jstr; + jlongArray jgroups; + jlong *jgroupsAsArray; + gid_t *groups; + jclass cls; + + groups = (gid_t *)calloc(numSuppGroups, sizeof(gid_t)); + + if (groups == NULL) { + jclass cls = (*env)->FindClass(env,"java/lang/OutOfMemoryError"); + if (cls != NULL) + (*env)->ThrowNew(env, cls, NULL); + return; + } + + cls = (*env)->GetObjectClass(env, obj); + + memset(pwd_buf, 0, sizeof(pwd_buf)); + if (getpwuid_r(getuid(), &pwd, pwd_buf, sizeof(pwd_buf)) != NULL && + getgroups(numSuppGroups, groups) != -1) { + + /* + * set username + */ + fid = (*env)->GetFieldID(env, cls, "username", "Ljava/lang/String;"); + if (fid == 0) { + (*env)->ExceptionClear(env); + throwIllegalArgumentException(env, "invalid field: username"); + goto cleanupAndReturn; + } + jstr = (*env)->NewStringUTF(env, pwd.pw_name); + if (jstr == NULL) { + goto cleanupAndReturn; + } + (*env)->SetObjectField(env, obj, fid, jstr); + + /* + * set uid + */ + fid = (*env)->GetFieldID(env, cls, "uid", "J"); + if (fid == 0) { + (*env)->ExceptionClear(env); + throwIllegalArgumentException(env, "invalid field: uid"); + goto cleanupAndReturn; + } + (*env)->SetLongField(env, obj, fid, pwd.pw_uid); + + /* + * set gid + */ + fid = (*env)->GetFieldID(env, cls, "gid", "J"); + if (fid == 0) { + (*env)->ExceptionClear(env); + throwIllegalArgumentException(env, "invalid field: gid"); + goto cleanupAndReturn; + } + (*env)->SetLongField(env, obj, fid, pwd.pw_gid); + + /* + * set supplementary groups + */ + fid = (*env)->GetFieldID(env, cls, "groups", "[J"); + if (fid == 0) { + (*env)->ExceptionClear(env); + throwIllegalArgumentException(env, "invalid field: groups"); + goto cleanupAndReturn; + } + + jgroups = (*env)->NewLongArray(env, numSuppGroups); + if (jgroups == NULL) { + goto cleanupAndReturn; + } + jgroupsAsArray = (*env)->GetLongArrayElements(env, jgroups, 0); + if (jgroupsAsArray == NULL) { + goto cleanupAndReturn; + } + for (i = 0; i < numSuppGroups; i++) + jgroupsAsArray[i] = groups[i]; + (*env)->ReleaseLongArrayElements(env, jgroups, jgroupsAsArray, 0); + (*env)->SetObjectField(env, obj, fid, jgroups); + } +cleanupAndReturn: + free(groups); + + return; +} --- old/jdk/make/data/checkdeps/refs.allowed 2015-01-23 17:25:19.001540562 +0100 +++ /dev/null 2015-01-08 08:58:23.458195824 +0100 @@ -1,34 +0,0 @@ -# -# This properties-formatted file contains the names of the non-existent types -# that are allowed to be referenced from classes in a profiles image. -# -# The property key is a type that does not exist. The property value is one or -# more types that reference the missing type. The property value also encodes -# the names of the profiles where this reference is allowed. - -# jsse.jar is not subsetted by the profiles build. For compact1 and compact2 -# then this means that there are references to Kerberos types that do not -# exist. These references are harmless. -# -javax.security.auth.kerberos.KerberosKey=sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,sun.security.ssl.krb5.Krb5ProxyImpl,compact1,compact2 -javax.security.auth.kerberos.KerberosPrincipal=sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,sun.security.ssl.krb5.Krb5ProxyImpl,compact1,compact2 -javax.security.auth.kerberos.KerberosTicket=sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2 -javax.security.auth.kerberos.KeyTab=sun.security.ssl.krb5.Krb5ProxyImpl,compact1,compact2 -javax.security.auth.kerberos.ServicePermission=sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,sun.security.ssl.krb5.Krb5ProxyImpl,compact1,compact2 -sun.security.jgss.GSSCaller=sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,sun.security.ssl.krb5.Krb5ProxyImpl,compact1,compact2 -sun.security.jgss.krb5.Krb5Util=sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,sun.security.ssl.krb5.Krb5ProxyImpl,compact1,compact2 -sun.security.jgss.krb5.ServiceCreds=sun.security.ssl.krb5.Krb5ProxyImpl,sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2 -sun.security.krb5.EncryptedData= sun.security.ssl.krb5.KerberosPreMasterSecret,sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2 -sun.security.krb5.EncryptionKey=sun.security.ssl.krb5.KerberosPreMasterSecret,sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2 -sun.security.krb5.internal.crypto.KeyUsage=sun.security.ssl.krb5.KerberosPreMasterSecret,sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2 -sun.security.krb5.internal.EncTicketPart=sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2 -sun.security.krb5.internal.Krb5=sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2 -sun.security.krb5.internal.Ticket=sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2 -sun.security.krb5.KrbException=sun.security.ssl.krb5.KerberosPreMasterSecret,sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2 -sun.security.krb5.PrincipalName=sun.security.ssl.krb5.Krb5ProxyImpl,sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2 -sun.security.krb5.Realm=sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2 - -# Residual references to java.beans. -# The RemoveMethods tool does not yet purge the constant pool. -# -java.beans.PropertyChangeListener=java.util.logging.LogManager,compact1,compact2,compact3 --- old/jdk/make/src/classes/build/tools/deps/CheckDeps.java 2015-01-23 17:25:19.405557344 +0100 +++ /dev/null 2015-01-08 08:58:23.458195824 +0100 @@ -1,226 +0,0 @@ -/* - * Copyright (c) 2013, 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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 build.tools.deps; - -import java.nio.file.DirectoryStream; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.charset.StandardCharsets; -import java.util.Set; -import java.util.HashSet; -import java.util.Map; -import java.util.HashMap; -import java.util.Enumeration; -import java.util.Properties; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.URL; - -import com.sun.tools.classfile.ClassFile; -import com.sun.tools.classfile.Dependencies; -import com.sun.tools.classfile.Dependency; - -/** - * A simple tool to check the JAR files in a JRE image to ensure that there - * aren't any references to types that do not exist. The tool is intended to - * be used in the JDK "profiles" build to help ensure that the profile - * definitions are kept up to date. - */ - -public class CheckDeps { - - // classfile API for finding dependencies - static final Dependency.Finder finder = Dependencies.getClassDependencyFinder(); - - // "known types", found in rt.jar or other JAR files - static final Set knownTypes = new HashSet<>(); - - // References to unknown types. The map key is the unknown type, the - // map value is the set of classes that reference it. - static final Map> unknownRefs = new HashMap<>(); - - // The property name is the name of an unknown type that is allowed to be - // references. The property value is a comma separated list of the types - // that are allowed to reference it. The list also includes the names of - // the profiles that the reference is allowed. - static final Properties allowedBadRefs = new Properties(); - - /** - * Returns the class name for the given class file. In the case of inner - * classes then the enclosing class is returned in order to keep the - * rules simple. - */ - static String toClassName(String s) { - int i = s.indexOf('$'); - if (i > 0) - s = s.substring(0, i); - return s.replace("/", "."); - } - - /** - * Analyze the dependencies of all classes in the given JAR file. The - * method updates knownTypes and unknownRefs as part of the analysis. - */ - static void analyzeDependencies(Path jarpath) throws Exception { - System.out.format("Analyzing %s%n", jarpath); - try (JarFile jf = new JarFile(jarpath.toFile())) { - Enumeration entries = jf.entries(); - while (entries.hasMoreElements()) { - JarEntry e = entries.nextElement(); - String name = e.getName(); - if (name.endsWith(".class")) { - ClassFile cf = ClassFile.read(jf.getInputStream(e)); - for (Dependency d : finder.findDependencies(cf)) { - String origin = toClassName(d.getOrigin().getName()); - String target = toClassName(d.getTarget().getName()); - - // origin is now known - unknownRefs.remove(origin); - knownTypes.add(origin); - - // if the target is not known then record the reference - if (!knownTypes.contains(target)) { - Set refs = unknownRefs.get(target); - if (refs == null) { - // first time seeing this unknown type - refs = new HashSet<>(); - unknownRefs.put(target, refs); - } - refs.add(origin); - } - } - } - } - } - } - - /** - * We have closure (no references to types that do not exist) if - * unknownRefs is empty. When unknownRefs is not empty then it should - * only contain references that are allowed to be present (these are - * loaded from the refs.allowed properties file). - * - * @param the profile that is being tested, this determines the exceptions - * in {@code allowedBadRefs} that apply. - * - * @return {@code true} if there are no missing types or the only references - * to missing types are described by {@code allowedBadRefs}. - */ - static boolean checkClosure(String profile) { - // process the references to types that do not exist. - boolean fail = false; - for (Map.Entry> entry: unknownRefs.entrySet()) { - String target = entry.getKey(); - for (String origin: entry.getValue()) { - // check if origin -> target allowed - String value = allowedBadRefs.getProperty(target); - if (value == null) { - System.err.format("%s -> %s (unknown type)%n", origin, target); - fail = true; - } else { - // target is known, check if the origin is one that we - // expect and that the exception applies to the profile. - boolean found = false; - boolean applicable = false; - for (String s: value.split(",")) { - s = s.trim(); - if (s.equals(origin)) - found = true; - if (s.equals(profile)) - applicable = true; - } - if (!found || !applicable) { - if (!found) { - System.err.format("%s -> %s (not allowed)%n", origin, target); - } else { - System.err.format("%s -> %s (reference not applicable to %s)%n", - origin, target, profile); - } - fail = true; - } - } - - } - } - - return !fail; - } - - static void fail(URL url) throws Exception { - System.err.println("One or more unexpected references encountered"); - if (url != null) - System.err.format("Check %s is up to date%n", Paths.get(url.toURI())); - System.exit(-1); - } - - public static void main(String[] args) throws Exception { - // load properties file so that we know what missing types that are - // allowed to be referenced. - URL url = CheckDeps.class.getResource("refs.allowed"); - if (url != null) { - try (InputStream in = url.openStream()) { - allowedBadRefs.load(new InputStreamReader(in, StandardCharsets.UTF_8)); - } - } - - if (args.length != 2) { - System.err.println("Usage: java CheckDeps "); - System.exit(-1); - } - - String image = args[0]; - String profile = args[1]; - - // process JAR files on boot class path - Path lib = Paths.get(image, "lib"); - try (DirectoryStream stream = Files.newDirectoryStream(lib, "*.jar")) { - for (Path jarpath: stream) { - analyzeDependencies(jarpath); - } - } - - // classes on boot class path should not reference other types - boolean okay = checkClosure(profile); - if (!okay) - fail(url); - - // process JAR files in the extensions directory - try (DirectoryStream stream = Files.newDirectoryStream(lib.resolve("ext"), "*.jar")) { - for (Path jarpath: stream) { - analyzeDependencies(jarpath); - } - } - - // re-check to ensure that the extensions doesn't reference types that - // do not exist. - okay = checkClosure(profile); - if (!okay) - fail(url); - } -}