8024854: PPC64: Basic changes and files to build the class library on AIX
Co-authored-by: Steve Poole <spoole@linux.vnet.ibm.com> Co-authored-by: Thomas Stuefe <thomas.stuefe@sap.com> Reviewed-by: alanb, prr, sla, chegar, michaelm, mullan, art
This commit is contained in:
parent
23c97aca2b
commit
780a13433f
@ -210,9 +210,12 @@ define SetupJVMTIDemo
|
||||
# Param 5 = libs for posix
|
||||
# Param 6 = libs for windows
|
||||
# Param 7 = libs for solaris
|
||||
# Param 8 = libs for linux
|
||||
# Param 9 = extra directories with required sources
|
||||
BUILD_DEMO_JVMTI_$1_EXTRA_SRC := \
|
||||
$$(wildcard $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/demo/jvmti/$1) \
|
||||
$$(wildcard $$(addprefix $(JDK_TOPDIR)/src/share/demo/jvmti/, $2))
|
||||
$$(wildcard $$(addprefix $(JDK_TOPDIR)/src/share/demo/jvmti/, $2)) \
|
||||
$9
|
||||
BUILD_DEMO_JVMTI_$1_EXTRA_SRC_EXCLUDE := \
|
||||
$$(wildcard $$(addprefix $(JDK_TOPDIR)/src/share/demo/jvmti/, $2)/README.txt) \
|
||||
$$(wildcard $$(addprefix $(JDK_TOPDIR)/src/share/demo/jvmti/, $2)/sample.makefile.txt)
|
||||
@ -304,9 +307,19 @@ $(eval $(call SetupJVMTIDemo,compiledMethodLoad, agent_util))
|
||||
$(eval $(call SetupJVMTIDemo,gctest, agent_util))
|
||||
$(eval $(call SetupJVMTIDemo,heapTracker, agent_util java_crw_demo))
|
||||
$(eval $(call SetupJVMTIDemo,heapViewer, agent_util))
|
||||
|
||||
# On AIX, hprof requires 'dladdr' from src/aix/porting/porting_aix.cpp
|
||||
BUILD_LIBHPROF_AIX_EXTRA_SRC :=
|
||||
BUILD_LIBHPROF_AIX_EXTRA_CFLAGS :=
|
||||
ifeq ($(OPENJDK_TARGET_OS), aix)
|
||||
BUILD_LIBHPROF_AIX_EXTRA_SRC += $(JDK_TOPDIR)/src/aix/porting
|
||||
BUILD_LIBHPROF_AIX_EXTRA_CFLAGS += -I$(JDK_TOPDIR)/src/aix/porting
|
||||
endif
|
||||
|
||||
$(eval $(call SetupJVMTIDemo,hprof, java_crw_demo, \
|
||||
-I$(JDK_TOPDIR)/src/share/npt -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/npt, C, \
|
||||
-ldl, ws2_32.lib winmm.lib, -lsocket -lnsl, -lpthread))
|
||||
-I$(JDK_TOPDIR)/src/share/npt -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/npt \
|
||||
$(BUILD_LIBHPROF_AIX_EXTRA_CFLAGS), C, \
|
||||
-ldl, ws2_32.lib winmm.lib, -lsocket -lnsl, -lpthread, $(BUILD_LIBHPROF_AIX_EXTRA_SRC)))
|
||||
|
||||
$(eval $(call SetupJVMTIDemo,minst, agent_util java_crw_demo))
|
||||
$(eval $(call SetupJVMTIDemo,mtrace, agent_util java_crw_demo))
|
||||
|
@ -231,6 +231,10 @@ else ifneq ($(OPENJDK_TARGET_OS), macosx)
|
||||
$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d/x11
|
||||
endif
|
||||
|
||||
ifeq ($(OPENJDK_TARGET_OS), aix)
|
||||
LIBAWT_DIRS += $(JDK_TOPDIR)/src/aix/porting
|
||||
endif
|
||||
|
||||
LIBAWT_CFLAGS += -D__MEDIALIB_OLD_NAMES -D__USE_J2D_NAMES \
|
||||
$(X_CFLAGS) \
|
||||
$(foreach dir, $(LIBAWT_DIRS), -I$(dir))
|
||||
@ -309,6 +313,10 @@ ifneq (, $(filter $(OPENJDK_TARGET_OS), solaris linux aix))
|
||||
LIBAWT_FILES += awt_LoadLibrary.c initIDs.c img_colors.c
|
||||
endif
|
||||
|
||||
ifeq ($(OPENJDK_TARGET_OS), aix)
|
||||
LIBAWT_FILES += porting_aix.c
|
||||
endif
|
||||
|
||||
ifeq ($(OPENJDK_TARGET_OS), macosx)
|
||||
LIBAWT_FILES += awt_LoadLibrary.c img_colors.c
|
||||
LIBAWT_CFLAGS += -F/System/Library/Frameworks/JavaVM.framework/Frameworks
|
||||
|
@ -37,7 +37,7 @@ endif
|
||||
LIBNET_CFLAGS := $(foreach dir, $(LIBNET_SRC_DIRS), -I$(dir))
|
||||
|
||||
LIBNET_EXCLUDE_FILES :=
|
||||
ifeq (, $(filter $(OPENJDK_TARGET_OS), linux aix))
|
||||
ifneq ($(OPENJDK_TARGET_OS), linux)
|
||||
LIBNET_EXCLUDE_FILES += linux_close.c
|
||||
endif
|
||||
|
||||
@ -45,6 +45,10 @@ ifneq ($(OPENJDK_TARGET_OS), macosx)
|
||||
LIBNET_EXCLUDE_FILES += bsd_close.c
|
||||
endif
|
||||
|
||||
ifeq ($(OPENJDK_TARGET_OS), aix)
|
||||
LIBNET_SRC_DIRS += $(JDK_TOPDIR)/src/aix/native/java/net/
|
||||
endif
|
||||
|
||||
ifeq ($(OPENJDK_TARGET_OS), windows)
|
||||
LIBNET_EXCLUDE_FILES += PlainSocketImpl.c PlainDatagramSocketImpl.c SdpSupport.c
|
||||
else
|
||||
|
@ -114,7 +114,9 @@ endif
|
||||
|
||||
ifeq ($(OPENJDK_TARGET_OS), aix)
|
||||
BUILD_LIBNIO_MAPFILE:=$(JDK_TOPDIR)/makefiles/mapfiles/libnio/mapfile-$(OPENJDK_TARGET_OS)
|
||||
BUILD_LIBNIO_SRC += $(JDK_TOPDIR)/src/aix/native/sun/nio/ch
|
||||
BUILD_LIBNIO_SRC += \
|
||||
$(JDK_TOPDIR)/src/aix/native/sun/nio/ch \
|
||||
$(JDK_TOPDIR)/src/aix/native/sun/nio/fs
|
||||
BUILD_LIBNIO_FILES += \
|
||||
AixPollPort.c \
|
||||
InheritedChannel.c \
|
||||
|
@ -344,6 +344,11 @@ BUILD_LIBHPROF_CFLAGS := -I$(JDK_TOPDIR)/src/share/demo/jvmti/hprof \
|
||||
-I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/npt \
|
||||
-I$(JDK_TOPDIR)/src/share/demo/jvmti/java_crw_demo
|
||||
|
||||
ifeq ($(OPENJDK_TARGET_OS), aix)
|
||||
BUILD_LIBHPROF_SRC += $(JDK_TOPDIR)/src/aix/porting
|
||||
BUILD_LIBHPROF_CFLAGS += -I$(JDK_TOPDIR)/src/aix/porting
|
||||
endif
|
||||
|
||||
BUILD_LIBHPROF_LDFLAGS :=
|
||||
|
||||
LIBHPROF_OPTIMIZATION := HIGHEST
|
||||
|
@ -0,0 +1,77 @@
|
||||
#
|
||||
#
|
||||
# Copyright 2013 SAP AG. 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.
|
||||
#
|
||||
|
||||
# Minimal version for AIX using the standard Latin Type1 Fonts from the
|
||||
# package X11.fnt.iso_T1. These fonts are installed by default into
|
||||
# "/usr/lpp/X11/lib/X11/fonts/Type1" and sym-linked to "/usr/lib/X11/fonts/Type1"
|
||||
|
||||
# Version
|
||||
|
||||
version=1
|
||||
|
||||
# Component Font Mappings
|
||||
|
||||
dialog.plain.latin-1=-*-helvetica-medium-r-normal--*-%d-100-100-p-*-iso10646-1
|
||||
dialog.bold.latin-1=-*-helvetica-bold-r-normal--*-%d-100-100-p-*-iso10646-1
|
||||
dialog.italic.latin-1=-*-helvetica-medium-o-normal--*-%d-100-100-p-*-iso10646-1
|
||||
dialog.bolditalic.latin-1=-*-helvetica-bold-o-normal--*-%d-100-100-p-*-iso10646-1
|
||||
|
||||
dialoginput.plain.latin-1=-*-courier-medium-r-normal--*-%d-100-100-m-*-iso10646-1
|
||||
dialoginput.bold.latin-1=-*-courier-bold-r-normal--*-%d-100-100-m-*-iso10646-1
|
||||
dialoginput.italic.latin-1=-*-courier-medium-o-normal--*-%d-100-100-m-*-iso10646-1
|
||||
dialoginput.bolditalic.latin-1=-*-courier-bold-o-normal--*-%d-100-100-m-*-iso10646-1
|
||||
|
||||
sansserif.plain.latin-1=-*-helvetica-medium-r-normal--*-%d-100-100-p-*-iso10646-1
|
||||
sansserif.bold.latin-1=-*-helvetica-bold-r-normal--*-%d-100-100-p-*-iso10646-1
|
||||
sansserif.italic.latin-1=-*-helvetica-medium-o-normal--*-%d-100-100-p-*-iso10646-1
|
||||
sansserif.bolditalic.latin-1=-*-helvetica-bold-o-normal--*-%d-100-100-p-*-iso10646-1
|
||||
|
||||
serif.plain.latin-1=-*-times new roman-medium-r-normal--*-%d-100-100-p-*-iso10646-1
|
||||
serif.bold.latin-1=-*-times new roman-bold-r-normal--*-%d-100-100-p-*-iso10646-1
|
||||
serif.italic.latin-1=-*-times new roman-medium-i-normal--*-%d-100-100-p-*-iso10646-1
|
||||
serif.bolditalic.latin-1=-*-times new roman-bold-i-normal--*-%d-100-100-p-*-iso10646-1
|
||||
|
||||
monospaced.plain.latin-1=-*-courier-medium-r-normal--*-%d-100-100-m-*-iso10646-1
|
||||
monospaced.bold.latin-1=-*-courier-bold-r-normal--*-%d-100-100-m-*-iso10646-1
|
||||
monospaced.italic.latin-1=-*-courier-medium-o-normal--*-%d-100-100-m-*-iso10646-1
|
||||
monospaced.bolditalic.latin-1=-*-courier-bold-o-normal--*-%d-100-100-m-*-iso10646-1
|
||||
|
||||
# Search Sequences
|
||||
|
||||
sequence.allfonts=latin-1
|
||||
|
||||
filename.-*-courier-medium-r-normal--*-%d-100-100-m-*-iso10646-1=/usr/lpp/X11/lib/X11/fonts/Type1/cour.pfa
|
||||
filename.-*-courier-bold-r-normal--*-%d-100-100-m-*-iso10646-1=/usr/lpp/X11/lib/X11/fonts/Type1/courb.pfa
|
||||
filename.-*-courier-medium-o-normal--*-%d-100-100-m-*-iso10646-1=/usr/lpp/X11/lib/X11/fonts/Type1/couri.pfa
|
||||
filename.-*-courier-bold-o-normal--*-%d-100-100-m-*-iso10646-1=/usr/lpp/X11/lib/X11/fonts/Type1/courbi.pfa
|
||||
filename.-*-helvetica-medium-r-normal--*-%d-100-100-p-*-iso10646-1=/usr/lpp/X11/lib/X11/fonts/Type1/helv.pfa
|
||||
filename.-*-helvetica-bold-r-normal--*-%d-100-100-p-*-iso10646-1=/usr/lpp/X11/lib/X11/fonts/Type1/helvb.pfa
|
||||
filename.-*-helvetica-medium-o-normal--*-%d-100-100-p-*-iso10646-1=/usr/lpp/X11/lib/X11/fonts/Type1/helvi.pfa
|
||||
filename.-*-helvetica-bold-o-normal--*-%d-100-100-p-*-iso10646-1=/usr/lpp/X11/lib/X11/fonts/Type1/helvbi.pfa
|
||||
filename.-*-times_new_roman-medium-r-normal--*-%d-100-100-p-*-iso10646-1=/usr/lpp/X11/lib/X11/fonts/Type1/tnr.pfa
|
||||
filename.-*-times_new_roman-bold-r-normal--*-%d-100-100-p-*-iso10646-1=/usr/lpp/X11/lib/X11/fonts/Type1/tnrb.pfa
|
||||
filename.-*-times_new_roman-medium-i-normal--*-%d-100-100-p-*-iso10646-1=/usr/lpp/X11/lib/X11/fonts/Type1/tnri.pfa
|
||||
filename.-*-times_new_roman-bold-i-normal--*-%d-100-100-p-*-iso10646-1=/usr/lpp/X11/lib/X11/fonts/Type1/tnrbi.pfa
|
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2012 SAP AG. 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 sun.nio.ch;
|
||||
|
||||
import java.nio.channels.*;
|
||||
import java.nio.channels.spi.AsynchronousChannelProvider;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.io.IOException;
|
||||
|
||||
public class AixAsynchronousChannelProvider
|
||||
extends AsynchronousChannelProvider
|
||||
{
|
||||
private static volatile AixPollPort defaultPort;
|
||||
|
||||
private AixPollPort defaultEventPort() throws IOException {
|
||||
if (defaultPort == null) {
|
||||
synchronized (AixAsynchronousChannelProvider.class) {
|
||||
if (defaultPort == null) {
|
||||
defaultPort = new AixPollPort(this, ThreadPool.getDefault()).start();
|
||||
}
|
||||
}
|
||||
}
|
||||
return defaultPort;
|
||||
}
|
||||
|
||||
public AixAsynchronousChannelProvider() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public AsynchronousChannelGroup openAsynchronousChannelGroup(int nThreads, ThreadFactory factory)
|
||||
throws IOException
|
||||
{
|
||||
return new AixPollPort(this, ThreadPool.create(nThreads, factory)).start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AsynchronousChannelGroup openAsynchronousChannelGroup(ExecutorService executor, int initialSize)
|
||||
throws IOException
|
||||
{
|
||||
return new AixPollPort(this, ThreadPool.wrap(executor, initialSize)).start();
|
||||
}
|
||||
|
||||
private Port toPort(AsynchronousChannelGroup group) throws IOException {
|
||||
if (group == null) {
|
||||
return defaultEventPort();
|
||||
} else {
|
||||
if (!(group instanceof AixPollPort))
|
||||
throw new IllegalChannelGroupException();
|
||||
return (Port)group;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AsynchronousServerSocketChannel openAsynchronousServerSocketChannel(AsynchronousChannelGroup group)
|
||||
throws IOException
|
||||
{
|
||||
return new UnixAsynchronousServerSocketChannelImpl(toPort(group));
|
||||
}
|
||||
|
||||
@Override
|
||||
public AsynchronousSocketChannel openAsynchronousSocketChannel(AsynchronousChannelGroup group)
|
||||
throws IOException
|
||||
{
|
||||
return new UnixAsynchronousSocketChannelImpl(toPort(group));
|
||||
}
|
||||
}
|
536
jdk/src/aix/classes/sun/nio/ch/AixPollPort.java
Normal file
536
jdk/src/aix/classes/sun/nio/ch/AixPollPort.java
Normal file
@ -0,0 +1,536 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2012 SAP AG. 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 sun.nio.ch;
|
||||
|
||||
import java.nio.channels.spi.AsynchronousChannelProvider;
|
||||
import java.io.IOException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.RejectedExecutionException;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import sun.misc.Unsafe;
|
||||
|
||||
/**
|
||||
* AsynchronousChannelGroup implementation based on the AIX pollset framework.
|
||||
*/
|
||||
final class AixPollPort
|
||||
extends Port
|
||||
{
|
||||
private static final Unsafe unsafe = Unsafe.getUnsafe();
|
||||
|
||||
static {
|
||||
IOUtil.load();
|
||||
init();
|
||||
}
|
||||
|
||||
/**
|
||||
* struct pollfd {
|
||||
* int fd;
|
||||
* short events;
|
||||
* short revents;
|
||||
* }
|
||||
*/
|
||||
private static final int SIZEOF_POLLFD = eventSize();
|
||||
private static final int OFFSETOF_EVENTS = eventsOffset();
|
||||
private static final int OFFSETOF_REVENTS = reventsOffset();
|
||||
private static final int OFFSETOF_FD = fdOffset();
|
||||
|
||||
// opcodes
|
||||
private static final int PS_ADD = 0x0;
|
||||
private static final int PS_MOD = 0x1;
|
||||
private static final int PS_DELETE = 0x2;
|
||||
|
||||
// maximum number of events to poll at a time
|
||||
private static final int MAX_POLL_EVENTS = 512;
|
||||
|
||||
// pollset ID
|
||||
private final int pollset;
|
||||
|
||||
// true if port is closed
|
||||
private boolean closed;
|
||||
|
||||
// socket pair used for wakeup
|
||||
private final int sp[];
|
||||
|
||||
// socket pair used to indicate pending pollsetCtl calls
|
||||
// Background info: pollsetCtl blocks when another thread is in a pollsetPoll call.
|
||||
private final int ctlSp[];
|
||||
|
||||
// number of wakeups pending
|
||||
private final AtomicInteger wakeupCount = new AtomicInteger();
|
||||
|
||||
// address of the poll array passed to pollset_poll
|
||||
private final long address;
|
||||
|
||||
// encapsulates an event for a channel
|
||||
static class Event {
|
||||
final PollableChannel channel;
|
||||
final int events;
|
||||
|
||||
Event(PollableChannel channel, int events) {
|
||||
this.channel = channel;
|
||||
this.events = events;
|
||||
}
|
||||
|
||||
PollableChannel channel() { return channel; }
|
||||
int events() { return events; }
|
||||
}
|
||||
|
||||
// queue of events for cases that a polling thread dequeues more than one
|
||||
// event
|
||||
private final ArrayBlockingQueue<Event> queue;
|
||||
private final Event NEED_TO_POLL = new Event(null, 0);
|
||||
private final Event EXECUTE_TASK_OR_SHUTDOWN = new Event(null, 0);
|
||||
|
||||
// encapsulates a pollset control event for a file descriptor
|
||||
static class ControlEvent {
|
||||
final int fd;
|
||||
final int events;
|
||||
final boolean removeOnly;
|
||||
int error = 0;
|
||||
|
||||
ControlEvent(int fd, int events, boolean removeOnly) {
|
||||
this.fd = fd;
|
||||
this.events = events;
|
||||
this.removeOnly = removeOnly;
|
||||
}
|
||||
|
||||
int fd() { return fd; }
|
||||
int events() { return events; }
|
||||
boolean removeOnly() { return removeOnly; }
|
||||
int error() { return error; }
|
||||
void setError(int error) { this.error = error; }
|
||||
}
|
||||
|
||||
// queue of control events that need to be processed
|
||||
// (this object is also used for synchronization)
|
||||
private final HashSet<ControlEvent> controlQueue = new HashSet<ControlEvent>();
|
||||
|
||||
// lock used to check whether a poll operation is ongoing
|
||||
private final ReentrantLock controlLock = new ReentrantLock();
|
||||
|
||||
AixPollPort(AsynchronousChannelProvider provider, ThreadPool pool)
|
||||
throws IOException
|
||||
{
|
||||
super(provider, pool);
|
||||
|
||||
// open pollset
|
||||
this.pollset = pollsetCreate();
|
||||
|
||||
// create socket pair for wakeup mechanism
|
||||
int[] sv = new int[2];
|
||||
try {
|
||||
socketpair(sv);
|
||||
// register one end with pollset
|
||||
pollsetCtl(pollset, PS_ADD, sv[0], POLLIN);
|
||||
} catch (IOException x) {
|
||||
pollsetDestroy(pollset);
|
||||
throw x;
|
||||
}
|
||||
this.sp = sv;
|
||||
|
||||
// create socket pair for pollset control mechanism
|
||||
sv = new int[2];
|
||||
try {
|
||||
socketpair(sv);
|
||||
// register one end with pollset
|
||||
pollsetCtl(pollset, PS_ADD, sv[0], POLLIN);
|
||||
} catch (IOException x) {
|
||||
pollsetDestroy(pollset);
|
||||
throw x;
|
||||
}
|
||||
this.ctlSp = sv;
|
||||
|
||||
// allocate the poll array
|
||||
this.address = allocatePollArray(MAX_POLL_EVENTS);
|
||||
|
||||
// create the queue and offer the special event to ensure that the first
|
||||
// threads polls
|
||||
this.queue = new ArrayBlockingQueue<Event>(MAX_POLL_EVENTS);
|
||||
this.queue.offer(NEED_TO_POLL);
|
||||
}
|
||||
|
||||
AixPollPort start() {
|
||||
startThreads(new EventHandlerTask());
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Release all resources
|
||||
*/
|
||||
private void implClose() {
|
||||
synchronized (this) {
|
||||
if (closed)
|
||||
return;
|
||||
closed = true;
|
||||
}
|
||||
freePollArray(address);
|
||||
close0(sp[0]);
|
||||
close0(sp[1]);
|
||||
close0(ctlSp[0]);
|
||||
close0(ctlSp[1]);
|
||||
pollsetDestroy(pollset);
|
||||
}
|
||||
|
||||
private void wakeup() {
|
||||
if (wakeupCount.incrementAndGet() == 1) {
|
||||
// write byte to socketpair to force wakeup
|
||||
try {
|
||||
interrupt(sp[1]);
|
||||
} catch (IOException x) {
|
||||
throw new AssertionError(x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
void executeOnHandlerTask(Runnable task) {
|
||||
synchronized (this) {
|
||||
if (closed)
|
||||
throw new RejectedExecutionException();
|
||||
offerTask(task);
|
||||
wakeup();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
void shutdownHandlerTasks() {
|
||||
/*
|
||||
* If no tasks are running then just release resources; otherwise
|
||||
* write to the one end of the socketpair to wakeup any polling threads.
|
||||
*/
|
||||
int nThreads = threadCount();
|
||||
if (nThreads == 0) {
|
||||
implClose();
|
||||
} else {
|
||||
// send interrupt to each thread
|
||||
while (nThreads-- > 0) {
|
||||
wakeup();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// invoke by clients to register a file descriptor
|
||||
@Override
|
||||
void startPoll(int fd, int events) {
|
||||
queueControlEvent(new ControlEvent(fd, events, false));
|
||||
}
|
||||
|
||||
// Callback method for implementations that need special handling when fd is removed
|
||||
@Override
|
||||
protected void preUnregister(int fd) {
|
||||
queueControlEvent(new ControlEvent(fd, 0, true));
|
||||
}
|
||||
|
||||
// Add control event into queue and wait for completion.
|
||||
// In case the control lock is free, this method also tries to apply the control change directly.
|
||||
private void queueControlEvent(ControlEvent ev) {
|
||||
// pollsetCtl blocks when a poll call is ongoing. This is very probable.
|
||||
// Therefore we let the polling thread do the pollsetCtl call.
|
||||
synchronized (controlQueue) {
|
||||
controlQueue.add(ev);
|
||||
// write byte to socketpair to force wakeup
|
||||
try {
|
||||
interrupt(ctlSp[1]);
|
||||
} catch (IOException x) {
|
||||
throw new AssertionError(x);
|
||||
}
|
||||
do {
|
||||
// Directly empty queue if no poll call is ongoing.
|
||||
if (controlLock.tryLock()) {
|
||||
try {
|
||||
processControlQueue();
|
||||
} finally {
|
||||
controlLock.unlock();
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
// Do not starve in case the polling thread returned before
|
||||
// we could write to ctlSp[1] but the polling thread did not
|
||||
// release the control lock until we checked. Therefore, use
|
||||
// a timed wait for the time being.
|
||||
controlQueue.wait(100);
|
||||
} catch (InterruptedException e) {
|
||||
// ignore exception and try again
|
||||
}
|
||||
}
|
||||
} while (controlQueue.contains(ev));
|
||||
}
|
||||
if (ev.error() != 0) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
||||
// Process all events currently stored in the control queue.
|
||||
private void processControlQueue() {
|
||||
synchronized (controlQueue) {
|
||||
// On Aix it is only possible to set the event
|
||||
// bits on the first call of pollsetCtl. Later
|
||||
// calls only add bits, but cannot remove them.
|
||||
// Therefore, we always remove the file
|
||||
// descriptor ignoring the error and then add it.
|
||||
Iterator<ControlEvent> iter = controlQueue.iterator();
|
||||
while (iter.hasNext()) {
|
||||
ControlEvent ev = iter.next();
|
||||
pollsetCtl(pollset, PS_DELETE, ev.fd(), 0);
|
||||
if (!ev.removeOnly()) {
|
||||
ev.setError(pollsetCtl(pollset, PS_MOD, ev.fd(), ev.events()));
|
||||
}
|
||||
iter.remove();
|
||||
}
|
||||
controlQueue.notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Task to process events from pollset and dispatch to the channel's
|
||||
* onEvent handler.
|
||||
*
|
||||
* Events are retreived from pollset in batch and offered to a BlockingQueue
|
||||
* where they are consumed by handler threads. A special "NEED_TO_POLL"
|
||||
* event is used to signal one consumer to re-poll when all events have
|
||||
* been consumed.
|
||||
*/
|
||||
private class EventHandlerTask implements Runnable {
|
||||
private Event poll() throws IOException {
|
||||
try {
|
||||
for (;;) {
|
||||
int n;
|
||||
controlLock.lock();
|
||||
try {
|
||||
n = pollsetPoll(pollset, address, MAX_POLL_EVENTS);
|
||||
} finally {
|
||||
controlLock.unlock();
|
||||
}
|
||||
/*
|
||||
* 'n' events have been read. Here we map them to their
|
||||
* corresponding channel in batch and queue n-1 so that
|
||||
* they can be handled by other handler threads. The last
|
||||
* event is handled by this thread (and so is not queued).
|
||||
*/
|
||||
fdToChannelLock.readLock().lock();
|
||||
try {
|
||||
while (n-- > 0) {
|
||||
long eventAddress = getEvent(address, n);
|
||||
int fd = getDescriptor(eventAddress);
|
||||
|
||||
// To emulate one shot semantic we need to remove
|
||||
// the file descriptor here.
|
||||
pollsetCtl(pollset, PS_DELETE, fd, 0);
|
||||
|
||||
// wakeup
|
||||
if (fd == sp[0]) {
|
||||
if (wakeupCount.decrementAndGet() == 0) {
|
||||
// no more wakeups so drain pipe
|
||||
drain1(sp[0]);
|
||||
}
|
||||
|
||||
// This is the only file descriptor without
|
||||
// one shot semantic => register it again.
|
||||
pollsetCtl(pollset, PS_ADD, sp[0], POLLIN);
|
||||
|
||||
// queue special event if there are more events
|
||||
// to handle.
|
||||
if (n > 0) {
|
||||
queue.offer(EXECUTE_TASK_OR_SHUTDOWN);
|
||||
continue;
|
||||
}
|
||||
return EXECUTE_TASK_OR_SHUTDOWN;
|
||||
}
|
||||
|
||||
// wakeup to process control event
|
||||
if (fd == ctlSp[0]) {
|
||||
synchronized (controlQueue) {
|
||||
drain1(ctlSp[0]);
|
||||
// This file descriptor does not have
|
||||
// one shot semantic => register it again.
|
||||
pollsetCtl(pollset, PS_ADD, ctlSp[0], POLLIN);
|
||||
processControlQueue();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
PollableChannel channel = fdToChannel.get(fd);
|
||||
if (channel != null) {
|
||||
int events = getRevents(eventAddress);
|
||||
Event ev = new Event(channel, events);
|
||||
|
||||
// n-1 events are queued; This thread handles
|
||||
// the last one except for the wakeup
|
||||
if (n > 0) {
|
||||
queue.offer(ev);
|
||||
} else {
|
||||
return ev;
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
fdToChannelLock.readLock().unlock();
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
// to ensure that some thread will poll when all events have
|
||||
// been consumed
|
||||
queue.offer(NEED_TO_POLL);
|
||||
}
|
||||
}
|
||||
|
||||
public void run() {
|
||||
Invoker.GroupAndInvokeCount myGroupAndInvokeCount =
|
||||
Invoker.getGroupAndInvokeCount();
|
||||
final boolean isPooledThread = (myGroupAndInvokeCount != null);
|
||||
boolean replaceMe = false;
|
||||
Event ev;
|
||||
try {
|
||||
for (;;) {
|
||||
// reset invoke count
|
||||
if (isPooledThread)
|
||||
myGroupAndInvokeCount.resetInvokeCount();
|
||||
|
||||
try {
|
||||
replaceMe = false;
|
||||
ev = queue.take();
|
||||
|
||||
// no events and this thread has been "selected" to
|
||||
// poll for more.
|
||||
if (ev == NEED_TO_POLL) {
|
||||
try {
|
||||
ev = poll();
|
||||
} catch (IOException x) {
|
||||
x.printStackTrace();
|
||||
return;
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException x) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// handle wakeup to execute task or shutdown
|
||||
if (ev == EXECUTE_TASK_OR_SHUTDOWN) {
|
||||
Runnable task = pollTask();
|
||||
if (task == null) {
|
||||
// shutdown request
|
||||
return;
|
||||
}
|
||||
// run task (may throw error/exception)
|
||||
replaceMe = true;
|
||||
task.run();
|
||||
continue;
|
||||
}
|
||||
|
||||
// process event
|
||||
try {
|
||||
ev.channel().onEvent(ev.events(), isPooledThread);
|
||||
} catch (Error x) {
|
||||
replaceMe = true; throw x;
|
||||
} catch (RuntimeException x) {
|
||||
replaceMe = true; throw x;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
// last handler to exit when shutdown releases resources
|
||||
int remaining = threadExit(this, replaceMe);
|
||||
if (remaining == 0 && isShutdown()) {
|
||||
implClose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocates a poll array to handle up to {@code count} events.
|
||||
*/
|
||||
private static long allocatePollArray(int count) {
|
||||
return unsafe.allocateMemory(count * SIZEOF_POLLFD);
|
||||
}
|
||||
|
||||
/**
|
||||
* Free a poll array
|
||||
*/
|
||||
private static void freePollArray(long address) {
|
||||
unsafe.freeMemory(address);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns event[i];
|
||||
*/
|
||||
private static long getEvent(long address, int i) {
|
||||
return address + (SIZEOF_POLLFD*i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns event->fd
|
||||
*/
|
||||
private static int getDescriptor(long eventAddress) {
|
||||
return unsafe.getInt(eventAddress + OFFSETOF_FD);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns event->events
|
||||
*/
|
||||
private static int getEvents(long eventAddress) {
|
||||
return unsafe.getChar(eventAddress + OFFSETOF_EVENTS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns event->revents
|
||||
*/
|
||||
private static int getRevents(long eventAddress) {
|
||||
return unsafe.getChar(eventAddress + OFFSETOF_REVENTS);
|
||||
}
|
||||
|
||||
// -- Native methods --
|
||||
|
||||
private static native void init();
|
||||
|
||||
private static native int eventSize();
|
||||
|
||||
private static native int eventsOffset();
|
||||
|
||||
private static native int reventsOffset();
|
||||
|
||||
private static native int fdOffset();
|
||||
|
||||
private static native int pollsetCreate() throws IOException;
|
||||
|
||||
private static native int pollsetCtl(int pollset, int opcode, int fd, int events);
|
||||
|
||||
private static native int pollsetPoll(int pollset, long pollAddress, int numfds)
|
||||
throws IOException;
|
||||
|
||||
private static native void pollsetDestroy(int pollset);
|
||||
|
||||
private static native void socketpair(int[] sv) throws IOException;
|
||||
|
||||
private static native void interrupt(int fd) throws IOException;
|
||||
|
||||
private static native void drain1(int fd) throws IOException;
|
||||
|
||||
private static native void close0(int fd);
|
||||
}
|
106
jdk/src/aix/classes/sun/nio/fs/AixFileStore.java
Normal file
106
jdk/src/aix/classes/sun/nio/fs/AixFileStore.java
Normal file
@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2013 SAP AG. 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 sun.nio.fs;
|
||||
|
||||
import java.nio.file.attribute.*;
|
||||
import java.util.*;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* AIX implementation of FileStore
|
||||
*/
|
||||
|
||||
class AixFileStore
|
||||
extends UnixFileStore
|
||||
{
|
||||
|
||||
AixFileStore(UnixPath file) throws IOException {
|
||||
super(file);
|
||||
}
|
||||
|
||||
AixFileStore(UnixFileSystem fs, UnixMountEntry entry) throws IOException {
|
||||
super(fs, entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds, and returns, the mount entry for the file system where the file
|
||||
* resides.
|
||||
*/
|
||||
@Override
|
||||
UnixMountEntry findMountEntry() throws IOException {
|
||||
AixFileSystem fs = (AixFileSystem)file().getFileSystem();
|
||||
|
||||
// step 1: get realpath
|
||||
UnixPath path = null;
|
||||
try {
|
||||
byte[] rp = UnixNativeDispatcher.realpath(file());
|
||||
path = new UnixPath(fs, rp);
|
||||
} catch (UnixException x) {
|
||||
x.rethrowAsIOException(file());
|
||||
}
|
||||
|
||||
// step 2: find mount point
|
||||
UnixPath parent = path.getParent();
|
||||
while (parent != null) {
|
||||
UnixFileAttributes attrs = null;
|
||||
try {
|
||||
attrs = UnixFileAttributes.get(parent, true);
|
||||
} catch (UnixException x) {
|
||||
x.rethrowAsIOException(parent);
|
||||
}
|
||||
if (attrs.dev() != dev())
|
||||
break;
|
||||
path = parent;
|
||||
parent = parent.getParent();
|
||||
}
|
||||
|
||||
// step 3: lookup mounted file systems
|
||||
byte[] dir = path.asByteArray();
|
||||
for (UnixMountEntry entry: fs.getMountEntries()) {
|
||||
if (Arrays.equals(dir, entry.dir()))
|
||||
return entry;
|
||||
}
|
||||
|
||||
throw new IOException("Mount point not found");
|
||||
}
|
||||
|
||||
// returns true if extended attributes enabled on file system where given
|
||||
// file resides, returns false if disabled or unable to determine.
|
||||
private boolean isExtendedAttributesEnabled(UnixPath path) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsFileAttributeView(Class<? extends FileAttributeView> type) {
|
||||
return super.supportsFileAttributeView(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsFileAttributeView(String name) {
|
||||
return super.supportsFileAttributeView(name);
|
||||
}
|
||||
}
|
94
jdk/src/aix/classes/sun/nio/fs/AixFileSystem.java
Normal file
94
jdk/src/aix/classes/sun/nio/fs/AixFileSystem.java
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2013 SAP AG. 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 sun.nio.fs;
|
||||
|
||||
import java.nio.file.*;
|
||||
import java.nio.file.attribute.*;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import static sun.nio.fs.AixNativeDispatcher.*;
|
||||
|
||||
/**
|
||||
* AIX implementation of FileSystem
|
||||
*/
|
||||
|
||||
class AixFileSystem extends UnixFileSystem {
|
||||
|
||||
AixFileSystem(UnixFileSystemProvider provider, String dir) {
|
||||
super(provider, dir);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WatchService newWatchService()
|
||||
throws IOException
|
||||
{
|
||||
return new PollingWatchService();
|
||||
}
|
||||
|
||||
// lazy initialization of the list of supported attribute views
|
||||
private static class SupportedFileFileAttributeViewsHolder {
|
||||
static final Set<String> supportedFileAttributeViews =
|
||||
supportedFileAttributeViews();
|
||||
private static Set<String> supportedFileAttributeViews() {
|
||||
Set<String> result = new HashSet<String>();
|
||||
result.addAll(UnixFileSystem.standardFileAttributeViews());
|
||||
return Collections.unmodifiableSet(result);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> supportedFileAttributeViews() {
|
||||
return SupportedFileFileAttributeViewsHolder.supportedFileAttributeViews;
|
||||
}
|
||||
|
||||
@Override
|
||||
void copyNonPosixAttributes(int ofd, int nfd) {
|
||||
// TODO: Implement if needed.
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns object to iterate over the mount entries returned by mntctl
|
||||
*/
|
||||
@Override
|
||||
Iterable<UnixMountEntry> getMountEntries() {
|
||||
UnixMountEntry[] entries = null;
|
||||
try {
|
||||
entries = getmntctl();
|
||||
} catch (UnixException x) {
|
||||
// nothing we can do
|
||||
}
|
||||
if (entries == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return Arrays.asList(entries);
|
||||
}
|
||||
|
||||
@Override
|
||||
FileStore getFileStore(UnixMountEntry entry) throws IOException {
|
||||
return new AixFileStore(this, entry);
|
||||
}
|
||||
}
|
52
jdk/src/aix/classes/sun/nio/fs/AixFileSystemProvider.java
Normal file
52
jdk/src/aix/classes/sun/nio/fs/AixFileSystemProvider.java
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2013 SAP AG. 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 sun.nio.fs;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* AIX implementation of FileSystemProvider
|
||||
*/
|
||||
|
||||
public class AixFileSystemProvider extends UnixFileSystemProvider {
|
||||
public AixFileSystemProvider() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
AixFileSystem newFileSystem(String dir) {
|
||||
return new AixFileSystem(this, dir);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see sun.nio.fs.UnixFileSystemProvider#getFileStore(sun.nio.fs.UnixPath)
|
||||
*/
|
||||
@Override
|
||||
AixFileStore getFileStore(UnixPath path) throws IOException {
|
||||
return new AixFileStore(path);
|
||||
}
|
||||
}
|
56
jdk/src/aix/classes/sun/nio/fs/AixNativeDispatcher.java
Normal file
56
jdk/src/aix/classes/sun/nio/fs/AixNativeDispatcher.java
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2013 SAP AG. 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 sun.nio.fs;
|
||||
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
|
||||
/**
|
||||
* AIX specific system calls.
|
||||
*/
|
||||
|
||||
class AixNativeDispatcher extends UnixNativeDispatcher {
|
||||
private AixNativeDispatcher() { }
|
||||
|
||||
/**
|
||||
* Special implementation of 'getextmntent' (see SolarisNativeDispatcher)
|
||||
* that returns all entries at once.
|
||||
*/
|
||||
static native UnixMountEntry[] getmntctl() throws UnixException;
|
||||
|
||||
// initialize
|
||||
private static native int init();
|
||||
|
||||
static {
|
||||
AccessController.doPrivileged(new PrivilegedAction<Void>() {
|
||||
public Void run() {
|
||||
System.loadLibrary("nio");
|
||||
return null;
|
||||
}});
|
||||
init();
|
||||
}
|
||||
}
|
88
jdk/src/aix/classes/sun/tools/attach/AixAttachProvider.java
Normal file
88
jdk/src/aix/classes/sun/tools/attach/AixAttachProvider.java
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2013 SAP AG. 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 sun.tools.attach;
|
||||
|
||||
import com.sun.tools.attach.VirtualMachine;
|
||||
import com.sun.tools.attach.VirtualMachineDescriptor;
|
||||
import com.sun.tools.attach.AttachNotSupportedException;
|
||||
import com.sun.tools.attach.spi.AttachProvider;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
// Based on 'LinuxAttachProvider.java'. All occurrences of the string
|
||||
// "Linux" have been textually replaced by "Aix" to avoid confusion.
|
||||
|
||||
/*
|
||||
* An AttachProvider implementation for Aix that uses a UNIX domain
|
||||
* socket.
|
||||
*/
|
||||
public class AixAttachProvider extends HotSpotAttachProvider {
|
||||
|
||||
// perf counter for the JVM version
|
||||
private static final String JVM_VERSION = "java.property.java.vm.version";
|
||||
|
||||
public AixAttachProvider() {
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return "sun";
|
||||
}
|
||||
|
||||
public String type() {
|
||||
return "socket";
|
||||
}
|
||||
|
||||
public VirtualMachine attachVirtualMachine(String vmid)
|
||||
throws AttachNotSupportedException, IOException
|
||||
{
|
||||
checkAttachPermission();
|
||||
|
||||
// AttachNotSupportedException will be thrown if the target VM can be determined
|
||||
// to be not attachable.
|
||||
testAttachable(vmid);
|
||||
|
||||
return new AixVirtualMachine(this, vmid);
|
||||
}
|
||||
|
||||
public VirtualMachine attachVirtualMachine(VirtualMachineDescriptor vmd)
|
||||
throws AttachNotSupportedException, IOException
|
||||
{
|
||||
if (vmd.provider() != this) {
|
||||
throw new AttachNotSupportedException("provider mismatch");
|
||||
}
|
||||
// To avoid re-checking if the VM if attachable, we check if the descriptor
|
||||
// is for a hotspot VM - these descriptors are created by the listVirtualMachines
|
||||
// implementation which only returns a list of attachable VMs.
|
||||
if (vmd instanceof HotSpotVirtualMachineDescriptor) {
|
||||
assert ((HotSpotVirtualMachineDescriptor)vmd).isAttachable();
|
||||
checkAttachPermission();
|
||||
return new AixVirtualMachine(this, vmd.id());
|
||||
} else {
|
||||
return attachVirtualMachine(vmd.id());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
317
jdk/src/aix/classes/sun/tools/attach/AixVirtualMachine.java
Normal file
317
jdk/src/aix/classes/sun/tools/attach/AixVirtualMachine.java
Normal file
@ -0,0 +1,317 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2013 SAP AG. 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 sun.tools.attach;
|
||||
|
||||
import com.sun.tools.attach.VirtualMachine;
|
||||
import com.sun.tools.attach.AgentLoadException;
|
||||
import com.sun.tools.attach.AttachNotSupportedException;
|
||||
import com.sun.tools.attach.spi.AttachProvider;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.File;
|
||||
import java.util.Properties;
|
||||
|
||||
// Based on 'LinuxVirtualMachine.java'. All occurrences of the string
|
||||
// "Linux" have been textually replaced by "Aix" to avoid confusion.
|
||||
|
||||
/*
|
||||
* Aix implementation of HotSpotVirtualMachine
|
||||
*/
|
||||
public class AixVirtualMachine extends HotSpotVirtualMachine {
|
||||
// "/tmp" is used as a global well-known location for the files
|
||||
// .java_pid<pid>. and .attach_pid<pid>. It is important that this
|
||||
// location is the same for all processes, otherwise the tools
|
||||
// will not be able to find all Hotspot processes.
|
||||
// Any changes to this needs to be synchronized with HotSpot.
|
||||
private static final String tmpdir = "/tmp";
|
||||
|
||||
// The patch to the socket file created by the target VM
|
||||
String path;
|
||||
|
||||
/**
|
||||
* Attaches to the target VM
|
||||
*/
|
||||
AixVirtualMachine(AttachProvider provider, String vmid)
|
||||
throws AttachNotSupportedException, IOException
|
||||
{
|
||||
super(provider, vmid);
|
||||
|
||||
// This provider only understands pids
|
||||
int pid;
|
||||
try {
|
||||
pid = Integer.parseInt(vmid);
|
||||
} catch (NumberFormatException x) {
|
||||
throw new AttachNotSupportedException("Invalid process identifier");
|
||||
}
|
||||
|
||||
// Find the socket file. If not found then we attempt to start the
|
||||
// attach mechanism in the target VM by sending it a QUIT signal.
|
||||
// Then we attempt to find the socket file again.
|
||||
path = findSocketFile(pid);
|
||||
if (path == null) {
|
||||
File f = createAttachFile(pid);
|
||||
try {
|
||||
sendQuitTo(pid);
|
||||
|
||||
// give the target VM time to start the attach mechanism
|
||||
int i = 0;
|
||||
long delay = 200;
|
||||
int retries = (int)(attachTimeout() / delay);
|
||||
do {
|
||||
try {
|
||||
Thread.sleep(delay);
|
||||
} catch (InterruptedException x) { }
|
||||
path = findSocketFile(pid);
|
||||
i++;
|
||||
} while (i <= retries && path == null);
|
||||
if (path == null) {
|
||||
throw new AttachNotSupportedException(
|
||||
"Unable to open socket file: target process not responding " +
|
||||
"or HotSpot VM not loaded");
|
||||
}
|
||||
} finally {
|
||||
f.delete();
|
||||
}
|
||||
}
|
||||
|
||||
// Check that the file owner/permission to avoid attaching to
|
||||
// bogus process
|
||||
checkPermissions(path);
|
||||
|
||||
// Check that we can connect to the process
|
||||
// - this ensures we throw the permission denied error now rather than
|
||||
// later when we attempt to enqueue a command.
|
||||
int s = socket();
|
||||
try {
|
||||
connect(s, path);
|
||||
} finally {
|
||||
close(s);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Detach from the target VM
|
||||
*/
|
||||
public void detach() throws IOException {
|
||||
synchronized (this) {
|
||||
if (this.path != null) {
|
||||
this.path = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// protocol version
|
||||
private final static String PROTOCOL_VERSION = "1";
|
||||
|
||||
// known errors
|
||||
private final static int ATTACH_ERROR_BADVERSION = 101;
|
||||
|
||||
/**
|
||||
* Execute the given command in the target VM.
|
||||
*/
|
||||
InputStream execute(String cmd, Object ... args) throws AgentLoadException, IOException {
|
||||
assert args.length <= 3; // includes null
|
||||
|
||||
// did we detach?
|
||||
String p;
|
||||
synchronized (this) {
|
||||
if (this.path == null) {
|
||||
throw new IOException("Detached from target VM");
|
||||
}
|
||||
p = this.path;
|
||||
}
|
||||
|
||||
// create UNIX socket
|
||||
int s = socket();
|
||||
|
||||
// connect to target VM
|
||||
try {
|
||||
connect(s, p);
|
||||
} catch (IOException x) {
|
||||
close(s);
|
||||
throw x;
|
||||
}
|
||||
|
||||
IOException ioe = null;
|
||||
|
||||
// connected - write request
|
||||
// <ver> <cmd> <args...>
|
||||
try {
|
||||
writeString(s, PROTOCOL_VERSION);
|
||||
writeString(s, cmd);
|
||||
|
||||
for (int i=0; i<3; i++) {
|
||||
if (i < args.length && args[i] != null) {
|
||||
writeString(s, (String)args[i]);
|
||||
} else {
|
||||
writeString(s, "");
|
||||
}
|
||||
}
|
||||
} catch (IOException x) {
|
||||
ioe = x;
|
||||
}
|
||||
|
||||
|
||||
// Create an input stream to read reply
|
||||
SocketInputStream sis = new SocketInputStream(s);
|
||||
|
||||
// Read the command completion status
|
||||
int completionStatus;
|
||||
try {
|
||||
completionStatus = readInt(sis);
|
||||
} catch (IOException x) {
|
||||
sis.close();
|
||||
if (ioe != null) {
|
||||
throw ioe;
|
||||
} else {
|
||||
throw x;
|
||||
}
|
||||
}
|
||||
|
||||
if (completionStatus != 0) {
|
||||
sis.close();
|
||||
|
||||
// In the event of a protocol mismatch then the target VM
|
||||
// returns a known error so that we can throw a reasonable
|
||||
// error.
|
||||
if (completionStatus == ATTACH_ERROR_BADVERSION) {
|
||||
throw new IOException("Protocol mismatch with target VM");
|
||||
}
|
||||
|
||||
// Special-case the "load" command so that the right exception is
|
||||
// thrown.
|
||||
if (cmd.equals("load")) {
|
||||
throw new AgentLoadException("Failed to load agent library");
|
||||
} else {
|
||||
throw new IOException("Command failed in target VM");
|
||||
}
|
||||
}
|
||||
|
||||
// Return the input stream so that the command output can be read
|
||||
return sis;
|
||||
}
|
||||
|
||||
/*
|
||||
* InputStream for the socket connection to get target VM
|
||||
*/
|
||||
private class SocketInputStream extends InputStream {
|
||||
int s;
|
||||
|
||||
public SocketInputStream(int s) {
|
||||
this.s = s;
|
||||
}
|
||||
|
||||
public synchronized int read() throws IOException {
|
||||
byte b[] = new byte[1];
|
||||
int n = this.read(b, 0, 1);
|
||||
if (n == 1) {
|
||||
return b[0] & 0xff;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized int read(byte[] bs, int off, int len) throws IOException {
|
||||
if ((off < 0) || (off > bs.length) || (len < 0) ||
|
||||
((off + len) > bs.length) || ((off + len) < 0)) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
} else if (len == 0)
|
||||
return 0;
|
||||
|
||||
return AixVirtualMachine.read(s, bs, off, len);
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
AixVirtualMachine.close(s);
|
||||
}
|
||||
}
|
||||
|
||||
// Return the socket file for the given process.
|
||||
private String findSocketFile(int pid) {
|
||||
File f = new File(tmpdir, ".java_pid" + pid);
|
||||
if (!f.exists()) {
|
||||
return null;
|
||||
}
|
||||
return f.getPath();
|
||||
}
|
||||
|
||||
// On Solaris/Linux/Aix a simple handshake is used to start the attach mechanism
|
||||
// if not already started. The client creates a .attach_pid<pid> file in the
|
||||
// target VM's working directory (or temp directory), and the SIGQUIT handler
|
||||
// checks for the file.
|
||||
private File createAttachFile(int pid) throws IOException {
|
||||
String fn = ".attach_pid" + pid;
|
||||
String path = "/proc/" + pid + "/cwd/" + fn;
|
||||
File f = new File(path);
|
||||
try {
|
||||
f.createNewFile();
|
||||
} catch (IOException x) {
|
||||
f = new File(tmpdir, fn);
|
||||
f.createNewFile();
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write/sends the given to the target VM. String is transmitted in
|
||||
* UTF-8 encoding.
|
||||
*/
|
||||
private void writeString(int fd, String s) throws IOException {
|
||||
if (s.length() > 0) {
|
||||
byte b[];
|
||||
try {
|
||||
b = s.getBytes("UTF-8");
|
||||
} catch (java.io.UnsupportedEncodingException x) {
|
||||
throw new InternalError(x);
|
||||
}
|
||||
AixVirtualMachine.write(fd, b, 0, b.length);
|
||||
}
|
||||
byte b[] = new byte[1];
|
||||
b[0] = 0;
|
||||
write(fd, b, 0, 1);
|
||||
}
|
||||
|
||||
|
||||
//-- native methods
|
||||
|
||||
static native void sendQuitTo(int pid) throws IOException;
|
||||
|
||||
static native void checkPermissions(String path) throws IOException;
|
||||
|
||||
static native int socket() throws IOException;
|
||||
|
||||
static native void connect(int fd, String path) throws IOException;
|
||||
|
||||
static native void close(int fd) throws IOException;
|
||||
|
||||
static native int read(int fd, byte buf[], int off, int bufLen) throws IOException;
|
||||
|
||||
static native void write(int fd, byte buf[], int off, int bufLen) throws IOException;
|
||||
|
||||
static {
|
||||
System.loadLibrary("attach");
|
||||
}
|
||||
}
|
427
jdk/src/aix/native/java/net/aix_close.c
Normal file
427
jdk/src/aix/native/java/net/aix_close.c
Normal file
@ -0,0 +1,427 @@
|
||||
/*
|
||||
* 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).
|
||||
*
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/uio.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <sys/poll.h>
|
||||
|
||||
/*
|
||||
* 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));
|
||||
|
||||
{
|
||||
/*
|
||||
* 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, 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) {
|
||||
BLOCKING_IO_RETURN_INT( s, connect(s, addr, addrlen) );
|
||||
}
|
||||
|
||||
#ifndef USE_SELECT
|
||||
int NET_Poll(struct pollfd *ufds, unsigned int nfds, int timeout) {
|
||||
BLOCKING_IO_RETURN_INT( ufds[0].fd, poll(ufds, nfds, timeout) );
|
||||
}
|
||||
#else
|
||||
int NET_Select(int s, fd_set *readfds, fd_set *writefds,
|
||||
fd_set *exceptfds, struct timeval *timeout) {
|
||||
BLOCKING_IO_RETURN_INT( s-1,
|
||||
select(s, readfds, writefds, exceptfds, timeout) );
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
175
jdk/src/aix/native/sun/nio/ch/AixPollPort.c
Normal file
175
jdk/src/aix/native/sun/nio/ch/AixPollPort.c
Normal file
@ -0,0 +1,175 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2012 SAP AG. 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 "jni.h"
|
||||
#include "jni_util.h"
|
||||
#include "jvm.h"
|
||||
#include "jlong.h"
|
||||
|
||||
#include "sun_nio_ch_AixPollPort.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/poll.h>
|
||||
#include <sys/pollset.h>
|
||||
#include <fcntl.h>
|
||||
#include <stddef.h>
|
||||
#include <dlfcn.h>
|
||||
#include <errno.h>
|
||||
|
||||
/* Initially copied from src/solaris/native/sun/nio/ch/nio_util.h */
|
||||
#define RESTARTABLE(_cmd, _result) do { \
|
||||
do { \
|
||||
_result = _cmd; \
|
||||
} while((_result == -1) && (errno == EINTR)); \
|
||||
} while(0)
|
||||
|
||||
typedef pollset_t pollset_create_func(int maxfd);
|
||||
typedef int pollset_destroy_func(pollset_t ps);
|
||||
typedef int pollset_ctl_func(pollset_t ps, struct poll_ctl *pollctl_array, int array_length);
|
||||
typedef int pollset_poll_func(pollset_t ps, struct pollfd *polldata_array, int array_length, int timeout);
|
||||
static pollset_create_func* _pollset_create = NULL;
|
||||
static pollset_destroy_func* _pollset_destroy = NULL;
|
||||
static pollset_ctl_func* _pollset_ctl = NULL;
|
||||
static pollset_poll_func* _pollset_poll = NULL;
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_nio_ch_AixPollPort_init(JNIEnv* env, jclass this) {
|
||||
_pollset_create = (pollset_create_func*) dlsym(RTLD_DEFAULT, "pollset_create");
|
||||
_pollset_destroy = (pollset_destroy_func*) dlsym(RTLD_DEFAULT, "pollset_destroy");
|
||||
_pollset_ctl = (pollset_ctl_func*) dlsym(RTLD_DEFAULT, "pollset_ctl");
|
||||
_pollset_poll = (pollset_poll_func*) dlsym(RTLD_DEFAULT, "pollset_poll");
|
||||
if (_pollset_create == NULL || _pollset_destroy == NULL ||
|
||||
_pollset_ctl == NULL || _pollset_poll == NULL) {
|
||||
JNU_ThrowInternalError(env, "unable to get address of pollset functions");
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_nio_ch_AixPollPort_eventSize(JNIEnv* env, jclass this) {
|
||||
return sizeof(struct pollfd);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_nio_ch_AixPollPort_eventsOffset(JNIEnv* env, jclass this) {
|
||||
return offsetof(struct pollfd, events);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_nio_ch_AixPollPort_reventsOffset(JNIEnv* env, jclass this) {
|
||||
return offsetof(struct pollfd, revents);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_nio_ch_AixPollPort_fdOffset(JNIEnv* env, jclass this) {
|
||||
return offsetof(struct pollfd, fd);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_nio_ch_AixPollPort_pollsetCreate(JNIEnv *env, jclass c) {
|
||||
/* pollset_create can take the maximum number of fds, but we
|
||||
* cannot predict this number so we leave it at OPEN_MAX. */
|
||||
pollset_t ps = _pollset_create(-1);
|
||||
if (ps < 0) {
|
||||
JNU_ThrowIOExceptionWithLastError(env, "pollset_create failed");
|
||||
}
|
||||
return (int)ps;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_nio_ch_AixPollPort_pollsetCtl(JNIEnv *env, jclass c, jint ps,
|
||||
jint opcode, jint fd, jint events) {
|
||||
struct poll_ctl event;
|
||||
int res;
|
||||
|
||||
event.cmd = opcode;
|
||||
event.events = events;
|
||||
event.fd = fd;
|
||||
|
||||
RESTARTABLE(_pollset_ctl((pollset_t)ps, &event, 1 /* length */), res);
|
||||
|
||||
return (res == 0) ? 0 : errno;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_nio_ch_AixPollPort_pollsetPoll(JNIEnv *env, jclass c,
|
||||
jint ps, jlong address, jint numfds) {
|
||||
struct pollfd *events = jlong_to_ptr(address);
|
||||
int res;
|
||||
|
||||
RESTARTABLE(_pollset_poll(ps, events, numfds, -1), res);
|
||||
if (res < 0) {
|
||||
JNU_ThrowIOExceptionWithLastError(env, "pollset_poll failed");
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_nio_ch_AixPollPort_pollsetDestroy(JNIEnv *env, jclass c, jint ps) {
|
||||
int res;
|
||||
RESTARTABLE(_pollset_destroy((pollset_t)ps), res);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_nio_ch_AixPollPort_socketpair(JNIEnv* env, jclass clazz, jintArray sv) {
|
||||
int sp[2];
|
||||
if (socketpair(PF_UNIX, SOCK_STREAM, 0, sp) == -1) {
|
||||
JNU_ThrowIOExceptionWithLastError(env, "socketpair failed");
|
||||
} else {
|
||||
jint res[2];
|
||||
res[0] = (jint)sp[0];
|
||||
res[1] = (jint)sp[1];
|
||||
(*env)->SetIntArrayRegion(env, sv, 0, 2, &res[0]);
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_nio_ch_AixPollPort_interrupt(JNIEnv *env, jclass c, jint fd) {
|
||||
int res;
|
||||
int buf[1];
|
||||
buf[0] = 1;
|
||||
RESTARTABLE(write(fd, buf, 1), res);
|
||||
if (res < 0) {
|
||||
JNU_ThrowIOExceptionWithLastError(env, "write failed");
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_nio_ch_AixPollPort_drain1(JNIEnv *env, jclass cl, jint fd) {
|
||||
int res;
|
||||
char buf[1];
|
||||
RESTARTABLE(read(fd, buf, 1), res);
|
||||
if (res < 0) {
|
||||
JNU_ThrowIOExceptionWithLastError(env, "drain1 failed");
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_nio_ch_AixPollPort_close0(JNIEnv *env, jclass c, jint fd) {
|
||||
int res;
|
||||
RESTARTABLE(close(fd), res);
|
||||
}
|
227
jdk/src/aix/native/sun/nio/fs/AixNativeDispatcher.c
Normal file
227
jdk/src/aix/native/sun/nio/fs/AixNativeDispatcher.c
Normal file
@ -0,0 +1,227 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2013 SAP AG. 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 <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/mntctl.h>
|
||||
|
||||
#include "jni.h"
|
||||
#include "jni_util.h"
|
||||
|
||||
#include "sun_nio_fs_AixNativeDispatcher.h"
|
||||
|
||||
static jfieldID entry_name;
|
||||
static jfieldID entry_dir;
|
||||
static jfieldID entry_fstype;
|
||||
static jfieldID entry_options;
|
||||
|
||||
static jclass entry_cls;
|
||||
|
||||
/**
|
||||
* Call this to throw an internal UnixException when a system/library
|
||||
* call fails
|
||||
*/
|
||||
static void throwUnixException(JNIEnv* env, int errnum) {
|
||||
jobject x = JNU_NewObjectByName(env, "sun/nio/fs/UnixException",
|
||||
"(I)V", errnum);
|
||||
if (x != NULL) {
|
||||
(*env)->Throw(env, x);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialization
|
||||
*/
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_sun_nio_fs_AixNativeDispatcher_init(JNIEnv* env, jclass this)
|
||||
{
|
||||
jint flags = 0;
|
||||
jclass clazz;
|
||||
|
||||
clazz = (*env)->FindClass(env, "sun/nio/fs/UnixMountEntry");
|
||||
if (clazz == NULL) {
|
||||
return 0;
|
||||
}
|
||||
entry_name = (*env)->GetFieldID(env, clazz, "name", "[B");
|
||||
entry_dir = (*env)->GetFieldID(env, clazz, "dir", "[B");
|
||||
entry_fstype = (*env)->GetFieldID(env, clazz, "fstype", "[B");
|
||||
entry_options = (*env)->GetFieldID(env, clazz, "opts", "[B");
|
||||
entry_cls = (*env)->NewGlobalRef(env, clazz);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Special implementation of getextmntent (see SolarisNativeDispatcher.c)
|
||||
* that returns all entries at once.
|
||||
*/
|
||||
JNIEXPORT jobjectArray JNICALL
|
||||
Java_sun_nio_fs_AixNativeDispatcher_getmntctl(JNIEnv* env, jclass this)
|
||||
{
|
||||
int must_free_buf = 0;
|
||||
char stack_buf[1024];
|
||||
char* buffer = stack_buf;
|
||||
size_t buffer_size = 1024;
|
||||
int num_entries;
|
||||
int i;
|
||||
jobjectArray ret;
|
||||
struct vmount * vm;
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
num_entries = mntctl(MCTL_QUERY, buffer_size, buffer);
|
||||
if (num_entries != 0) {
|
||||
break;
|
||||
}
|
||||
if (must_free_buf) {
|
||||
free(buffer);
|
||||
}
|
||||
buffer_size *= 8;
|
||||
buffer = malloc(buffer_size);
|
||||
must_free_buf = 1;
|
||||
}
|
||||
/* Treat zero entries like errors. */
|
||||
if (num_entries <= 0) {
|
||||
if (must_free_buf) {
|
||||
free(buffer);
|
||||
}
|
||||
throwUnixException(env, errno);
|
||||
return NULL;
|
||||
}
|
||||
ret = (*env)->NewObjectArray(env, num_entries, entry_cls, NULL);
|
||||
if (ret == NULL) {
|
||||
if (must_free_buf) {
|
||||
free(buffer);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
vm = (struct vmount*)buffer;
|
||||
for (i = 0; i < num_entries; i++) {
|
||||
jsize len;
|
||||
jbyteArray bytes;
|
||||
const char* fstype;
|
||||
/* We set all relevant attributes so there is no need to call constructor. */
|
||||
jobject entry = (*env)->AllocObject(env, entry_cls);
|
||||
if (entry == NULL) {
|
||||
if (must_free_buf) {
|
||||
free(buffer);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
(*env)->SetObjectArrayElement(env, ret, i, entry);
|
||||
|
||||
/* vm->vmt_data[...].vmt_size is 32 bit aligned and also includes NULL byte. */
|
||||
/* Since we only need the characters, it is necessary to check string size manually. */
|
||||
len = strlen((char*)vm + vm->vmt_data[VMT_OBJECT].vmt_off);
|
||||
bytes = (*env)->NewByteArray(env, len);
|
||||
if (bytes == NULL) {
|
||||
if (must_free_buf) {
|
||||
free(buffer);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
(*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)((char *)vm + vm->vmt_data[VMT_OBJECT].vmt_off));
|
||||
(*env)->SetObjectField(env, entry, entry_name, bytes);
|
||||
|
||||
len = strlen((char*)vm + vm->vmt_data[VMT_STUB].vmt_off);
|
||||
bytes = (*env)->NewByteArray(env, len);
|
||||
if (bytes == NULL) {
|
||||
if (must_free_buf) {
|
||||
free(buffer);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
(*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)((char *)vm + vm->vmt_data[VMT_STUB].vmt_off));
|
||||
(*env)->SetObjectField(env, entry, entry_dir, bytes);
|
||||
|
||||
switch (vm->vmt_gfstype) {
|
||||
case MNT_J2:
|
||||
fstype = "jfs2";
|
||||
break;
|
||||
case MNT_NAMEFS:
|
||||
fstype = "namefs";
|
||||
break;
|
||||
case MNT_NFS:
|
||||
fstype = "nfs";
|
||||
break;
|
||||
case MNT_JFS:
|
||||
fstype = "jfs";
|
||||
break;
|
||||
case MNT_CDROM:
|
||||
fstype = "cdrom";
|
||||
break;
|
||||
case MNT_PROCFS:
|
||||
fstype = "procfs";
|
||||
break;
|
||||
case MNT_NFS3:
|
||||
fstype = "nfs3";
|
||||
break;
|
||||
case MNT_AUTOFS:
|
||||
fstype = "autofs";
|
||||
break;
|
||||
case MNT_UDF:
|
||||
fstype = "udfs";
|
||||
break;
|
||||
case MNT_NFS4:
|
||||
fstype = "nfs4";
|
||||
break;
|
||||
case MNT_CIFS:
|
||||
fstype = "smbfs";
|
||||
break;
|
||||
default:
|
||||
fstype = "unknown";
|
||||
}
|
||||
len = strlen(fstype);
|
||||
bytes = (*env)->NewByteArray(env, len);
|
||||
if (bytes == NULL) {
|
||||
if (must_free_buf) {
|
||||
free(buffer);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
(*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)fstype);
|
||||
(*env)->SetObjectField(env, entry, entry_fstype, bytes);
|
||||
|
||||
len = strlen((char*)vm + vm->vmt_data[VMT_ARGS].vmt_off);
|
||||
bytes = (*env)->NewByteArray(env, len);
|
||||
if (bytes == NULL) {
|
||||
if (must_free_buf) {
|
||||
free(buffer);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
(*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)((char *)vm + vm->vmt_data[VMT_ARGS].vmt_off));
|
||||
(*env)->SetObjectField(env, entry, entry_options, bytes);
|
||||
|
||||
/* goto the next vmount structure: */
|
||||
vm = (struct vmount *)((char *)vm + vm->vmt_length);
|
||||
}
|
||||
|
||||
if (must_free_buf) {
|
||||
free(buffer);
|
||||
}
|
||||
return ret;
|
||||
}
|
283
jdk/src/aix/native/sun/tools/attach/AixVirtualMachine.c
Normal file
283
jdk/src/aix/native/sun/tools/attach/AixVirtualMachine.c
Normal file
@ -0,0 +1,283 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2013 SAP AG. 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 "jni.h"
|
||||
#include "jni_util.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <dirent.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
/*
|
||||
* Based on 'LinuxVirtualMachine.c'. Non-relevant code has been removed and all
|
||||
* occurrences of the string "Linux" have been replaced by "Aix".
|
||||
*/
|
||||
|
||||
#include "sun_tools_attach_AixVirtualMachine.h"
|
||||
|
||||
#define RESTARTABLE(_cmd, _result) do { \
|
||||
do { \
|
||||
_result = _cmd; \
|
||||
} while((_result == -1) && (errno == EINTR)); \
|
||||
} while(0)
|
||||
|
||||
|
||||
/*
|
||||
* Class: sun_tools_attach_AixVirtualMachine
|
||||
* Method: socket
|
||||
* Signature: ()I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_sun_tools_attach_AixVirtualMachine_socket
|
||||
(JNIEnv *env, jclass cls)
|
||||
{
|
||||
int fd = socket(PF_UNIX, SOCK_STREAM, 0);
|
||||
if (fd == -1) {
|
||||
JNU_ThrowIOExceptionWithLastError(env, "socket");
|
||||
}
|
||||
/* added time out values */
|
||||
else {
|
||||
struct timeval tv;
|
||||
tv.tv_sec = 2 * 60;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char*)&tv, sizeof(tv));
|
||||
setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (char*)&tv, sizeof(tv));
|
||||
}
|
||||
return (jint)fd;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_tools_attach_AixVirtualMachine
|
||||
* Method: connect
|
||||
* Signature: (ILjava/lang/String;)I
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_sun_tools_attach_AixVirtualMachine_connect
|
||||
(JNIEnv *env, jclass cls, jint fd, jstring path)
|
||||
{
|
||||
jboolean isCopy;
|
||||
const char* p = GetStringPlatformChars(env, path, &isCopy);
|
||||
if (p != NULL) {
|
||||
struct sockaddr_un addr;
|
||||
int err = 0;
|
||||
|
||||
/* added missing structure initialization */
|
||||
memset(&addr,0, sizeof(addr));
|
||||
addr.sun_family = AF_UNIX;
|
||||
strcpy(addr.sun_path, p);
|
||||
/* We must call bind with the actual socketaddr length. This is obligatory for AS400. */
|
||||
if (connect(fd, (struct sockaddr*)&addr, SUN_LEN(&addr)) == -1) {
|
||||
err = errno;
|
||||
}
|
||||
|
||||
if (isCopy) {
|
||||
JNU_ReleaseStringPlatformChars(env, path, p);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the connect failed then we throw the appropriate exception
|
||||
* here (can't throw it before releasing the string as can't call
|
||||
* JNI with pending exception)
|
||||
*/
|
||||
if (err != 0) {
|
||||
if (err == ENOENT) {
|
||||
JNU_ThrowByName(env, "java/io/FileNotFoundException", NULL);
|
||||
} else {
|
||||
char* msg = strdup(strerror(err));
|
||||
JNU_ThrowIOException(env, msg);
|
||||
if (msg != NULL) {
|
||||
free(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Structure and callback function used to send a QUIT signal to all
|
||||
* children of a given process
|
||||
*/
|
||||
typedef struct {
|
||||
pid_t ppid;
|
||||
} SendQuitContext;
|
||||
|
||||
static void SendQuitCallback(const pid_t pid, void* user_data) {
|
||||
SendQuitContext* context = (SendQuitContext*)user_data;
|
||||
pid_t parent = getParent(pid);
|
||||
if (parent == context->ppid) {
|
||||
kill(pid, SIGQUIT);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_tools_attach_AixVirtualMachine
|
||||
* Method: sendQuitTo
|
||||
* Signature: (I)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_sun_tools_attach_AixVirtualMachine_sendQuitTo
|
||||
(JNIEnv *env, jclass cls, jint pid)
|
||||
{
|
||||
if (kill((pid_t)pid, SIGQUIT)) {
|
||||
JNU_ThrowIOExceptionWithLastError(env, "kill");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_tools_attach_AixVirtualMachine
|
||||
* Method: checkPermissions
|
||||
* Signature: (Ljava/lang/String;)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_sun_tools_attach_AixVirtualMachine_checkPermissions
|
||||
(JNIEnv *env, jclass cls, jstring path)
|
||||
{
|
||||
jboolean isCopy;
|
||||
const char* p = GetStringPlatformChars(env, path, &isCopy);
|
||||
if (p != NULL) {
|
||||
struct stat64 sb;
|
||||
uid_t uid, gid;
|
||||
int res;
|
||||
/* added missing initialization of the stat64 buffer */
|
||||
memset(&sb, 0, sizeof(struct stat64));
|
||||
|
||||
/*
|
||||
* Check that the path is owned by the effective uid/gid of this
|
||||
* process. Also check that group/other access is not allowed.
|
||||
*/
|
||||
uid = geteuid();
|
||||
gid = getegid();
|
||||
|
||||
res = stat64(p, &sb);
|
||||
if (res != 0) {
|
||||
/* save errno */
|
||||
res = errno;
|
||||
}
|
||||
|
||||
/* release p here before we throw an I/O exception */
|
||||
if (isCopy) {
|
||||
JNU_ReleaseStringPlatformChars(env, path, p);
|
||||
}
|
||||
|
||||
if (res == 0) {
|
||||
if ( (sb.st_uid != uid) || (sb.st_gid != gid) ||
|
||||
((sb.st_mode & (S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)) != 0) ) {
|
||||
JNU_ThrowIOException(env, "well-known file is not secure");
|
||||
}
|
||||
} else {
|
||||
char* msg = strdup(strerror(res));
|
||||
JNU_ThrowIOException(env, msg);
|
||||
if (msg != NULL) {
|
||||
free(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_tools_attach_AixVirtualMachine
|
||||
* Method: close
|
||||
* Signature: (I)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_sun_tools_attach_AixVirtualMachine_close
|
||||
(JNIEnv *env, jclass cls, jint fd)
|
||||
{
|
||||
int res;
|
||||
/* Fixed deadlock when this call of close by the client is not seen by the attach server
|
||||
* which has accepted the (very short) connection already and is waiting for the request. But read don't get a byte,
|
||||
* because the close is lost without shutdown.
|
||||
*/
|
||||
shutdown(fd, 2);
|
||||
RESTARTABLE(close(fd), res);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_tools_attach_AixVirtualMachine
|
||||
* Method: read
|
||||
* Signature: (I[BI)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_sun_tools_attach_AixVirtualMachine_read
|
||||
(JNIEnv *env, jclass cls, jint fd, jbyteArray ba, jint off, jint baLen)
|
||||
{
|
||||
unsigned char buf[128];
|
||||
size_t len = sizeof(buf);
|
||||
ssize_t n;
|
||||
|
||||
size_t remaining = (size_t)(baLen - off);
|
||||
if (len > remaining) {
|
||||
len = remaining;
|
||||
}
|
||||
|
||||
RESTARTABLE(read(fd, buf+off, len), n);
|
||||
if (n == -1) {
|
||||
JNU_ThrowIOExceptionWithLastError(env, "read");
|
||||
} else {
|
||||
if (n == 0) {
|
||||
n = -1; // EOF
|
||||
} else {
|
||||
(*env)->SetByteArrayRegion(env, ba, off, (jint)n, (jbyte *)(buf+off));
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_tools_attach_AixVirtualMachine
|
||||
* Method: write
|
||||
* Signature: (I[B)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_sun_tools_attach_AixVirtualMachine_write
|
||||
(JNIEnv *env, jclass cls, jint fd, jbyteArray ba, jint off, jint bufLen)
|
||||
{
|
||||
size_t remaining = bufLen;
|
||||
do {
|
||||
unsigned char buf[128];
|
||||
size_t len = sizeof(buf);
|
||||
int n;
|
||||
|
||||
if (len > remaining) {
|
||||
len = remaining;
|
||||
}
|
||||
(*env)->GetByteArrayRegion(env, ba, off, len, (jbyte *)buf);
|
||||
|
||||
RESTARTABLE(write(fd, buf, len), n);
|
||||
if (n > 0) {
|
||||
off += n;
|
||||
remaining -= n;
|
||||
} else {
|
||||
JNU_ThrowIOExceptionWithLastError(env, "write");
|
||||
return;
|
||||
}
|
||||
|
||||
} while (remaining > 0);
|
||||
}
|
86
jdk/src/aix/porting/porting_aix.c
Normal file
86
jdk/src/aix/porting/porting_aix.c
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 2012, 2013 SAP AG. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/ldr.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "porting_aix.h"
|
||||
|
||||
static unsigned char dladdr_buffer[0x4000];
|
||||
|
||||
static void fill_dll_info(void) {
|
||||
int rc = loadquery(L_GETINFO,dladdr_buffer, sizeof(dladdr_buffer));
|
||||
if (rc == -1) {
|
||||
fprintf(stderr, "loadquery failed (%d %s)", errno, strerror(errno));
|
||||
fflush(stderr);
|
||||
}
|
||||
}
|
||||
|
||||
static int dladdr_dont_reload(void* addr, Dl_info* info) {
|
||||
const struct ld_info* p = (struct ld_info*) dladdr_buffer;
|
||||
info->dli_fbase = 0; info->dli_fname = 0;
|
||||
info->dli_sname = 0; info->dli_saddr = 0;
|
||||
for (;;) {
|
||||
if (addr >= p->ldinfo_textorg &&
|
||||
addr < (((char*)p->ldinfo_textorg) + p->ldinfo_textsize)) {
|
||||
info->dli_fname = p->ldinfo_filename;
|
||||
info->dli_fbase = p->ldinfo_textorg;
|
||||
return 1; /* [sic] */
|
||||
}
|
||||
if (!p->ldinfo_next) {
|
||||
break;
|
||||
}
|
||||
p = (struct ld_info*)(((char*)p) + p->ldinfo_next);
|
||||
}
|
||||
return 0; /* [sic] */
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
int dladdr(void *addr, Dl_info *info) {
|
||||
static int loaded = 0;
|
||||
if (!loaded) {
|
||||
fill_dll_info();
|
||||
loaded = 1;
|
||||
}
|
||||
if (!addr) {
|
||||
return 0; /* [sic] */
|
||||
}
|
||||
/* Address could be AIX function descriptor? */
|
||||
void* const addr0 = *( (void**) addr );
|
||||
int rc = dladdr_dont_reload(addr, info);
|
||||
if (rc == 0) {
|
||||
rc = dladdr_dont_reload(addr0, info);
|
||||
if (rc == 0) { /* [sic] */
|
||||
fill_dll_info(); /* refill, maybe loadquery info is outdated */
|
||||
rc = dladdr_dont_reload(addr, info);
|
||||
if (rc == 0) {
|
||||
rc = dladdr_dont_reload(addr0, info);
|
||||
}
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
59
jdk/src/aix/porting/porting_aix.h
Normal file
59
jdk/src/aix/porting/porting_aix.h
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2012, 2013 SAP AG. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Header file to contain porting-relevant code which does not have a
|
||||
* home anywhere else.
|
||||
* This is intially based on hotspot/src/os/aix/vm/{loadlib,porting}_aix.{hpp,cpp}
|
||||
*/
|
||||
|
||||
/*
|
||||
* Aix' own version of dladdr().
|
||||
* This function tries to mimick dladdr(3) on Linux
|
||||
* (see http://linux.die.net/man/3/dladdr)
|
||||
* dladdr(3) is not POSIX but a GNU extension, and is not available on AIX.
|
||||
*
|
||||
* Differences between AIX dladdr and Linux dladdr:
|
||||
*
|
||||
* 1) Dl_info.dli_fbase: can never work, is disabled.
|
||||
* A loaded image on AIX is divided in multiple segments, at least two
|
||||
* (text and data) but potentially also far more. This is because the loader may
|
||||
* load each member into an own segment, as for instance happens with the libC.a
|
||||
* 2) Dl_info.dli_sname: This only works for code symbols (functions); for data, a
|
||||
* zero-length string is returned ("").
|
||||
* 3) Dl_info.dli_saddr: For code, this will return the entry point of the function,
|
||||
* not the function descriptor.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
const char *dli_fname; /* file path of loaded library */
|
||||
void *dli_fbase; /* doesn't make sence on AIX */
|
||||
const char *dli_sname; /* symbol name; "" if not known */
|
||||
void *dli_saddr; /* address of *entry* of function; not function descriptor; */
|
||||
} Dl_info;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
int dladdr(void *addr, Dl_info *info);
|
@ -85,6 +85,9 @@ void JLI_CmdToArgs(char *cmdline);
|
||||
#ifdef MACOSX
|
||||
#define JLI_Lseek lseek
|
||||
#endif
|
||||
#ifdef _AIX
|
||||
#define JLI_Lseek lseek
|
||||
#endif
|
||||
#endif /* _WIN32 */
|
||||
|
||||
/*
|
||||
|
497
jdk/src/share/lib/security/java.security-aix
Normal file
497
jdk/src/share/lib/security/java.security-aix
Normal file
@ -0,0 +1,497 @@
|
||||
#
|
||||
# This is the "master security properties file".
|
||||
#
|
||||
# An alternate java.security properties file may be specified
|
||||
# from the command line via the system property
|
||||
#
|
||||
# -Djava.security.properties=<URL>
|
||||
#
|
||||
# This properties file appends to the master security properties file.
|
||||
# If both properties files specify values for the same key, the value
|
||||
# from the command-line properties file is selected, as it is the last
|
||||
# one loaded.
|
||||
#
|
||||
# Also, if you specify
|
||||
#
|
||||
# -Djava.security.properties==<URL> (2 equals),
|
||||
#
|
||||
# then that properties file completely overrides the master security
|
||||
# properties file.
|
||||
#
|
||||
# To disable the ability to specify an additional properties file from
|
||||
# the command line, set the key security.overridePropertiesFile
|
||||
# to false in the master security properties file. It is set to true
|
||||
# by default.
|
||||
|
||||
# In this file, various security properties are set for use by
|
||||
# java.security classes. This is where users can statically register
|
||||
# Cryptography Package Providers ("providers" for short). The term
|
||||
# "provider" refers to a package or set of packages that supply a
|
||||
# concrete implementation of a subset of the cryptography aspects of
|
||||
# the Java Security API. A provider may, for example, implement one or
|
||||
# more digital signature algorithms or message digest algorithms.
|
||||
#
|
||||
# Each provider must implement a subclass of the Provider class.
|
||||
# To register a provider in this master security properties file,
|
||||
# specify the Provider subclass name and priority in the format
|
||||
#
|
||||
# security.provider.<n>=<className>
|
||||
#
|
||||
# This declares a provider, and specifies its preference
|
||||
# order n. The preference order is the order in which providers are
|
||||
# searched for requested algorithms (when no specific provider is
|
||||
# requested). The order is 1-based; 1 is the most preferred, followed
|
||||
# by 2, and so on.
|
||||
#
|
||||
# <className> must specify the subclass of the Provider class whose
|
||||
# constructor sets the values of various properties that are required
|
||||
# for the Java Security API to look up the algorithms or other
|
||||
# facilities implemented by the provider.
|
||||
#
|
||||
# There must be at least one provider specification in java.security.
|
||||
# There is a default provider that comes standard with the JDK. It
|
||||
# is called the "SUN" provider, and its Provider subclass
|
||||
# named Sun appears in the sun.security.provider package. Thus, the
|
||||
# "SUN" provider is registered via the following:
|
||||
#
|
||||
# security.provider.1=sun.security.provider.Sun
|
||||
#
|
||||
# (The number 1 is used for the default provider.)
|
||||
#
|
||||
# Note: Providers can be dynamically registered instead by calls to
|
||||
# either the addProvider or insertProviderAt method in the Security
|
||||
# class.
|
||||
|
||||
#
|
||||
# List of providers and their preference orders (see above):
|
||||
#
|
||||
security.provider.1=sun.security.provider.Sun
|
||||
security.provider.2=sun.security.rsa.SunRsaSign
|
||||
security.provider.3=sun.security.ec.SunEC
|
||||
security.provider.4=com.sun.net.ssl.internal.ssl.Provider
|
||||
security.provider.5=com.sun.crypto.provider.SunJCE
|
||||
security.provider.6=sun.security.jgss.SunProvider
|
||||
security.provider.7=com.sun.security.sasl.Provider
|
||||
security.provider.8=org.jcp.xml.dsig.internal.dom.XMLDSigRI
|
||||
security.provider.9=sun.security.smartcardio.SunPCSC
|
||||
|
||||
#
|
||||
# Sun Provider SecureRandom seed source.
|
||||
#
|
||||
# Select the primary source of seed data for the "SHA1PRNG" and
|
||||
# "NativePRNG" SecureRandom implementations in the "Sun" provider.
|
||||
# (Other SecureRandom implementations might also use this property.)
|
||||
#
|
||||
# On Unix-like systems (for example, Solaris/Linux/MacOS), the
|
||||
# "NativePRNG" and "SHA1PRNG" implementations obtains seed data from
|
||||
# special device files such as file:/dev/random.
|
||||
#
|
||||
# On Windows systems, specifying the URLs "file:/dev/random" or
|
||||
# "file:/dev/urandom" will enable the native Microsoft CryptoAPI seeding
|
||||
# mechanism for SHA1PRNG.
|
||||
#
|
||||
# By default, an attempt is made to use the entropy gathering device
|
||||
# specified by the "securerandom.source" Security property. If an
|
||||
# exception occurs while accessing the specified URL:
|
||||
#
|
||||
# SHA1PRNG:
|
||||
# the traditional system/thread activity algorithm will be used.
|
||||
#
|
||||
# NativePRNG:
|
||||
# a default value of /dev/random will be used. If neither
|
||||
# are available, the implementation will be disabled.
|
||||
# "file" is the only currently supported protocol type.
|
||||
#
|
||||
# The entropy gathering device can also be specified with the System
|
||||
# property "java.security.egd". For example:
|
||||
#
|
||||
# % java -Djava.security.egd=file:/dev/random MainClass
|
||||
#
|
||||
# Specifying this System property will override the
|
||||
# "securerandom.source" Security property.
|
||||
#
|
||||
# In addition, if "file:/dev/random" or "file:/dev/urandom" is
|
||||
# specified, the "NativePRNG" implementation will be more preferred than
|
||||
# SHA1PRNG in the Sun provider.
|
||||
#
|
||||
securerandom.source=file:/dev/random
|
||||
|
||||
#
|
||||
# A list of known strong SecureRandom implementations.
|
||||
#
|
||||
# To help guide applications in selecting a suitable strong
|
||||
# java.security.SecureRandom implementation, Java distributions should
|
||||
# indicate a list of known strong implementations using the property.
|
||||
#
|
||||
# This is a comma-separated list of algorithm and/or algorithm:provider
|
||||
# entries.
|
||||
#
|
||||
securerandom.strongAlgorithms=NativePRNGBlocking:SUN
|
||||
|
||||
#
|
||||
# Class to instantiate as the javax.security.auth.login.Configuration
|
||||
# provider.
|
||||
#
|
||||
login.configuration.provider=sun.security.provider.ConfigFile
|
||||
|
||||
#
|
||||
# Default login configuration file
|
||||
#
|
||||
#login.config.url.1=file:${user.home}/.java.login.config
|
||||
|
||||
#
|
||||
# Class to instantiate as the system Policy. This is the name of the class
|
||||
# that will be used as the Policy object.
|
||||
#
|
||||
policy.provider=sun.security.provider.PolicyFile
|
||||
|
||||
# The default is to have a single system-wide policy file,
|
||||
# and a policy file in the user's home directory.
|
||||
policy.url.1=file:${java.home}/lib/security/java.policy
|
||||
policy.url.2=file:${user.home}/.java.policy
|
||||
|
||||
# whether or not we expand properties in the policy file
|
||||
# if this is set to false, properties (${...}) will not be expanded in policy
|
||||
# files.
|
||||
policy.expandProperties=true
|
||||
|
||||
# whether or not we allow an extra policy to be passed on the command line
|
||||
# with -Djava.security.policy=somefile. Comment out this line to disable
|
||||
# this feature.
|
||||
policy.allowSystemProperty=true
|
||||
|
||||
# whether or not we look into the IdentityScope for trusted Identities
|
||||
# when encountering a 1.1 signed JAR file. If the identity is found
|
||||
# and is trusted, we grant it AllPermission.
|
||||
policy.ignoreIdentityScope=false
|
||||
|
||||
#
|
||||
# Default keystore type.
|
||||
#
|
||||
keystore.type=jks
|
||||
|
||||
#
|
||||
# List of comma-separated packages that start with or equal this string
|
||||
# will cause a security exception to be thrown when
|
||||
# passed to checkPackageAccess unless the
|
||||
# corresponding RuntimePermission ("accessClassInPackage."+package) has
|
||||
# been granted.
|
||||
package.access=sun.,\
|
||||
com.sun.xml.internal.,\
|
||||
com.sun.imageio.,\
|
||||
com.sun.istack.internal.,\
|
||||
com.sun.jmx.,\
|
||||
com.sun.media.sound.,\
|
||||
com.sun.proxy.,\
|
||||
com.sun.corba.se.,\
|
||||
com.sun.org.apache.bcel.internal.,\
|
||||
com.sun.org.apache.regexp.internal.,\
|
||||
com.sun.org.apache.xerces.internal.,\
|
||||
com.sun.org.apache.xpath.internal.,\
|
||||
com.sun.org.apache.xalan.internal.extensions.,\
|
||||
com.sun.org.apache.xalan.internal.lib.,\
|
||||
com.sun.org.apache.xalan.internal.res.,\
|
||||
com.sun.org.apache.xalan.internal.templates.,\
|
||||
com.sun.org.apache.xalan.internal.utils.,\
|
||||
com.sun.org.apache.xalan.internal.xslt.,\
|
||||
com.sun.org.apache.xalan.internal.xsltc.cmdline.,\
|
||||
com.sun.org.apache.xalan.internal.xsltc.compiler.,\
|
||||
com.sun.org.apache.xalan.internal.xsltc.trax.,\
|
||||
com.sun.org.apache.xalan.internal.xsltc.util.,\
|
||||
com.sun.org.apache.xml.internal.res.,\
|
||||
com.sun.org.apache.xml.internal.security.,\
|
||||
com.sun.org.apache.xml.internal.serializer.utils.,\
|
||||
com.sun.org.apache.xml.internal.utils.,\
|
||||
com.sun.org.glassfish.,\
|
||||
com.oracle.xmlns.internal.,\
|
||||
com.oracle.webservices.internal.,\
|
||||
oracle.jrockit.jfr.,\
|
||||
org.jcp.xml.dsig.internal.,\
|
||||
jdk.internal.,\
|
||||
jdk.nashorn.internal.,\
|
||||
jdk.nashorn.tools.
|
||||
|
||||
|
||||
#
|
||||
# List of comma-separated packages that start with or equal this string
|
||||
# will cause a security exception to be thrown when
|
||||
# passed to checkPackageDefinition unless the
|
||||
# corresponding RuntimePermission ("defineClassInPackage."+package) has
|
||||
# been granted.
|
||||
#
|
||||
# by default, none of the class loaders supplied with the JDK call
|
||||
# checkPackageDefinition.
|
||||
#
|
||||
package.definition=sun.,\
|
||||
com.sun.xml.internal.,\
|
||||
com.sun.imageio.,\
|
||||
com.sun.istack.internal.,\
|
||||
com.sun.jmx.,\
|
||||
com.sun.media.sound.,\
|
||||
com.sun.proxy.,\
|
||||
com.sun.corba.se.,\
|
||||
com.sun.org.apache.bcel.internal.,\
|
||||
com.sun.org.apache.regexp.internal.,\
|
||||
com.sun.org.apache.xerces.internal.,\
|
||||
com.sun.org.apache.xpath.internal.,\
|
||||
com.sun.org.apache.xalan.internal.extensions.,\
|
||||
com.sun.org.apache.xalan.internal.lib.,\
|
||||
com.sun.org.apache.xalan.internal.res.,\
|
||||
com.sun.org.apache.xalan.internal.templates.,\
|
||||
com.sun.org.apache.xalan.internal.utils.,\
|
||||
com.sun.org.apache.xalan.internal.xslt.,\
|
||||
com.sun.org.apache.xalan.internal.xsltc.cmdline.,\
|
||||
com.sun.org.apache.xalan.internal.xsltc.compiler.,\
|
||||
com.sun.org.apache.xalan.internal.xsltc.trax.,\
|
||||
com.sun.org.apache.xalan.internal.xsltc.util.,\
|
||||
com.sun.org.apache.xml.internal.res.,\
|
||||
com.sun.org.apache.xml.internal.security.,\
|
||||
com.sun.org.apache.xml.internal.serializer.utils.,\
|
||||
com.sun.org.apache.xml.internal.utils.,\
|
||||
com.sun.org.glassfish.,\
|
||||
com.oracle.xmlns.internal.,\
|
||||
com.oracle.webservices.internal.,\
|
||||
oracle.jrockit.jfr.,\
|
||||
org.jcp.xml.dsig.internal.,\
|
||||
jdk.internal.,\
|
||||
jdk.nashorn.internal.,\
|
||||
jdk.nashorn.tools.
|
||||
|
||||
|
||||
#
|
||||
# Determines whether this properties file can be appended to
|
||||
# or overridden on the command line via -Djava.security.properties
|
||||
#
|
||||
security.overridePropertiesFile=true
|
||||
|
||||
#
|
||||
# Determines the default key and trust manager factory algorithms for
|
||||
# the javax.net.ssl package.
|
||||
#
|
||||
ssl.KeyManagerFactory.algorithm=SunX509
|
||||
ssl.TrustManagerFactory.algorithm=PKIX
|
||||
|
||||
#
|
||||
# The Java-level namelookup cache policy for successful lookups:
|
||||
#
|
||||
# any negative value: caching forever
|
||||
# any positive value: the number of seconds to cache an address for
|
||||
# zero: do not cache
|
||||
#
|
||||
# default value is forever (FOREVER). For security reasons, this
|
||||
# caching is made forever when a security manager is set. When a security
|
||||
# manager is not set, the default behavior in this implementation
|
||||
# is to cache for 30 seconds.
|
||||
#
|
||||
# NOTE: setting this to anything other than the default value can have
|
||||
# serious security implications. Do not set it unless
|
||||
# you are sure you are not exposed to DNS spoofing attack.
|
||||
#
|
||||
#networkaddress.cache.ttl=-1
|
||||
|
||||
# The Java-level namelookup cache policy for failed lookups:
|
||||
#
|
||||
# any negative value: cache forever
|
||||
# any positive value: the number of seconds to cache negative lookup results
|
||||
# zero: do not cache
|
||||
#
|
||||
# In some Microsoft Windows networking environments that employ
|
||||
# the WINS name service in addition to DNS, name service lookups
|
||||
# that fail may take a noticeably long time to return (approx. 5 seconds).
|
||||
# For this reason the default caching policy is to maintain these
|
||||
# results for 10 seconds.
|
||||
#
|
||||
#
|
||||
networkaddress.cache.negative.ttl=10
|
||||
|
||||
#
|
||||
# Properties to configure OCSP for certificate revocation checking
|
||||
#
|
||||
|
||||
# Enable OCSP
|
||||
#
|
||||
# By default, OCSP is not used for certificate revocation checking.
|
||||
# This property enables the use of OCSP when set to the value "true".
|
||||
#
|
||||
# NOTE: SocketPermission is required to connect to an OCSP responder.
|
||||
#
|
||||
# Example,
|
||||
# ocsp.enable=true
|
||||
|
||||
#
|
||||
# Location of the OCSP responder
|
||||
#
|
||||
# By default, the location of the OCSP responder is determined implicitly
|
||||
# from the certificate being validated. This property explicitly specifies
|
||||
# the location of the OCSP responder. The property is used when the
|
||||
# Authority Information Access extension (defined in RFC 3280) is absent
|
||||
# from the certificate or when it requires overriding.
|
||||
#
|
||||
# Example,
|
||||
# ocsp.responderURL=http://ocsp.example.net:80
|
||||
|
||||
#
|
||||
# Subject name of the OCSP responder's certificate
|
||||
#
|
||||
# By default, the certificate of the OCSP responder is that of the issuer
|
||||
# of the certificate being validated. This property identifies the certificate
|
||||
# of the OCSP responder when the default does not apply. Its value is a string
|
||||
# distinguished name (defined in RFC 2253) which identifies a certificate in
|
||||
# the set of certificates supplied during cert path validation. In cases where
|
||||
# the subject name alone is not sufficient to uniquely identify the certificate
|
||||
# then both the "ocsp.responderCertIssuerName" and
|
||||
# "ocsp.responderCertSerialNumber" properties must be used instead. When this
|
||||
# property is set then those two properties are ignored.
|
||||
#
|
||||
# Example,
|
||||
# ocsp.responderCertSubjectName="CN=OCSP Responder, O=XYZ Corp"
|
||||
|
||||
#
|
||||
# Issuer name of the OCSP responder's certificate
|
||||
#
|
||||
# By default, the certificate of the OCSP responder is that of the issuer
|
||||
# of the certificate being validated. This property identifies the certificate
|
||||
# of the OCSP responder when the default does not apply. Its value is a string
|
||||
# distinguished name (defined in RFC 2253) which identifies a certificate in
|
||||
# the set of certificates supplied during cert path validation. When this
|
||||
# property is set then the "ocsp.responderCertSerialNumber" property must also
|
||||
# be set. When the "ocsp.responderCertSubjectName" property is set then this
|
||||
# property is ignored.
|
||||
#
|
||||
# Example,
|
||||
# ocsp.responderCertIssuerName="CN=Enterprise CA, O=XYZ Corp"
|
||||
|
||||
#
|
||||
# Serial number of the OCSP responder's certificate
|
||||
#
|
||||
# By default, the certificate of the OCSP responder is that of the issuer
|
||||
# of the certificate being validated. This property identifies the certificate
|
||||
# of the OCSP responder when the default does not apply. Its value is a string
|
||||
# of hexadecimal digits (colon or space separators may be present) which
|
||||
# identifies a certificate in the set of certificates supplied during cert path
|
||||
# validation. When this property is set then the "ocsp.responderCertIssuerName"
|
||||
# property must also be set. When the "ocsp.responderCertSubjectName" property
|
||||
# is set then this property is ignored.
|
||||
#
|
||||
# Example,
|
||||
# ocsp.responderCertSerialNumber=2A:FF:00
|
||||
|
||||
#
|
||||
# Policy for failed Kerberos KDC lookups:
|
||||
#
|
||||
# When a KDC is unavailable (network error, service failure, etc), it is
|
||||
# put inside a blacklist and accessed less often for future requests. The
|
||||
# value (case-insensitive) for this policy can be:
|
||||
#
|
||||
# tryLast
|
||||
# KDCs in the blacklist are always tried after those not on the list.
|
||||
#
|
||||
# tryLess[:max_retries,timeout]
|
||||
# KDCs in the blacklist are still tried by their order in the configuration,
|
||||
# but with smaller max_retries and timeout values. max_retries and timeout
|
||||
# are optional numerical parameters (default 1 and 5000, which means once
|
||||
# and 5 seconds). Please notes that if any of the values defined here is
|
||||
# more than what is defined in krb5.conf, it will be ignored.
|
||||
#
|
||||
# Whenever a KDC is detected as available, it is removed from the blacklist.
|
||||
# The blacklist is reset when krb5.conf is reloaded. You can add
|
||||
# refreshKrb5Config=true to a JAAS configuration file so that krb5.conf is
|
||||
# reloaded whenever a JAAS authentication is attempted.
|
||||
#
|
||||
# Example,
|
||||
# krb5.kdc.bad.policy = tryLast
|
||||
# krb5.kdc.bad.policy = tryLess:2,2000
|
||||
krb5.kdc.bad.policy = tryLast
|
||||
|
||||
# Algorithm restrictions for certification path (CertPath) processing
|
||||
#
|
||||
# In some environments, certain algorithms or key lengths may be undesirable
|
||||
# for certification path building and validation. For example, "MD2" is
|
||||
# generally no longer considered to be a secure hash algorithm. This section
|
||||
# describes the mechanism for disabling algorithms based on algorithm name
|
||||
# and/or key length. This includes algorithms used in certificates, as well
|
||||
# as revocation information such as CRLs and signed OCSP Responses.
|
||||
#
|
||||
# The syntax of the disabled algorithm string is described as this Java
|
||||
# BNF-style:
|
||||
# DisabledAlgorithms:
|
||||
# " DisabledAlgorithm { , DisabledAlgorithm } "
|
||||
#
|
||||
# DisabledAlgorithm:
|
||||
# AlgorithmName [Constraint]
|
||||
#
|
||||
# AlgorithmName:
|
||||
# (see below)
|
||||
#
|
||||
# Constraint:
|
||||
# KeySizeConstraint
|
||||
#
|
||||
# KeySizeConstraint:
|
||||
# keySize Operator DecimalInteger
|
||||
#
|
||||
# Operator:
|
||||
# <= | < | == | != | >= | >
|
||||
#
|
||||
# DecimalInteger:
|
||||
# DecimalDigits
|
||||
#
|
||||
# DecimalDigits:
|
||||
# DecimalDigit {DecimalDigit}
|
||||
#
|
||||
# DecimalDigit: one of
|
||||
# 1 2 3 4 5 6 7 8 9 0
|
||||
#
|
||||
# The "AlgorithmName" is the standard algorithm name of the disabled
|
||||
# algorithm. See "Java Cryptography Architecture Standard Algorithm Name
|
||||
# Documentation" for information about Standard Algorithm Names. Matching
|
||||
# is performed using a case-insensitive sub-element matching rule. (For
|
||||
# example, in "SHA1withECDSA" the sub-elements are "SHA1" for hashing and
|
||||
# "ECDSA" for signatures.) If the assertion "AlgorithmName" is a
|
||||
# sub-element of the certificate algorithm name, the algorithm will be
|
||||
# rejected during certification path building and validation. For example,
|
||||
# the assertion algorithm name "DSA" will disable all certificate algorithms
|
||||
# that rely on DSA, such as NONEwithDSA, SHA1withDSA. However, the assertion
|
||||
# will not disable algorithms related to "ECDSA".
|
||||
#
|
||||
# A "Constraint" provides further guidance for the algorithm being specified.
|
||||
# The "KeySizeConstraint" requires a key of a valid size range if the
|
||||
# "AlgorithmName" is of a key algorithm. The "DecimalInteger" indicates the
|
||||
# key size specified in number of bits. For example, "RSA keySize <= 1024"
|
||||
# indicates that any RSA key with key size less than or equal to 1024 bits
|
||||
# should be disabled, and "RSA keySize < 1024, RSA keySize > 2048" indicates
|
||||
# that any RSA key with key size less than 1024 or greater than 2048 should
|
||||
# be disabled. Note that the "KeySizeConstraint" only makes sense to key
|
||||
# algorithms.
|
||||
#
|
||||
# Note: This property is currently used by Oracle's PKIX implementation. It
|
||||
# is not guaranteed to be examined and used by other implementations.
|
||||
#
|
||||
# Example:
|
||||
# jdk.certpath.disabledAlgorithms=MD2, DSA, RSA keySize < 2048
|
||||
#
|
||||
#
|
||||
jdk.certpath.disabledAlgorithms=MD2, RSA keySize < 1024
|
||||
|
||||
# Algorithm restrictions for Secure Socket Layer/Transport Layer Security
|
||||
# (SSL/TLS) processing
|
||||
#
|
||||
# In some environments, certain algorithms or key lengths may be undesirable
|
||||
# when using SSL/TLS. This section describes the mechanism for disabling
|
||||
# algorithms during SSL/TLS security parameters negotiation, including cipher
|
||||
# suites selection, peer authentication and key exchange mechanisms.
|
||||
#
|
||||
# For PKI-based peer authentication and key exchange mechanisms, this list
|
||||
# of disabled algorithms will also be checked during certification path
|
||||
# building and validation, including algorithms used in certificates, as
|
||||
# well as revocation information such as CRLs and signed OCSP Responses.
|
||||
# This is in addition to the jdk.certpath.disabledAlgorithms property above.
|
||||
#
|
||||
# See the specification of "jdk.certpath.disabledAlgorithms" for the
|
||||
# syntax of the disabled algorithm string.
|
||||
#
|
||||
# Note: This property is currently used by Oracle's JSSE implementation.
|
||||
# It is not guaranteed to be examined and used by other implementations.
|
||||
#
|
||||
# Example:
|
||||
# jdk.tls.disabledAlgorithms=MD5, SHA1, DSA, RSA keySize < 2048
|
||||
|
@ -90,6 +90,41 @@
|
||||
#include "classfile_constants.h"
|
||||
#include "opcodes.in_out"
|
||||
|
||||
/* On AIX malloc(0) and calloc(0, ...) return a NULL pointer, which is legal,
|
||||
* but the code here does not handles it. So we wrap the methods and return non-NULL
|
||||
* pointers even if we allocate 0 bytes.
|
||||
*/
|
||||
#ifdef _AIX
|
||||
static int aix_dummy;
|
||||
static void* aix_malloc(size_t len) {
|
||||
if (len == 0) {
|
||||
return &aix_dummy;
|
||||
}
|
||||
return malloc(len);
|
||||
}
|
||||
|
||||
static void* aix_calloc(size_t n, size_t size) {
|
||||
if (n == 0) {
|
||||
return &aix_dummy;
|
||||
}
|
||||
return calloc(n, size);
|
||||
}
|
||||
|
||||
static void aix_free(void* p) {
|
||||
if (p == &aix_dummy) {
|
||||
return;
|
||||
}
|
||||
free(p);
|
||||
}
|
||||
|
||||
#undef malloc
|
||||
#undef calloc
|
||||
#undef free
|
||||
#define malloc aix_malloc
|
||||
#define calloc aix_calloc
|
||||
#define free aix_free
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
/* use setjmp/longjmp versions that do not save/restore the signal mask */
|
||||
#define setjmp _setjmp
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* 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
|
||||
@ -67,7 +67,7 @@ JNI_OnLoad(JavaVM *vm, void *reserved)
|
||||
supporting socket APIs are available
|
||||
*/
|
||||
IPv6_available = IPv6_supported() & (!preferIPv4Stack);
|
||||
initLocalAddrTable ();
|
||||
platformInit();
|
||||
parseExclusiveBindProperty(env);
|
||||
|
||||
return JNI_VERSION_1_2;
|
||||
|
@ -140,7 +140,7 @@ NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port, struct sockaddr
|
||||
JNIEXPORT jobject JNICALL
|
||||
NET_SockaddrToInetAddress(JNIEnv *env, struct sockaddr *him, int *port);
|
||||
|
||||
void initLocalAddrTable ();
|
||||
void platformInit();
|
||||
void parseExclusiveBindProperty(JNIEnv *env);
|
||||
|
||||
void
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2003, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 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
|
||||
@ -86,10 +86,13 @@ __typeof__ ( __mlib_sincosf) mlib_sincosf
|
||||
|
||||
void *__mlib_malloc(mlib_u32 size)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
#if defined(_MSC_VER) || defined(AIX)
|
||||
/*
|
||||
* Currently, all MS C compilers for Win32 platforms default to 8 byte
|
||||
* alignment. -- from stdlib.h of MS VC++5.0.
|
||||
*
|
||||
* On AIX, the malloc subroutine returns a pointer to space suitably
|
||||
* aligned for the storage of any type of object (see 'man malloc').
|
||||
*/
|
||||
return (void *) malloc(size);
|
||||
#elif defined(MACOSX)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2003, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 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
|
||||
@ -57,7 +57,7 @@ typedef unsigned int mlib_u32;
|
||||
typedef float mlib_f32;
|
||||
typedef double mlib_d64;
|
||||
|
||||
#if defined(__SUNPRO_C) || defined(__SUNPRO_CC) || defined(__GNUC__)
|
||||
#if defined(__SUNPRO_C) || defined(__SUNPRO_CC) || defined(__GNUC__) || defined(_AIX)
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
@ -39,7 +39,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define DEBUG 0
|
||||
#define DEBUG_KERN_TABLE 0
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
@ -99,14 +99,14 @@ KernTable::KernTable(const LETableReference& base, LEErrorCode &success)
|
||||
: pairsSwapped(NULL), fTable(base)
|
||||
{
|
||||
if(LE_FAILURE(success) || (fTable.isEmpty())) {
|
||||
#if DEBUG
|
||||
#if DEBUG_KERN_TABLE
|
||||
fprintf(stderr, "no kern data\n");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
LEReferenceTo<KernTableHeader> header(fTable, success);
|
||||
|
||||
#if DEBUG
|
||||
#if DEBUG_KERN_TABLE
|
||||
// dump first 32 bytes of header
|
||||
for (int i = 0; i < 64; ++i) {
|
||||
fprintf(stderr, "%0.2x ", ((const char*)header.getAlias())[i]&0xff);
|
||||
@ -171,7 +171,7 @@ KernTable::KernTable(const LETableReference& base, LEErrorCode &success)
|
||||
fprintf(stderr, " searchRange: %d entrySelector: %d rangeShift: %d\n", searchRange, entrySelector, rangeShift);
|
||||
fprintf(stderr, "[[ ignored font table entries: range %d selector %d shift %d ]]\n", SWAPW(table->searchRange), SWAPW(table->entrySelector), SWAPW(table->rangeShift));
|
||||
#endif
|
||||
#if DEBUG
|
||||
#if DEBUG_KERN_TABLE
|
||||
fprintf(stderr, "coverage: %0.4x nPairs: %d pairs 0x%x\n", coverage, nPairs, pairsSwapped);
|
||||
fprintf(stderr,
|
||||
" searchRange(pairs): %d entrySelector: %d rangeShift(pairs): %d\n",
|
||||
@ -242,7 +242,7 @@ void KernTable::process(LEGlyphStorage& storage, LEErrorCode &success)
|
||||
p = tp;
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
#if DEBUG_KERN_TABLE
|
||||
fprintf(stderr, "binary search for %0.8x\n", key);
|
||||
#endif
|
||||
|
||||
@ -251,13 +251,13 @@ void KernTable::process(LEGlyphStorage& storage, LEErrorCode &success)
|
||||
probe >>= 1;
|
||||
tp = (const PairInfo*)(p + (probe/KERN_PAIRINFO_SIZE));
|
||||
le_uint32 tkey = tp->key;
|
||||
#if DEBUG
|
||||
#if DEBUG_KERN_TABLE
|
||||
fprintf(stdout, " %.3d (%0.8x)\n", (tp - pairsSwapped), tkey);
|
||||
#endif
|
||||
if (tkey <= key) {
|
||||
if (tkey == key) {
|
||||
le_int16 value = SWAPW(tp->value);
|
||||
#if DEBUG
|
||||
#if DEBUG_KERN_TABLE
|
||||
fprintf(stdout, "binary found kerning pair %x:%x at %d, value: 0x%x (%g)\n",
|
||||
storage[i-1], storage[i], i, value & 0xffff, font->xUnitsToPoints(value));
|
||||
fflush(stdout);
|
||||
|
@ -65,6 +65,13 @@ typedef unsigned long ulong_t;
|
||||
typedef enum boolean { B_FALSE, B_TRUE } boolean_t;
|
||||
#endif /* _ALLBSD_SOURCE */
|
||||
|
||||
#ifdef AIX
|
||||
#define B_FALSE FALSE
|
||||
#define B_TRUE TRUE
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned long ulong_t;
|
||||
#endif /* AIX */
|
||||
|
||||
#ifdef _WIN32
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned long ulong_t;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* 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
|
||||
@ -30,8 +30,8 @@
|
||||
#include "sys.h"
|
||||
#include "util.h"
|
||||
|
||||
#if defined(LINUX) || defined(_ALLBSD_SOURCE)
|
||||
/* Linux */
|
||||
#if defined(LINUX) || defined(_ALLBSD_SOURCE) || defined(AIX)
|
||||
/* Linux, BSD, AIX */
|
||||
#define FORK() fork()
|
||||
#else
|
||||
/* Solaris (make sure we always get the POSIX-specified behavior) */
|
||||
|
@ -41,7 +41,11 @@
|
||||
|
||||
#define JVM_DLL "libjvm.so"
|
||||
#define JAVA_DLL "libjava.so"
|
||||
#ifdef AIX
|
||||
#define LD_LIBRARY_PATH "LIBPATH"
|
||||
#else
|
||||
#define LD_LIBRARY_PATH "LD_LIBRARY_PATH"
|
||||
#endif
|
||||
|
||||
/* help jettison the LD_LIBRARY_PATH settings in the future */
|
||||
#ifndef SETENV_REQUIRED
|
||||
@ -287,6 +291,11 @@ RequiresSetenv(int wanted, const char *jvmpath) {
|
||||
char *dmllp = NULL;
|
||||
char *p; /* a utility pointer */
|
||||
|
||||
#ifdef AIX
|
||||
/* We always have to set the LIBPATH on AIX because ld doesn't support $ORIGIN. */
|
||||
return JNI_TRUE;
|
||||
#endif
|
||||
|
||||
llp = getenv("LD_LIBRARY_PATH");
|
||||
#ifdef __solaris__
|
||||
dmllp = (CURRENT_DATA_MODEL == 32)
|
||||
@ -598,7 +607,7 @@ CreateExecutionEnvironment(int *pargc, char ***pargv,
|
||||
* If not on Solaris, assume only a single LD_LIBRARY_PATH
|
||||
* variable.
|
||||
*/
|
||||
runpath = getenv("LD_LIBRARY_PATH");
|
||||
runpath = getenv(LD_LIBRARY_PATH);
|
||||
#endif /* __solaris__ */
|
||||
|
||||
/* runpath contains current effective LD_LIBRARY_PATH setting */
|
||||
@ -606,8 +615,12 @@ CreateExecutionEnvironment(int *pargc, char ***pargv,
|
||||
jvmpath = JLI_StringDup(jvmpath);
|
||||
new_runpath = JLI_MemAlloc(((runpath != NULL) ? JLI_StrLen(runpath) : 0) +
|
||||
2 * JLI_StrLen(jrepath) + 2 * JLI_StrLen(arch) +
|
||||
#ifdef AIX
|
||||
/* On AIX we additionally need 'jli' in the path because ld doesn't support $ORIGIN. */
|
||||
JLI_StrLen(jrepath) + JLI_StrLen(arch) + JLI_StrLen("/lib//jli:") +
|
||||
#endif
|
||||
JLI_StrLen(jvmpath) + 52);
|
||||
newpath = new_runpath + JLI_StrLen("LD_LIBRARY_PATH=");
|
||||
newpath = new_runpath + JLI_StrLen(LD_LIBRARY_PATH "=");
|
||||
|
||||
|
||||
/*
|
||||
@ -619,9 +632,12 @@ CreateExecutionEnvironment(int *pargc, char ***pargv,
|
||||
if (lastslash)
|
||||
*lastslash = '\0';
|
||||
|
||||
sprintf(new_runpath, "LD_LIBRARY_PATH="
|
||||
sprintf(new_runpath, LD_LIBRARY_PATH "="
|
||||
"%s:"
|
||||
"%s/lib/%s:"
|
||||
#ifdef AIX
|
||||
"%s/lib/%s/jli:" /* Needed on AIX because ld doesn't support $ORIGIN. */
|
||||
#endif
|
||||
"%s/../lib/%s",
|
||||
jvmpath,
|
||||
#ifdef DUAL_MODE
|
||||
@ -629,6 +645,9 @@ CreateExecutionEnvironment(int *pargc, char ***pargv,
|
||||
jrepath, GetArchPath(wanted)
|
||||
#else /* !DUAL_MODE */
|
||||
jrepath, arch,
|
||||
#ifdef AIX
|
||||
jrepath, arch,
|
||||
#endif
|
||||
jrepath, arch
|
||||
#endif /* DUAL_MODE */
|
||||
);
|
||||
@ -1000,7 +1019,7 @@ void SplashFreeLibrary() {
|
||||
int
|
||||
ContinueInNewThread0(int (JNICALL *continuation)(void *), jlong stack_size, void * args) {
|
||||
int rslt;
|
||||
#ifdef __linux__
|
||||
#ifndef __solaris__
|
||||
pthread_t tid;
|
||||
pthread_attr_t attr;
|
||||
pthread_attr_init(&attr);
|
||||
@ -1025,7 +1044,7 @@ ContinueInNewThread0(int (JNICALL *continuation)(void *), jlong stack_size, void
|
||||
}
|
||||
|
||||
pthread_attr_destroy(&attr);
|
||||
#else /* ! __linux__ */
|
||||
#else /* __solaris__ */
|
||||
thread_t tid;
|
||||
long flags = 0;
|
||||
if (thr_create(NULL, stack_size, (void *(*)(void *))continuation, args, flags, &tid) == 0) {
|
||||
@ -1036,7 +1055,7 @@ ContinueInNewThread0(int (JNICALL *continuation)(void *), jlong stack_size, void
|
||||
/* See above. Continue in current thread if thr_create() failed */
|
||||
rslt = continuation(args);
|
||||
}
|
||||
#endif /* __linux__ */
|
||||
#endif /* !__solaris__ */
|
||||
return rslt;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* 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
|
||||
@ -45,23 +45,19 @@ extern char **environ;
|
||||
* A collection of useful strings. One should think of these as #define
|
||||
* entries, but actual strings can be more efficient (with many compilers).
|
||||
*/
|
||||
#ifdef __linux__
|
||||
static const char *system_dir = "/usr/java";
|
||||
static const char *user_dir = "/java";
|
||||
#else /* Solaris */
|
||||
#ifdef __solaris__
|
||||
static const char *system_dir = "/usr/jdk";
|
||||
static const char *user_dir = "/jdk";
|
||||
#else /* !__solaris__, i.e. Linux, AIX,.. */
|
||||
static const char *system_dir = "/usr/java";
|
||||
static const char *user_dir = "/java";
|
||||
#endif
|
||||
|
||||
#include <dlfcn.h>
|
||||
#ifdef __linux__
|
||||
#include <pthread.h>
|
||||
#else
|
||||
#ifdef __solaris__
|
||||
#include <thread.h>
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
#define JVM_DLL "libjvm.so"
|
||||
#define JAVA_DLL "libjava.so"
|
||||
#define LD_LIBRARY_PATH "LD_LIBRARY_PATH"
|
||||
|
||||
#endif /* JAVA_MD_SOLINUX_H */
|
||||
|
419
jdk/src/solaris/classes/java/lang/UNIXProcess.java.aix
Normal file
419
jdk/src/solaris/classes/java/lang/UNIXProcess.java.aix
Normal file
@ -0,0 +1,419 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 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 java.lang;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.security.AccessController;
|
||||
import static java.security.AccessController.doPrivileged;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
|
||||
/**
|
||||
* java.lang.Process subclass in the UNIX environment.
|
||||
*
|
||||
* @author Mario Wolczko and Ross Knippel.
|
||||
* @author Konstantin Kladko (ported to Linux)
|
||||
* @author Martin Buchholz
|
||||
* @author Volker Simonis (ported to AIX)
|
||||
*/
|
||||
final class UNIXProcess extends Process {
|
||||
private static final sun.misc.JavaIOFileDescriptorAccess fdAccess
|
||||
= sun.misc.SharedSecrets.getJavaIOFileDescriptorAccess();
|
||||
|
||||
private final int pid;
|
||||
private int exitcode;
|
||||
private boolean hasExited;
|
||||
|
||||
private /* final */ OutputStream stdin;
|
||||
private /* final */ InputStream stdout;
|
||||
private /* final */ InputStream stderr;
|
||||
|
||||
private static enum LaunchMechanism {
|
||||
FORK(1),
|
||||
POSIX_SPAWN(2);
|
||||
|
||||
private int value;
|
||||
LaunchMechanism(int x) {value = x;}
|
||||
};
|
||||
|
||||
/* On AIX, the default is to spawn */
|
||||
private static final LaunchMechanism launchMechanism;
|
||||
private static byte[] helperpath;
|
||||
|
||||
private static byte[] toCString(String s) {
|
||||
if (s == null)
|
||||
return null;
|
||||
byte[] bytes = s.getBytes();
|
||||
byte[] result = new byte[bytes.length + 1];
|
||||
System.arraycopy(bytes, 0,
|
||||
result, 0,
|
||||
bytes.length);
|
||||
result[result.length-1] = (byte)0;
|
||||
return result;
|
||||
}
|
||||
|
||||
static {
|
||||
launchMechanism = AccessController.doPrivileged(
|
||||
new PrivilegedAction<LaunchMechanism>()
|
||||
{
|
||||
public LaunchMechanism run() {
|
||||
String javahome = System.getProperty("java.home");
|
||||
String osArch = System.getProperty("os.arch");
|
||||
|
||||
helperpath = toCString(javahome + "/lib/" + osArch + "/jspawnhelper");
|
||||
String s = System.getProperty(
|
||||
"jdk.lang.Process.launchMechanism", "posix_spawn");
|
||||
|
||||
try {
|
||||
return LaunchMechanism.valueOf(s.toUpperCase());
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new Error(s + " is not a supported " +
|
||||
"process launch mechanism on this platform.");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* this is for the reaping thread */
|
||||
private native int waitForProcessExit(int pid);
|
||||
|
||||
/**
|
||||
* Create a process. Depending on the mode flag, this is done by
|
||||
* one of the following mechanisms.
|
||||
* - fork(2) and exec(2)
|
||||
* - clone(2) and exec(2)
|
||||
* - vfork(2) and exec(2)
|
||||
*
|
||||
* @param fds an array of three file descriptors.
|
||||
* Indexes 0, 1, and 2 correspond to standard input,
|
||||
* standard output and standard error, respectively. On
|
||||
* input, a value of -1 means to create a pipe to connect
|
||||
* child and parent processes. On output, a value which
|
||||
* is not -1 is the parent pipe fd corresponding to the
|
||||
* pipe which has been created. An element of this array
|
||||
* is -1 on input if and only if it is <em>not</em> -1 on
|
||||
* output.
|
||||
* @return the pid of the subprocess
|
||||
*/
|
||||
private native int forkAndExec(int mode, byte[] helperpath,
|
||||
byte[] prog,
|
||||
byte[] argBlock, int argc,
|
||||
byte[] envBlock, int envc,
|
||||
byte[] dir,
|
||||
int[] fds,
|
||||
boolean redirectErrorStream)
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* The thread factory used to create "process reaper" daemon threads.
|
||||
*/
|
||||
private static class ProcessReaperThreadFactory implements ThreadFactory {
|
||||
private final static ThreadGroup group = getRootThreadGroup();
|
||||
|
||||
private static ThreadGroup getRootThreadGroup() {
|
||||
return doPrivileged(new PrivilegedAction<ThreadGroup> () {
|
||||
public ThreadGroup run() {
|
||||
ThreadGroup root = Thread.currentThread().getThreadGroup();
|
||||
while (root.getParent() != null)
|
||||
root = root.getParent();
|
||||
return root;
|
||||
}});
|
||||
}
|
||||
|
||||
public Thread newThread(Runnable grimReaper) {
|
||||
// Our thread stack requirement is quite modest.
|
||||
Thread t = new Thread(group, grimReaper, "process reaper", 32768);
|
||||
t.setDaemon(true);
|
||||
// A small attempt (probably futile) to avoid priority inversion
|
||||
t.setPriority(Thread.MAX_PRIORITY);
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The thread pool of "process reaper" daemon threads.
|
||||
*/
|
||||
private static final Executor processReaperExecutor =
|
||||
doPrivileged(new PrivilegedAction<Executor>() {
|
||||
public Executor run() {
|
||||
return Executors.newCachedThreadPool
|
||||
(new ProcessReaperThreadFactory());
|
||||
}});
|
||||
|
||||
UNIXProcess(final byte[] prog,
|
||||
final byte[] argBlock, final int argc,
|
||||
final byte[] envBlock, final int envc,
|
||||
final byte[] dir,
|
||||
final int[] fds,
|
||||
final boolean redirectErrorStream)
|
||||
throws IOException {
|
||||
|
||||
pid = forkAndExec(launchMechanism.value,
|
||||
helperpath,
|
||||
prog,
|
||||
argBlock, argc,
|
||||
envBlock, envc,
|
||||
dir,
|
||||
fds,
|
||||
redirectErrorStream);
|
||||
|
||||
try {
|
||||
doPrivileged(new PrivilegedExceptionAction<Void>() {
|
||||
public Void run() throws IOException {
|
||||
initStreams(fds);
|
||||
return null;
|
||||
}});
|
||||
} catch (PrivilegedActionException ex) {
|
||||
throw (IOException) ex.getException();
|
||||
}
|
||||
}
|
||||
|
||||
static FileDescriptor newFileDescriptor(int fd) {
|
||||
FileDescriptor fileDescriptor = new FileDescriptor();
|
||||
fdAccess.set(fileDescriptor, fd);
|
||||
return fileDescriptor;
|
||||
}
|
||||
|
||||
void initStreams(int[] fds) throws IOException {
|
||||
stdin = (fds[0] == -1) ?
|
||||
ProcessBuilder.NullOutputStream.INSTANCE :
|
||||
new ProcessPipeOutputStream(fds[0]);
|
||||
|
||||
stdout = (fds[1] == -1) ?
|
||||
ProcessBuilder.NullInputStream.INSTANCE :
|
||||
new ProcessPipeInputStream(fds[1]);
|
||||
|
||||
stderr = (fds[2] == -1) ?
|
||||
ProcessBuilder.NullInputStream.INSTANCE :
|
||||
new ProcessPipeInputStream(fds[2]);
|
||||
|
||||
processReaperExecutor.execute(new Runnable() {
|
||||
public void run() {
|
||||
int exitcode = waitForProcessExit(pid);
|
||||
UNIXProcess.this.processExited(exitcode);
|
||||
}});
|
||||
}
|
||||
|
||||
void processExited(int exitcode) {
|
||||
synchronized (this) {
|
||||
this.exitcode = exitcode;
|
||||
hasExited = true;
|
||||
notifyAll();
|
||||
}
|
||||
|
||||
if (stdout instanceof ProcessPipeInputStream)
|
||||
((ProcessPipeInputStream) stdout).processExited();
|
||||
|
||||
if (stderr instanceof ProcessPipeInputStream)
|
||||
((ProcessPipeInputStream) stderr).processExited();
|
||||
|
||||
if (stdin instanceof ProcessPipeOutputStream)
|
||||
((ProcessPipeOutputStream) stdin).processExited();
|
||||
}
|
||||
|
||||
public OutputStream getOutputStream() {
|
||||
return stdin;
|
||||
}
|
||||
|
||||
public InputStream getInputStream() {
|
||||
return stdout;
|
||||
}
|
||||
|
||||
public InputStream getErrorStream() {
|
||||
return stderr;
|
||||
}
|
||||
|
||||
public synchronized int waitFor() throws InterruptedException {
|
||||
while (!hasExited) {
|
||||
wait();
|
||||
}
|
||||
return exitcode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean waitFor(long timeout, TimeUnit unit)
|
||||
throws InterruptedException
|
||||
{
|
||||
if (hasExited) return true;
|
||||
if (timeout <= 0) return false;
|
||||
|
||||
long timeoutAsNanos = unit.toNanos(timeout);
|
||||
long startTime = System.nanoTime();
|
||||
long rem = timeoutAsNanos;
|
||||
|
||||
while (!hasExited && (rem > 0)) {
|
||||
wait(Math.max(TimeUnit.NANOSECONDS.toMillis(rem), 1));
|
||||
rem = timeoutAsNanos - (System.nanoTime() - startTime);
|
||||
}
|
||||
return hasExited;
|
||||
}
|
||||
|
||||
public synchronized int exitValue() {
|
||||
if (!hasExited) {
|
||||
throw new IllegalThreadStateException("process hasn't exited");
|
||||
}
|
||||
return exitcode;
|
||||
}
|
||||
|
||||
private static native void destroyProcess(int pid, boolean force);
|
||||
private void destroy(boolean force) {
|
||||
// There is a risk that pid will be recycled, causing us to
|
||||
// kill the wrong process! So we only terminate processes
|
||||
// that appear to still be running. Even with this check,
|
||||
// there is an unavoidable race condition here, but the window
|
||||
// is very small, and OSes try hard to not recycle pids too
|
||||
// soon, so this is quite safe.
|
||||
synchronized (this) {
|
||||
if (!hasExited)
|
||||
destroyProcess(pid, force);
|
||||
}
|
||||
try { stdin.close(); } catch (IOException ignored) {}
|
||||
try { stdout.close(); } catch (IOException ignored) {}
|
||||
try { stderr.close(); } catch (IOException ignored) {}
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
destroy(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Process destroyForcibly() {
|
||||
destroy(true);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isAlive() {
|
||||
return !hasExited;
|
||||
}
|
||||
|
||||
private static native void init();
|
||||
|
||||
static {
|
||||
init();
|
||||
}
|
||||
|
||||
/**
|
||||
* A buffered input stream for a subprocess pipe file descriptor
|
||||
* that allows the underlying file descriptor to be reclaimed when
|
||||
* the process exits, via the processExited hook.
|
||||
*
|
||||
* This is tricky because we do not want the user-level InputStream to be
|
||||
* closed until the user invokes close(), and we need to continue to be
|
||||
* able to read any buffered data lingering in the OS pipe buffer.
|
||||
*/
|
||||
static class ProcessPipeInputStream extends BufferedInputStream {
|
||||
private final Object closeLock = new Object();
|
||||
|
||||
ProcessPipeInputStream(int fd) {
|
||||
super(new FileInputStream(newFileDescriptor(fd)));
|
||||
}
|
||||
|
||||
private InputStream drainInputStream(InputStream in)
|
||||
throws IOException {
|
||||
int n = 0;
|
||||
int j;
|
||||
byte[] a = null;
|
||||
synchronized (closeLock) {
|
||||
if (buf == null) // asynchronous close()?
|
||||
return null; // discard
|
||||
j = in.available();
|
||||
}
|
||||
while (j > 0) {
|
||||
a = (a == null) ? new byte[j] : Arrays.copyOf(a, n + j);
|
||||
synchronized (closeLock) {
|
||||
if (buf == null) // asynchronous close()?
|
||||
return null; // discard
|
||||
n += in.read(a, n, j);
|
||||
j = in.available();
|
||||
}
|
||||
}
|
||||
return (a == null) ?
|
||||
ProcessBuilder.NullInputStream.INSTANCE :
|
||||
new ByteArrayInputStream(n == a.length ? a : Arrays.copyOf(a, n));
|
||||
}
|
||||
|
||||
/** Called by the process reaper thread when the process exits. */
|
||||
synchronized void processExited() {
|
||||
try {
|
||||
InputStream in = this.in;
|
||||
if (in != null) {
|
||||
InputStream stragglers = drainInputStream(in);
|
||||
in.close();
|
||||
this.in = stragglers;
|
||||
}
|
||||
} catch (IOException ignored) { }
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
// BufferedInputStream#close() is not synchronized unlike most other methods.
|
||||
// Synchronizing helps avoid racing with drainInputStream().
|
||||
synchronized (closeLock) {
|
||||
super.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A buffered output stream for a subprocess pipe file descriptor
|
||||
* that allows the underlying file descriptor to be reclaimed when
|
||||
* the process exits, via the processExited hook.
|
||||
*/
|
||||
static class ProcessPipeOutputStream extends BufferedOutputStream {
|
||||
ProcessPipeOutputStream(int fd) {
|
||||
super(new FileOutputStream(newFileDescriptor(fd)));
|
||||
}
|
||||
|
||||
/** Called by the process reaper thread when the process exits. */
|
||||
synchronized void processExited() {
|
||||
OutputStream out = this.out;
|
||||
if (out != null) {
|
||||
try {
|
||||
out.close();
|
||||
} catch (IOException ignored) {
|
||||
// We know of no reason to get an IOException, but if
|
||||
// we do, there's nothing else to do but carry on.
|
||||
}
|
||||
this.out = ProcessBuilder.NullOutputStream.INSTANCE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -68,6 +68,8 @@ public class DefaultAsynchronousChannelProvider {
|
||||
return createProvider("sun.nio.ch.LinuxAsynchronousChannelProvider");
|
||||
if (osname.contains("OS X"))
|
||||
return createProvider("sun.nio.ch.BsdAsynchronousChannelProvider");
|
||||
if (osname.equals("AIX"))
|
||||
return createProvider("sun.nio.ch.AixAsynchronousChannelProvider");
|
||||
throw new InternalError("platform not recognized");
|
||||
}
|
||||
}
|
||||
|
@ -76,12 +76,22 @@ abstract class Port extends AsynchronousChannelGroupImpl {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback method for implementations that need special handling when fd is
|
||||
* removed (currently only needed in the AIX-Port - see AixPollPort.java).
|
||||
*/
|
||||
protected void preUnregister(int fd) {
|
||||
// Do nothing by default.
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister channel identified by its file descriptor
|
||||
*/
|
||||
final void unregister(int fd) {
|
||||
boolean checkForShutdown = false;
|
||||
|
||||
preUnregister(fd);
|
||||
|
||||
fdToChannelLock.writeLock().lock();
|
||||
try {
|
||||
fdToChannel.remove(Integer.valueOf(fd));
|
||||
|
@ -63,6 +63,8 @@ public class DefaultFileSystemProvider {
|
||||
return createProvider("sun.nio.fs.LinuxFileSystemProvider");
|
||||
if (osname.contains("OS X"))
|
||||
return createProvider("sun.nio.fs.MacOSXFileSystemProvider");
|
||||
if (osname.equals("AIX"))
|
||||
return createProvider("sun.nio.fs.AixFileSystemProvider");
|
||||
throw new AssertionError("Platform not recognized");
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -42,7 +42,7 @@
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#if !defined(LINUX) && !defined(_ALLBSD_SOURCE)
|
||||
#if !defined(LINUX) && !defined(_ALLBSD_SOURCE) && !defined(AIX)
|
||||
#include <procfs.h>
|
||||
#endif
|
||||
|
||||
@ -65,6 +65,10 @@
|
||||
#include "jvm_md.h"
|
||||
#include "hprof.h"
|
||||
|
||||
#ifdef AIX
|
||||
#include "porting_aix.h" /* For the 'dladdr' function. */
|
||||
#endif
|
||||
|
||||
int
|
||||
md_getpid(void)
|
||||
{
|
||||
@ -86,7 +90,7 @@ md_sleep(unsigned seconds)
|
||||
void
|
||||
md_init(void)
|
||||
{
|
||||
#if defined(LINUX) || defined(_ALLBSD_SOURCE)
|
||||
#if defined(LINUX) || defined(_ALLBSD_SOURCE) || defined(AIX)
|
||||
/* No Hi-Res timer option? */
|
||||
#else
|
||||
if ( gdata->micro_state_accounting ) {
|
||||
@ -253,7 +257,7 @@ md_timeofday(void)
|
||||
jlong
|
||||
md_get_microsecs(void)
|
||||
{
|
||||
#if defined(LINUX) || defined(_ALLBSD_SOURCE)
|
||||
#if defined(LINUX) || defined(_ALLBSD_SOURCE) || defined(AIX)
|
||||
return (jlong)(md_timeofday() * (jlong)1000); /* Milli to micro */
|
||||
#else
|
||||
return (jlong)(gethrtime()/(hrtime_t)1000); /* Nano seconds to micro seconds */
|
||||
@ -271,7 +275,7 @@ md_get_timemillis(void)
|
||||
jlong
|
||||
md_get_thread_cpu_timemillis(void)
|
||||
{
|
||||
#if defined(LINUX) || defined(_ALLBSD_SOURCE)
|
||||
#if defined(LINUX) || defined(_ALLBSD_SOURCE) || defined(AIX)
|
||||
return md_timeofday();
|
||||
#else
|
||||
return (jlong)(gethrvtime()/1000); /* Nano seconds to milli seconds */
|
||||
@ -286,7 +290,7 @@ md_get_prelude_path(char *path, int path_len, char *filename)
|
||||
Dl_info dlinfo;
|
||||
|
||||
libdir[0] = 0;
|
||||
#if defined(LINUX) || defined(_ALLBSD_SOURCE)
|
||||
#if defined(LINUX) || defined(_ALLBSD_SOURCE) || defined(AIX)
|
||||
addr = (void*)&Agent_OnLoad;
|
||||
#else
|
||||
/* Just using &Agent_OnLoad will get the first external symbol with
|
||||
@ -457,3 +461,5 @@ md_find_library_entry(void *handle, const char *name)
|
||||
sym = dlsym(handle, name);
|
||||
return sym;
|
||||
}
|
||||
|
||||
|
||||
|
@ -39,6 +39,10 @@
|
||||
#include <math.h>
|
||||
#define ISNANF(f) isnanf(f)
|
||||
#define ISNAND(d) isnan(d)
|
||||
#elif defined(_AIX)
|
||||
#include <math.h>
|
||||
#define ISNANF(f) _isnanf(f)
|
||||
#define ISNAND(d) _isnan(d)
|
||||
#else
|
||||
#error "missing platform-specific definition here"
|
||||
#endif
|
||||
|
@ -35,7 +35,7 @@
|
||||
#include <sys/filio.h>
|
||||
#endif
|
||||
|
||||
#if defined(__linux__) || defined(_ALLBSD_SOURCE)
|
||||
#if defined(__linux__) || defined(_ALLBSD_SOURCE) || defined(_AIX)
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1995, 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
|
||||
@ -44,7 +44,7 @@
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(__solaris__) || defined(_ALLBSD_SOURCE)
|
||||
#if defined(__solaris__) || defined(_ALLBSD_SOURCE) || defined(_AIX)
|
||||
#include <spawn.h>
|
||||
#endif
|
||||
|
||||
@ -455,7 +455,7 @@ forkChild(ChildStuff *c) {
|
||||
return resultPid;
|
||||
}
|
||||
|
||||
#if defined(__solaris__) || defined(_ALLBSD_SOURCE)
|
||||
#if defined(__solaris__) || defined(_ALLBSD_SOURCE) || defined(_AIX)
|
||||
static pid_t
|
||||
spawnChild(JNIEnv *env, jobject process, ChildStuff *c, const char *helperpath) {
|
||||
pid_t resultPid;
|
||||
@ -551,7 +551,7 @@ startChild(JNIEnv *env, jobject process, ChildStuff *c, const char *helperpath)
|
||||
return vforkChild(c);
|
||||
case MODE_FORK:
|
||||
return forkChild(c);
|
||||
#if defined(__solaris__) || defined(_ALLBSD_SOURCE)
|
||||
#if defined(__solaris__) || defined(_ALLBSD_SOURCE) || defined(_AIX)
|
||||
case MODE_POSIX_SPAWN:
|
||||
return spawnChild(env, process, c, helperpath);
|
||||
#endif
|
||||
|
@ -66,6 +66,9 @@ isAsciiDigit(char c)
|
||||
#define FD_DIR "/dev/fd"
|
||||
#define dirent64 dirent
|
||||
#define readdir64 readdir
|
||||
#elif defined(_AIX)
|
||||
/* AIX does not understand '/proc/self' - it requires the real process ID */
|
||||
#define FD_DIR aix_fd_dir
|
||||
#else
|
||||
#define FD_DIR "/proc/self/fd"
|
||||
#endif
|
||||
@ -87,6 +90,12 @@ closeDescriptors(void)
|
||||
close(from_fd); /* for possible use by opendir() */
|
||||
close(from_fd + 1); /* another one for good luck */
|
||||
|
||||
#if defined(_AIX)
|
||||
/* AIX does not understand '/proc/self' - it requires the real process ID */
|
||||
char aix_fd_dir[32]; /* the pid has at most 19 digits */
|
||||
snprintf(aix_fd_dir, 32, "/proc/%d/fd", getpid());
|
||||
#endif
|
||||
|
||||
if ((dp = opendir(FD_DIR)) == NULL)
|
||||
return 0;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* 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
|
||||
@ -52,6 +52,13 @@
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#if defined(_AIX)
|
||||
#include <sys/ioctl.h>
|
||||
#include <netinet/in6_var.h>
|
||||
#include <sys/ndd_var.h>
|
||||
#include <sys/kinfo.h>
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
#define _PATH_PROCNET_IFINET6 "/proc/net/if_inet6"
|
||||
#endif
|
||||
@ -1041,8 +1048,8 @@ static int openSocket(JNIEnv *env, int proto){
|
||||
}
|
||||
|
||||
|
||||
/** Linux **/
|
||||
#ifdef __linux__
|
||||
/** Linux, AIX **/
|
||||
#if defined(__linux__) || defined(_AIX)
|
||||
/* Open socket for further ioct calls, try v4 socket first and
|
||||
* if it falls return v6 socket
|
||||
*/
|
||||
@ -1080,11 +1087,13 @@ static int openSocketWithFallback(JNIEnv *env, const char *ifname){
|
||||
static netif *enumIPv4Interfaces(JNIEnv *env, int sock, netif *ifs) {
|
||||
struct ifconf ifc;
|
||||
struct ifreq *ifreqP;
|
||||
char *buf;
|
||||
char *buf = NULL;
|
||||
int numifs;
|
||||
unsigned i;
|
||||
int siocgifconfRequest = SIOCGIFCONF;
|
||||
|
||||
|
||||
#if defined(__linux__)
|
||||
/* need to do a dummy SIOCGIFCONF to determine the buffer size.
|
||||
* SIOCGIFCOUNT doesn't work
|
||||
*/
|
||||
@ -1093,11 +1102,21 @@ static netif *enumIPv4Interfaces(JNIEnv *env, int sock, netif *ifs) {
|
||||
NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "ioctl SIOCGIFCONF failed");
|
||||
return ifs;
|
||||
}
|
||||
#elif defined(_AIX)
|
||||
ifc.ifc_buf = NULL;
|
||||
if (ioctl(sock, SIOCGSIZIFCONF, &(ifc.ifc_len)) < 0) {
|
||||
NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "ioctl SIOCGSIZIFCONF failed");
|
||||
return ifs;
|
||||
}
|
||||
#endif /* __linux__ */
|
||||
|
||||
CHECKED_MALLOC3(buf,char *, ifc.ifc_len);
|
||||
|
||||
ifc.ifc_buf = buf;
|
||||
if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) {
|
||||
#if defined(_AIX)
|
||||
siocgifconfRequest = CSIOCGIFCONF;
|
||||
#endif
|
||||
if (ioctl(sock, siocgifconfRequest, (char *)&ifc) < 0) {
|
||||
NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "ioctl SIOCGIFCONF failed");
|
||||
(void) free(buf);
|
||||
return ifs;
|
||||
@ -1108,6 +1127,9 @@ static netif *enumIPv4Interfaces(JNIEnv *env, int sock, netif *ifs) {
|
||||
*/
|
||||
ifreqP = ifc.ifc_req;
|
||||
for (i=0; i<ifc.ifc_len/sizeof (struct ifreq); i++, ifreqP++) {
|
||||
#if defined(_AIX)
|
||||
if (ifreqP->ifr_addr.sa_family != AF_INET) continue;
|
||||
#endif
|
||||
/*
|
||||
* Add to the list
|
||||
*/
|
||||
@ -1135,7 +1157,7 @@ static netif *enumIPv4Interfaces(JNIEnv *env, int sock, netif *ifs) {
|
||||
* Enumerates and returns all IPv6 interfaces on Linux
|
||||
*/
|
||||
|
||||
#ifdef AF_INET6
|
||||
#if defined(AF_INET6) && defined(__linux__)
|
||||
static netif *enumIPv6Interfaces(JNIEnv *env, int sock, netif *ifs) {
|
||||
FILE *f;
|
||||
char addr6[40], devname[21];
|
||||
@ -1179,11 +1201,103 @@ static netif *enumIPv6Interfaces(JNIEnv *env, int sock, netif *ifs) {
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Enumerates and returns all IPv6 interfaces on AIX
|
||||
*/
|
||||
|
||||
#if defined(AF_INET6) && defined(_AIX)
|
||||
static netif *enumIPv6Interfaces(JNIEnv *env, int sock, netif *ifs) {
|
||||
struct ifconf ifc;
|
||||
struct ifreq *ifreqP;
|
||||
char *buf;
|
||||
int numifs;
|
||||
unsigned i;
|
||||
unsigned bufsize;
|
||||
char *cp, *cplimit;
|
||||
|
||||
/* use SIOCGSIZIFCONF to get size for SIOCGIFCONF */
|
||||
|
||||
ifc.ifc_buf = NULL;
|
||||
if (ioctl(sock, SIOCGSIZIFCONF, &(ifc.ifc_len)) < 0) {
|
||||
NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException",
|
||||
"ioctl SIOCGSIZIFCONF failed");
|
||||
return ifs;
|
||||
}
|
||||
bufsize = ifc.ifc_len;
|
||||
|
||||
buf = (char *)malloc(bufsize);
|
||||
if (!buf) {
|
||||
JNU_ThrowOutOfMemoryError(env, "Network interface native buffer allocation failed");
|
||||
return ifs;
|
||||
}
|
||||
ifc.ifc_len = bufsize;
|
||||
ifc.ifc_buf = buf;
|
||||
if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) {
|
||||
NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException",
|
||||
"ioctl CSIOCGIFCONF failed");
|
||||
free(buf);
|
||||
return ifs;
|
||||
}
|
||||
|
||||
/*
|
||||
* Iterate through each interface
|
||||
*/
|
||||
ifreqP = ifc.ifc_req;
|
||||
cp = (char *)ifc.ifc_req;
|
||||
cplimit = cp + ifc.ifc_len;
|
||||
|
||||
for ( ; cp < cplimit; cp += (sizeof(ifreqP->ifr_name) + MAX((ifreqP->ifr_addr).sa_len, sizeof(ifreqP->ifr_addr)))) {
|
||||
ifreqP = (struct ifreq *)cp;
|
||||
struct ifreq if2;
|
||||
|
||||
memset((char *)&if2, 0, sizeof(if2));
|
||||
strcpy(if2.ifr_name, ifreqP->ifr_name);
|
||||
|
||||
/*
|
||||
* Skip interface that aren't UP
|
||||
*/
|
||||
if (ioctl(sock, SIOCGIFFLAGS, (char *)&if2) >= 0) {
|
||||
if (!(if2.ifr_flags & IFF_UP)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (ifreqP->ifr_addr.sa_family != AF_INET6)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Add to the list
|
||||
*/
|
||||
ifs = addif(env, sock, ifreqP->ifr_name, ifs,
|
||||
(struct sockaddr *)&(ifreqP->ifr_addr),
|
||||
AF_INET6, 0);
|
||||
|
||||
/*
|
||||
* If an exception occurred then free the list
|
||||
*/
|
||||
if ((*env)->ExceptionOccurred(env)) {
|
||||
free(buf);
|
||||
freeif(ifs);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Free socket and buffer
|
||||
*/
|
||||
free(buf);
|
||||
return ifs;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static int getIndex(int sock, const char *name){
|
||||
/*
|
||||
* Try to get the interface index
|
||||
* (Not supported on Solaris 2.6 or 7)
|
||||
*/
|
||||
#if defined(_AIX)
|
||||
return if_nametoindex(name);
|
||||
#else
|
||||
struct ifreq if2;
|
||||
strcpy(if2.ifr_name, name);
|
||||
|
||||
@ -1192,6 +1306,7 @@ static int getIndex(int sock, const char *name){
|
||||
}
|
||||
|
||||
return if2.ifr_ifindex;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1258,6 +1373,46 @@ static short getSubnet(JNIEnv *env, int sock, const char *ifname) {
|
||||
* MAC address. Returns -1 if there is no hardware address on that interface.
|
||||
*/
|
||||
static int getMacAddress(JNIEnv *env, int sock, const char* ifname, const struct in_addr* addr, unsigned char *buf) {
|
||||
#if defined (_AIX)
|
||||
int size;
|
||||
struct kinfo_ndd *nddp;
|
||||
void *end;
|
||||
|
||||
size = getkerninfo(KINFO_NDD, 0, 0, 0);
|
||||
if (size == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (size < 0) {
|
||||
perror("getkerninfo 1");
|
||||
return -1;
|
||||
}
|
||||
|
||||
nddp = (struct kinfo_ndd *)malloc(size);
|
||||
|
||||
if (!nddp) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (getkerninfo(KINFO_NDD, nddp, &size, 0) < 0) {
|
||||
perror("getkerninfo 2");
|
||||
return -1;
|
||||
}
|
||||
|
||||
end = (void *)nddp + size;
|
||||
while ((void *)nddp < end) {
|
||||
if (!strcmp(nddp->ndd_alias, ifname) ||
|
||||
!strcmp(nddp->ndd_name, ifname)) {
|
||||
bcopy(nddp->ndd_addr, buf, 6);
|
||||
return 6;
|
||||
} else {
|
||||
nddp++;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
|
||||
#elif defined(__linux__)
|
||||
static struct ifreq ifr;
|
||||
int i;
|
||||
|
||||
@ -1279,6 +1434,7 @@ static int getMacAddress(JNIEnv *env, int sock, const char* ifname, const struct
|
||||
}
|
||||
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int getMTU(JNIEnv *env, int sock, const char *ifname) {
|
||||
|
@ -963,7 +963,7 @@ Java_java_net_PlainSocketImpl_socketSetOption(JNIEnv *env, jobject this,
|
||||
}
|
||||
|
||||
if (NET_SetSockOpt(fd, level, optname, (const void *)&optval, optlen) < 0) {
|
||||
#ifdef __solaris__
|
||||
#if defined(__solaris__) || defined(_AIX)
|
||||
if (errno == EINVAL) {
|
||||
// On Solaris setsockopt will set errno to EINVAL if the socket
|
||||
// is closed. The default error message is then confusing
|
||||
|
@ -738,14 +738,23 @@ static int getLocalScopeID (char *addr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void initLocalAddrTable () {
|
||||
void platformInit () {
|
||||
initLoopbackRoutes();
|
||||
initLocalIfs();
|
||||
}
|
||||
|
||||
#elif defined(_AIX)
|
||||
|
||||
/* Initialize stubs for blocking I/O workarounds (see src/solaris/native/java/net/linux_close.c) */
|
||||
extern void aix_close_init();
|
||||
|
||||
void platformInit () {
|
||||
aix_close_init();
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void initLocalAddrTable () {}
|
||||
void platformInit () {}
|
||||
|
||||
#endif
|
||||
|
||||
@ -987,7 +996,11 @@ NET_MapSocketOption(jint cmd, int *level, int *optname) {
|
||||
{ java_net_SocketOptions_SO_SNDBUF, SOL_SOCKET, SO_SNDBUF },
|
||||
{ java_net_SocketOptions_SO_RCVBUF, SOL_SOCKET, SO_RCVBUF },
|
||||
{ java_net_SocketOptions_SO_KEEPALIVE, SOL_SOCKET, SO_KEEPALIVE },
|
||||
#if defined(_AIX)
|
||||
{ java_net_SocketOptions_SO_REUSEADDR, SOL_SOCKET, SO_REUSEPORT },
|
||||
#else
|
||||
{ java_net_SocketOptions_SO_REUSEADDR, SOL_SOCKET, SO_REUSEADDR },
|
||||
#endif
|
||||
{ java_net_SocketOptions_SO_BROADCAST, SOL_SOCKET, SO_BROADCAST },
|
||||
{ java_net_SocketOptions_IP_TOS, IPPROTO_IP, IP_TOS },
|
||||
{ java_net_SocketOptions_IP_MULTICAST_IF, IPPROTO_IP, IP_MULTICAST_IF },
|
||||
@ -1387,6 +1400,29 @@ NET_SetSockOpt(int fd, int level, int opt, const void *arg,
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _AIX
|
||||
if (level == SOL_SOCKET) {
|
||||
if (opt == SO_SNDBUF || opt == SO_RCVBUF) {
|
||||
/*
|
||||
* Just try to set the requested size. If it fails we will leave the
|
||||
* socket option as is. Setting the buffer size means only a hint in
|
||||
* the jse2/java software layer, see javadoc. In the previous
|
||||
* solution the buffer has always been truncated to a length of
|
||||
* 0x100000 Byte, even if the technical limit has not been reached.
|
||||
* This kind of absolute truncation was unexpected in the jck tests.
|
||||
*/
|
||||
int ret = setsockopt(fd, level, opt, arg, len);
|
||||
if ((ret == 0) || (ret == -1 && errno == ENOBUFS)) {
|
||||
// Accept failure because of insufficient buffer memory resources.
|
||||
return 0;
|
||||
} else {
|
||||
// Deliver all other kinds of errors.
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* On Linux the receive buffer is used for both socket
|
||||
* structures and the the packet payload. The implication
|
||||
|
@ -37,7 +37,17 @@
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(__linux__) || defined(MACOSX)
|
||||
/*
|
||||
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.
|
||||
...
|
||||
*/
|
||||
#if defined(__linux__) || defined(MACOSX) || defined (_AIX)
|
||||
extern int NET_Timeout(int s, long timeout);
|
||||
extern int NET_Read(int s, void* buf, size_t len);
|
||||
extern int NET_RecvFrom(int s, void *buf, int len, unsigned int flags,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 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
|
||||
@ -123,7 +123,7 @@ findZoneinfoFile(char *buf, size_t size, const char *dir)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if defined(__linux__) || defined(MACOSX) || (defined(__solaris__) \
|
||||
#if defined(_AIX) || defined(__linux__) || defined(MACOSX) || (defined(__solaris__) \
|
||||
&& (defined(_POSIX_PTHREAD_SEMANTICS) || defined(_LP64)))
|
||||
while (readdir_r(dirp, entry, &dp) == 0 && dp != NULL) {
|
||||
#else
|
||||
@ -615,6 +615,14 @@ getSolarisDefaultZoneID() {
|
||||
#endif /*__solaris__*/
|
||||
#endif /*__linux__*/
|
||||
|
||||
#ifdef _AIX
|
||||
static char *
|
||||
getPlatformTimeZoneID()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* findJavaTZ_md() maps platform time zone ID to Java time zone ID
|
||||
* using <java_home>/lib/tzmappings. If the TZ value is not found, it
|
||||
@ -635,7 +643,7 @@ findJavaTZ_md(const char *java_home_dir, const char *country)
|
||||
#if defined(__linux__) || defined(_ALLBSD_SOURCE)
|
||||
if (tz == NULL) {
|
||||
#else
|
||||
#ifdef __solaris__
|
||||
#if defined (__solaris__) || defined(_AIX)
|
||||
if (tz == NULL || *tz == '\0') {
|
||||
#endif
|
||||
#endif
|
||||
|
@ -37,6 +37,10 @@
|
||||
|
||||
#include "awt_Plugin.h"
|
||||
|
||||
#ifdef AIX
|
||||
#include "porting_aix.h" /* For the 'dladdr' function. */
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
#define VERBOSE_AWT_DEBUG
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* 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
|
||||
@ -64,7 +64,7 @@ extern Display *awt_display;
|
||||
|
||||
#define MAXFDIRS 512 /* Max number of directories that contain fonts */
|
||||
|
||||
#if !defined(__linux__)
|
||||
#if defined(__solaris__)
|
||||
/*
|
||||
* This can be set in the makefile to "/usr/X11" if so desired.
|
||||
*/
|
||||
@ -114,7 +114,7 @@ static char *fullSolarisFontPath[] = {
|
||||
NULL, /* terminates the list */
|
||||
};
|
||||
|
||||
#else /* __linux */
|
||||
#elif defined( __linux__)
|
||||
/* All the known interesting locations we have discovered on
|
||||
* various flavors of Linux
|
||||
*/
|
||||
@ -134,6 +134,12 @@ static char *fullLinuxFontPath[] = {
|
||||
"/usr/share/fonts/default/Type1", /* RH 9.0 */
|
||||
NULL, /* terminates the list */
|
||||
};
|
||||
#elif defined(_AIX)
|
||||
static char *fullAixFontPath[] = {
|
||||
"/usr/lpp/X11/lib/X11/fonts/Type1", /* from X11.fnt.iso_T1 */
|
||||
"/usr/lpp/X11/lib/X11/fonts/TrueType", /* from X11.fnt.ucs.ttf */
|
||||
NULL, /* terminates the list */
|
||||
};
|
||||
#endif
|
||||
|
||||
static char **getFontConfigLocations();
|
||||
@ -497,10 +503,11 @@ static char *getPlatformFontPathChars(JNIEnv *env, jboolean noType1) {
|
||||
|
||||
#if defined(__linux__)
|
||||
knowndirs = fullLinuxFontPath;
|
||||
#else /* IF SOLARIS */
|
||||
#elif defined(__solaris__)
|
||||
knowndirs = fullSolarisFontPath;
|
||||
#elif defined(_AIX)
|
||||
knowndirs = fullAixFontPath;
|
||||
#endif
|
||||
|
||||
/* REMIND: this code requires to be executed when the GraphicsEnvironment
|
||||
* is already initialised. That is always true, but if it were not so,
|
||||
* this code could throw an exception and the fontpath would fail to
|
||||
@ -592,6 +599,25 @@ static void* openFontConfig() {
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(_AIX)
|
||||
/* On AIX, fontconfig is not a standard package supported by IBM.
|
||||
* instead it has to be installed from the "AIX Toolbox for Linux Applications"
|
||||
* site http://www-03.ibm.com/systems/power/software/aix/linux/toolbox/alpha.html
|
||||
* and will be installed under /opt/freeware/lib/libfontconfig.a.
|
||||
* Notice that the archive contains the real 32- and 64-bit shared libraries.
|
||||
* We first try to load 'libfontconfig.so' from the default library path in the
|
||||
* case the user has installed a private version of the library and if that
|
||||
* doesn't succeed, we try the version from /opt/freeware/lib/libfontconfig.a
|
||||
*/
|
||||
libfontconfig = dlopen("libfontconfig.so", RTLD_LOCAL|RTLD_LAZY);
|
||||
if (libfontconfig == NULL) {
|
||||
libfontconfig = dlopen("/opt/freeware/lib/libfontconfig.a(libfontconfig.so.1)", RTLD_MEMBER|RTLD_LOCAL|RTLD_LAZY);
|
||||
if (libfontconfig == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* 64 bit sparc should pick up the right version from the lib path.
|
||||
* New features may be added to libfontconfig, this is expected to
|
||||
* be compatible with old features, but we may need to start
|
||||
@ -606,6 +632,7 @@ static void* openFontConfig() {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Version 1.0 of libfontconfig crashes if HOME isn't defined in
|
||||
* the environment. This should generally never happen, but we can't
|
||||
@ -1203,7 +1230,7 @@ Java_sun_font_FontConfigManager_getFontConfig
|
||||
*/
|
||||
if (fontformat != NULL
|
||||
&& (strcmp((char*)fontformat, "TrueType") != 0)
|
||||
#ifdef __linux__
|
||||
#if defined(__linux__) || defined(_AIX)
|
||||
&& (strcmp((char*)fontformat, "Type 1") != 0)
|
||||
#endif
|
||||
) {
|
||||
|
@ -56,8 +56,8 @@ typedef struct _X11RIPrivate {
|
||||
int x, y;
|
||||
} X11RIPrivate;
|
||||
|
||||
#define MAX(a,b) ((a) > (b) ? (a) : (b))
|
||||
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||
#define XSD_MAX(a,b) ((a) > (b) ? (a) : (b))
|
||||
#define XSD_MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||
|
||||
static LockFunc X11SD_Lock;
|
||||
static GetRasInfoFunc X11SD_GetRasInfo;
|
||||
@ -1090,10 +1090,10 @@ X11SD_ClipToRoot(SurfaceDataBounds *b, SurfaceDataBounds *bounds,
|
||||
x2 = x1 + DisplayWidth(awt_display, xsdo->configData->awt_visInfo.screen);
|
||||
y2 = y1 + DisplayHeight(awt_display, xsdo->configData->awt_visInfo.screen);
|
||||
|
||||
x1 = MAX(bounds->x1, x1);
|
||||
y1 = MAX(bounds->y1, y1);
|
||||
x2 = MIN(bounds->x2, x2);
|
||||
y2 = MIN(bounds->y2, y2);
|
||||
x1 = XSD_MAX(bounds->x1, x1);
|
||||
y1 = XSD_MAX(bounds->y1, y1);
|
||||
x2 = XSD_MIN(bounds->x2, x2);
|
||||
y2 = XSD_MIN(bounds->y2, y2);
|
||||
if ((x1 >= x2) || (y1 >= y2)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2010, 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
|
||||
@ -72,8 +72,8 @@ typedef struct _XRadialGradient {
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
#ifdef __solaris__
|
||||
/* Solaris 10 will not have these symbols at runtime */
|
||||
#if defined(__solaris__) || defined(_AIX)
|
||||
/* Solaris 10 and AIX will not have these symbols at runtime */
|
||||
|
||||
typedef Picture (*XRenderCreateLinearGradientFuncType)
|
||||
(Display *dpy,
|
||||
@ -147,7 +147,7 @@ static jboolean IsXRenderAvailable(jboolean verbose, jboolean ignoreLinuxVersion
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
#ifdef __solaris__
|
||||
#if defined(__solaris__) || defined(_AIX)
|
||||
xrenderlib = dlopen("libXrender.so",RTLD_GLOBAL|RTLD_LAZY);
|
||||
if (xrenderlib != NULL) {
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 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
|
||||
@ -41,7 +41,7 @@
|
||||
#include <sys/proc_info.h>
|
||||
#include <libproc.h>
|
||||
#endif
|
||||
#else
|
||||
#elif !defined(_AIX)
|
||||
#include <sys/swap.h>
|
||||
#endif
|
||||
#include <sys/resource.h>
|
||||
@ -57,9 +57,13 @@
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if defined(_AIX)
|
||||
#include <libperfstat.h>
|
||||
#endif
|
||||
|
||||
static jlong page_size = 0;
|
||||
|
||||
#if defined(_ALLBSD_SOURCE)
|
||||
#if defined(_ALLBSD_SOURCE) || defined(_AIX)
|
||||
#define MB (1024UL * 1024UL)
|
||||
#else
|
||||
|
||||
@ -326,6 +330,12 @@ Java_sun_management_OperatingSystemImpl_getFreePhysicalMemorySize
|
||||
*/
|
||||
// throw_internal_error(env, "unimplemented in FreeBSD")
|
||||
return (128 * MB);
|
||||
#elif defined(_AIX)
|
||||
perfstat_memory_total_t memory_info;
|
||||
if (-1 != perfstat_memory_total(NULL, &memory_info, sizeof(perfstat_memory_total_t), 1)) {
|
||||
return (jlong)(memory_info.real_free * 4L * 1024L);
|
||||
}
|
||||
return -1;
|
||||
#else // solaris / linux
|
||||
jlong num_avail_physical_pages = sysconf(_SC_AVPHYS_PAGES);
|
||||
return (num_avail_physical_pages * page_size);
|
||||
@ -349,6 +359,12 @@ Java_sun_management_OperatingSystemImpl_getTotalPhysicalMemorySize
|
||||
return -1;
|
||||
}
|
||||
return result;
|
||||
#elif defined(_AIX)
|
||||
perfstat_memory_total_t memory_info;
|
||||
if (-1 != perfstat_memory_total(NULL, &memory_info, sizeof(perfstat_memory_total_t), 1)) {
|
||||
return (jlong)(memory_info.real_total * 4L * 1024L);
|
||||
}
|
||||
return -1;
|
||||
#else // solaris / linux
|
||||
jlong num_physical_pages = sysconf(_SC_PHYS_PAGES);
|
||||
return (num_physical_pages * page_size);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* 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
|
||||
@ -40,6 +40,9 @@
|
||||
#include "nio.h"
|
||||
#include "sun_nio_ch_PollArrayWrapper.h"
|
||||
|
||||
#ifdef _AIX
|
||||
#include <sys/utsname.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* IP_MULTICAST_ALL supported since 2.6.31 but may not be available at
|
||||
@ -51,24 +54,46 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _ALLBSD_SOURCE
|
||||
#if defined(_ALLBSD_SOURCE) || defined(_AIX)
|
||||
|
||||
#ifndef IP_BLOCK_SOURCE
|
||||
|
||||
#if defined(_AIX)
|
||||
|
||||
#define IP_BLOCK_SOURCE 58 /* Block data from a given source to a given group */
|
||||
#define IP_UNBLOCK_SOURCE 59 /* Unblock data from a given source to a given group */
|
||||
#define IP_ADD_SOURCE_MEMBERSHIP 60 /* Join a source-specific group */
|
||||
#define IP_DROP_SOURCE_MEMBERSHIP 61 /* Leave a source-specific group */
|
||||
|
||||
#else
|
||||
|
||||
#define IP_ADD_SOURCE_MEMBERSHIP 70 /* join a source-specific group */
|
||||
#define IP_DROP_SOURCE_MEMBERSHIP 71 /* drop a single source */
|
||||
#define IP_BLOCK_SOURCE 72 /* block a source */
|
||||
#define IP_UNBLOCK_SOURCE 73 /* unblock a source */
|
||||
|
||||
#endif /* _AIX */
|
||||
|
||||
#endif /* IP_BLOCK_SOURCE */
|
||||
|
||||
#ifndef MCAST_BLOCK_SOURCE
|
||||
|
||||
#if defined(_AIX)
|
||||
|
||||
#define MCAST_BLOCK_SOURCE 64
|
||||
#define MCAST_UNBLOCK_SOURCE 65
|
||||
#define MCAST_JOIN_SOURCE_GROUP 66
|
||||
#define MCAST_LEAVE_SOURCE_GROUP 67
|
||||
|
||||
#else
|
||||
|
||||
#define MCAST_JOIN_SOURCE_GROUP 82 /* join a source-specific group */
|
||||
#define MCAST_LEAVE_SOURCE_GROUP 83 /* leave a single source */
|
||||
#define MCAST_BLOCK_SOURCE 84 /* block a source */
|
||||
#define MCAST_UNBLOCK_SOURCE 85 /* unblock a source */
|
||||
|
||||
#endif /* _AIX */
|
||||
|
||||
#endif /* MCAST_BLOCK_SOURCE */
|
||||
|
||||
#ifndef IPV6_ADD_MEMBERSHIP
|
||||
@ -123,6 +148,36 @@ static void initGroupSourceReq(JNIEnv* env, jbyteArray group, jint index,
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _AIX
|
||||
|
||||
/*
|
||||
* Checks whether or not "socket extensions for multicast source filters" is supported.
|
||||
* Returns JNI_TRUE if it is supported, JNI_FALSE otherwise
|
||||
*/
|
||||
static jboolean isSourceFilterSupported(){
|
||||
static jboolean alreadyChecked = JNI_FALSE;
|
||||
static jboolean result = JNI_TRUE;
|
||||
if (alreadyChecked != JNI_TRUE){
|
||||
struct utsname uts;
|
||||
memset(&uts, 0, sizeof(uts));
|
||||
strcpy(uts.sysname, "?");
|
||||
const int utsRes = uname(&uts);
|
||||
int major = -1;
|
||||
int minor = -1;
|
||||
major = atoi(uts.version);
|
||||
minor = atoi(uts.release);
|
||||
if (strcmp(uts.sysname, "AIX") == 0) {
|
||||
if (major < 6 || (major == 6 && minor < 1)) {// unsupported on aix < 6.1
|
||||
result = JNI_FALSE;
|
||||
}
|
||||
}
|
||||
alreadyChecked = JNI_TRUE;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* _AIX */
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_nio_ch_Net_initIDs(JNIEnv *env, jclass clazz)
|
||||
{
|
||||
@ -475,6 +530,14 @@ Java_sun_nio_ch_Net_joinOrDrop4(JNIEnv *env, jobject this, jboolean join, jobjec
|
||||
/* no IPv4 include-mode filtering for now */
|
||||
return IOS_UNAVAILABLE;
|
||||
#else
|
||||
|
||||
#ifdef _AIX
|
||||
/* check AIX for support of source filtering */
|
||||
if (isSourceFilterSupported() != JNI_TRUE){
|
||||
return IOS_UNAVAILABLE;
|
||||
}
|
||||
#endif
|
||||
|
||||
mreq_source.imr_multiaddr.s_addr = htonl(group);
|
||||
mreq_source.imr_sourceaddr.s_addr = htonl(source);
|
||||
mreq_source.imr_interface.s_addr = htonl(interf);
|
||||
@ -486,7 +549,7 @@ Java_sun_nio_ch_Net_joinOrDrop4(JNIEnv *env, jobject this, jboolean join, jobjec
|
||||
|
||||
n = setsockopt(fdval(env,fdo), IPPROTO_IP, opt, optval, optlen);
|
||||
if (n < 0) {
|
||||
if (join && (errno == ENOPROTOOPT))
|
||||
if (join && (errno == ENOPROTOOPT || errno == EOPNOTSUPP))
|
||||
return IOS_UNAVAILABLE;
|
||||
handleSocketError(env, errno);
|
||||
}
|
||||
@ -505,6 +568,13 @@ Java_sun_nio_ch_Net_blockOrUnblock4(JNIEnv *env, jobject this, jboolean block, j
|
||||
int n;
|
||||
int opt = (block) ? IP_BLOCK_SOURCE : IP_UNBLOCK_SOURCE;
|
||||
|
||||
#ifdef _AIX
|
||||
/* check AIX for support of source filtering */
|
||||
if (isSourceFilterSupported() != JNI_TRUE){
|
||||
return IOS_UNAVAILABLE;
|
||||
}
|
||||
#endif
|
||||
|
||||
mreq_source.imr_multiaddr.s_addr = htonl(group);
|
||||
mreq_source.imr_sourceaddr.s_addr = htonl(source);
|
||||
mreq_source.imr_interface.s_addr = htonl(interf);
|
||||
@ -512,7 +582,7 @@ Java_sun_nio_ch_Net_blockOrUnblock4(JNIEnv *env, jobject this, jboolean block, j
|
||||
n = setsockopt(fdval(env,fdo), IPPROTO_IP, opt,
|
||||
(void*)&mreq_source, sizeof(mreq_source));
|
||||
if (n < 0) {
|
||||
if (block && (errno == ENOPROTOOPT))
|
||||
if (block && (errno == ENOPROTOOPT || errno == EOPNOTSUPP))
|
||||
return IOS_UNAVAILABLE;
|
||||
handleSocketError(env, errno);
|
||||
}
|
||||
@ -550,7 +620,7 @@ Java_sun_nio_ch_Net_joinOrDrop6(JNIEnv *env, jobject this, jboolean join, jobjec
|
||||
|
||||
n = setsockopt(fdval(env,fdo), IPPROTO_IPV6, opt, optval, optlen);
|
||||
if (n < 0) {
|
||||
if (join && (errno == ENOPROTOOPT))
|
||||
if (join && (errno == ENOPROTOOPT || errno == EOPNOTSUPP))
|
||||
return IOS_UNAVAILABLE;
|
||||
handleSocketError(env, errno);
|
||||
}
|
||||
@ -579,7 +649,7 @@ Java_sun_nio_ch_Net_blockOrUnblock6(JNIEnv *env, jobject this, jboolean block, j
|
||||
n = setsockopt(fdval(env,fdo), IPPROTO_IPV6, opt,
|
||||
(void*)&req, sizeof(req));
|
||||
if (n < 0) {
|
||||
if (block && (errno == ENOPROTOOPT))
|
||||
if (block && (errno == ENOPROTOOPT || errno == EOPNOTSUPP))
|
||||
return IOS_UNAVAILABLE;
|
||||
handleSocketError(env, errno);
|
||||
}
|
||||
|
@ -42,7 +42,7 @@
|
||||
#include <strings.h>
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
#if defined(__linux__) || defined(_AIX)
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
@ -294,7 +294,13 @@ Java_sun_nio_fs_UnixNativeDispatcher_strerror(JNIEnv* env, jclass this, jint err
|
||||
jsize len;
|
||||
jbyteArray bytes;
|
||||
|
||||
#ifdef _AIX
|
||||
/* strerror() is not thread-safe on AIX so we have to use strerror_r() */
|
||||
char buffer[256];
|
||||
msg = (strerror_r((int)error, buffer, 256) == 0) ? buffer : "Error while calling strerror_r";
|
||||
#else
|
||||
msg = strerror((int)error);
|
||||
#endif
|
||||
len = strlen(msg);
|
||||
bytes = (*env)->NewByteArray(env, len);
|
||||
if (bytes != NULL) {
|
||||
@ -674,6 +680,15 @@ Java_sun_nio_fs_UnixNativeDispatcher_readdir(JNIEnv* env, jclass this, jlong val
|
||||
/* EINTR not listed as a possible error */
|
||||
/* TDB: reentrant version probably not required here */
|
||||
res = readdir64_r(dirp, ptr, &result);
|
||||
|
||||
#ifdef _AIX
|
||||
/* On AIX, readdir_r() returns EBADF (i.e. '9') and sets 'result' to NULL for the */
|
||||
/* directory stream end. Otherwise, 'errno' will contain the error code. */
|
||||
if (res != 0) {
|
||||
res = (result == NULL && res == EBADF) ? 0 : errno;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (res != 0) {
|
||||
throwUnixException(env, res);
|
||||
return NULL;
|
||||
@ -877,6 +892,18 @@ Java_sun_nio_fs_UnixNativeDispatcher_statvfs0(JNIEnv* env, jclass this,
|
||||
if (err == -1) {
|
||||
throwUnixException(env, errno);
|
||||
} else {
|
||||
#ifdef _AIX
|
||||
/* AIX returns ULONG_MAX in buf.f_blocks for the /proc file system. */
|
||||
/* This is too big for a Java signed long and fools various tests. */
|
||||
if (buf.f_blocks == ULONG_MAX) {
|
||||
buf.f_blocks = 0;
|
||||
}
|
||||
/* The number of free or available blocks can never exceed the total number of blocks */
|
||||
if (buf.f_blocks == 0) {
|
||||
buf.f_bfree = 0;
|
||||
buf.f_bavail = 0;
|
||||
}
|
||||
#endif
|
||||
(*env)->SetLongField(env, attrs, attrs_f_frsize, long_to_jlong(buf.f_frsize));
|
||||
(*env)->SetLongField(env, attrs, attrs_f_blocks, long_to_jlong(buf.f_blocks));
|
||||
(*env)->SetLongField(env, attrs, attrs_f_bfree, long_to_jlong(buf.f_bfree));
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 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
|
||||
@ -50,7 +50,11 @@ JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_Secmod_nssGetLibraryHandle
|
||||
{
|
||||
const char *libName = (*env)->GetStringUTFChars(env, jLibName, NULL);
|
||||
// look up existing handle only, do not load
|
||||
#if defined(AIX)
|
||||
void *hModule = dlopen(libName, RTLD_LAZY);
|
||||
#else
|
||||
void *hModule = dlopen(libName, RTLD_NOLOAD);
|
||||
#endif
|
||||
dprintf2("-handle for %s: %u\n", libName, hModule);
|
||||
(*env)->ReleaseStringUTFChars(env, jLibName, libName);
|
||||
return ptr_to_jlong(hModule);
|
||||
|
@ -125,8 +125,8 @@ DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void initLocalAddrTable () {}
|
||||
void parseExclusiveBindProperty (JNIEnv *env) {}
|
||||
void platformInit() {}
|
||||
void parseExclusiveBindProperty(JNIEnv *env) {}
|
||||
|
||||
/*
|
||||
* Since winsock doesn't have the equivalent of strerror(errno)
|
||||
|
@ -58,6 +58,9 @@ public class Basic {
|
||||
/* used for Mac OS X only */
|
||||
static final String cfUserTextEncoding = System.getenv("__CF_USER_TEXT_ENCODING");
|
||||
|
||||
/* used for AIX only */
|
||||
static final String libpath = System.getenv("LIBPATH");
|
||||
|
||||
private static String commandOutput(Reader r) throws Throwable {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
int c;
|
||||
@ -75,7 +78,11 @@ public class Basic {
|
||||
String output = commandOutput(r);
|
||||
equal(p.waitFor(), 0);
|
||||
equal(p.exitValue(), 0);
|
||||
return output;
|
||||
// The debug/fastdebug versions of the VM may write some warnings to stdout
|
||||
// (i.e. "Warning: Cannot open log file: hotspot.log" if the VM is started
|
||||
// in a directory without write permissions). These warnings will confuse tests
|
||||
// which match the entire output of the child process so better filter them out.
|
||||
return output.replaceAll("Warning:.*\\n", "");
|
||||
}
|
||||
|
||||
private static String commandOutput(ProcessBuilder pb) {
|
||||
@ -584,6 +591,12 @@ public class Basic {
|
||||
System.getProperty("os.name").startsWith("Windows");
|
||||
}
|
||||
|
||||
static class AIX {
|
||||
public static boolean is() { return is; }
|
||||
private static final boolean is =
|
||||
System.getProperty("os.name").equals("AIX");
|
||||
}
|
||||
|
||||
static class Unix {
|
||||
public static boolean is() { return is; }
|
||||
private static final boolean is =
|
||||
@ -637,7 +650,7 @@ public class Basic {
|
||||
|
||||
private static boolean isEnglish(String envvar) {
|
||||
String val = getenv(envvar);
|
||||
return (val == null) || val.matches("en.*");
|
||||
return (val == null) || val.matches("en.*") || val.matches("C");
|
||||
}
|
||||
|
||||
/** Returns true if we can expect English OS error strings */
|
||||
@ -712,6 +725,14 @@ public class Basic {
|
||||
return cleanedVars.replace(javaMainClassStr,"");
|
||||
}
|
||||
|
||||
/* Only used for AIX --
|
||||
* AIX adds the variable AIXTHREAD_GUARDPAGES=0 to the environment.
|
||||
* Remove it from the list of env variables
|
||||
*/
|
||||
private static String removeAixExpectedVars(String vars) {
|
||||
return vars.replace("AIXTHREAD_GUARDPAGES=0,","");
|
||||
}
|
||||
|
||||
private static String sortByLinesWindowsly(String text) {
|
||||
String[] lines = text.split("\n");
|
||||
Arrays.sort(lines, new WindowsComparator());
|
||||
@ -1160,13 +1181,20 @@ public class Basic {
|
||||
ProcessBuilder pb = new ProcessBuilder();
|
||||
pb.environment().clear();
|
||||
String expected = Windows.is() ? "SystemRoot="+systemRoot+",": "";
|
||||
expected = AIX.is() ? "LIBPATH="+libpath+",": expected;
|
||||
if (Windows.is()) {
|
||||
pb.environment().put("SystemRoot", systemRoot);
|
||||
}
|
||||
if (AIX.is()) {
|
||||
pb.environment().put("LIBPATH", libpath);
|
||||
}
|
||||
String result = getenvInChild(pb);
|
||||
if (MacOSX.is()) {
|
||||
result = removeMacExpectedVars(result);
|
||||
}
|
||||
if (AIX.is()) {
|
||||
result = removeAixExpectedVars(result);
|
||||
}
|
||||
equal(result, expected);
|
||||
} catch (Throwable t) { unexpected(t); }
|
||||
|
||||
@ -1681,10 +1709,14 @@ public class Basic {
|
||||
}
|
||||
Process p = Runtime.getRuntime().exec(cmdp, envp);
|
||||
String expected = Windows.is() ? "=C:=\\,=ExitValue=3,SystemRoot="+systemRoot+"," : "=C:=\\,";
|
||||
expected = AIX.is() ? expected + "LIBPATH="+libpath+",": expected;
|
||||
String commandOutput = commandOutput(p);
|
||||
if (MacOSX.is()) {
|
||||
commandOutput = removeMacExpectedVars(commandOutput);
|
||||
}
|
||||
if (AIX.is()) {
|
||||
commandOutput = removeAixExpectedVars(commandOutput);
|
||||
}
|
||||
equal(commandOutput, expected);
|
||||
if (Windows.is()) {
|
||||
ProcessBuilder pb = new ProcessBuilder(childArgs);
|
||||
@ -1736,9 +1768,14 @@ public class Basic {
|
||||
if (MacOSX.is()) {
|
||||
commandOutput = removeMacExpectedVars(commandOutput);
|
||||
}
|
||||
if (AIX.is()) {
|
||||
commandOutput = removeAixExpectedVars(commandOutput);
|
||||
}
|
||||
check(commandOutput.equals(Windows.is()
|
||||
? "LC_ALL=C,SystemRoot="+systemRoot+","
|
||||
: "LC_ALL=C,"),
|
||||
: AIX.is()
|
||||
? "LC_ALL=C,LIBPATH="+libpath+","
|
||||
: "LC_ALL=C,"),
|
||||
"Incorrect handling of envstrings containing NULs");
|
||||
} catch (Throwable t) { unexpected(t); }
|
||||
|
||||
@ -2015,7 +2052,12 @@ public class Basic {
|
||||
if (Unix.is()
|
||||
&& new File("/bin/bash").exists()
|
||||
&& new File("/bin/sleep").exists()) {
|
||||
final String[] cmd = { "/bin/bash", "-c", "(/bin/sleep 6666)" };
|
||||
// Notice that we only destroy the process created by us (i.e.
|
||||
// our child) but not our grandchild (i.e. '/bin/sleep'). So
|
||||
// pay attention that the grandchild doesn't run too long to
|
||||
// avoid polluting the process space with useless processes.
|
||||
// Running the grandchild for 60s should be more than enough.
|
||||
final String[] cmd = { "/bin/bash", "-c", "(/bin/sleep 60)" };
|
||||
final ProcessBuilder pb = new ProcessBuilder(cmd);
|
||||
final Process p = pb.start();
|
||||
final InputStream stdout = p.getInputStream();
|
||||
@ -2037,12 +2079,26 @@ public class Basic {
|
||||
reader.start();
|
||||
Thread.sleep(100);
|
||||
p.destroy();
|
||||
// Subprocess is now dead, but file descriptors remain open.
|
||||
check(p.waitFor() != 0);
|
||||
check(p.exitValue() != 0);
|
||||
// Subprocess is now dead, but file descriptors remain open.
|
||||
// Make sure the test will fail if we don't manage to close
|
||||
// the open streams within 30 seconds. Notice that this time
|
||||
// must be shorter than the sleep time of the grandchild.
|
||||
Timer t = new Timer("test/java/lang/ProcessBuilder/Basic.java process reaper", true);
|
||||
t.schedule(new TimerTask() {
|
||||
public void run() {
|
||||
fail("Subprocesses which create subprocesses of " +
|
||||
"their own caused the parent to hang while " +
|
||||
"waiting for file descriptors to be closed.");
|
||||
System.exit(-1);
|
||||
}
|
||||
}, 30000);
|
||||
stdout.close();
|
||||
stderr.close();
|
||||
stdin.close();
|
||||
// All streams successfully closed so we can cancel the timer.
|
||||
t.cancel();
|
||||
//----------------------------------------------------------
|
||||
// There remain unsolved issues with asynchronous close.
|
||||
// Here's a highly non-portable experiment to demonstrate:
|
||||
@ -2188,8 +2244,9 @@ public class Basic {
|
||||
}
|
||||
long end = System.nanoTime();
|
||||
// give waitFor(timeout) a wide berth (100ms)
|
||||
if ((end - start) > 100000000)
|
||||
fail("Test failed: waitFor took too long");
|
||||
// Old AIX machines my need a little longer.
|
||||
if ((end - start) > 100000000L * (AIX.is() ? 4 : 1))
|
||||
fail("Test failed: waitFor took too long (" + (end - start) + "ns)");
|
||||
|
||||
p.destroy();
|
||||
p.waitFor();
|
||||
@ -2216,7 +2273,7 @@ public class Basic {
|
||||
|
||||
long end = System.nanoTime();
|
||||
if ((end - start) < 500000000)
|
||||
fail("Test failed: waitFor didn't take long enough");
|
||||
fail("Test failed: waitFor didn't take long enough (" + (end - start) + "ns)");
|
||||
|
||||
p.destroy();
|
||||
|
||||
@ -2224,7 +2281,7 @@ public class Basic {
|
||||
p.waitFor(1000, TimeUnit.MILLISECONDS);
|
||||
end = System.nanoTime();
|
||||
if ((end - start) > 900000000)
|
||||
fail("Test failed: waitFor took too long on a dead process.");
|
||||
fail("Test failed: waitFor took too long on a dead process. (" + (end - start) + "ns)");
|
||||
} catch (Throwable t) { unexpected(t); }
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
@ -154,6 +154,9 @@ public class DestroyTest {
|
||||
} else if (osName.equals("SunOS")) {
|
||||
return new UnixTest(
|
||||
File.createTempFile("ProcessTrap-", ".sh",null));
|
||||
} else if (osName.equals("AIX")) {
|
||||
return new UnixTest(
|
||||
File.createTempFile("ProcessTrap-", ".sh",null));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user