summaryrefslogtreecommitdiff
path: root/native
diff options
context:
space:
mode:
Diffstat (limited to 'native')
-rw-r--r--native/jawt/jawt.c2
-rw-r--r--native/jni/classpath/classpath_jawt.h1
-rw-r--r--native/jni/classpath/jcl.c2
-rw-r--r--native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoGraphics2D.c73
-rw-r--r--native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFramePeer.c44
-rw-r--r--native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkToolkit.c38
-rw-r--r--native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c64
-rw-r--r--native/jni/gtk-peer/gtk_jawt.c35
-rw-r--r--native/jni/java-net/Makefile.am1
-rw-r--r--native/jni/java-net/gnu_java_net_VMPlainSocketImpl.c170
-rw-r--r--native/jni/java-net/javanet.c2
-rw-r--r--native/jni/java-net/javanet.h1
-rw-r--r--native/jni/java-nio/gnu_java_nio_VMChannel.c104
-rw-r--r--native/jni/native-lib/cpio.c10
-rw-r--r--native/jni/native-lib/cpio.h1
15 files changed, 406 insertions, 142 deletions
diff --git a/native/jawt/jawt.c b/native/jawt/jawt.c
index a41786850..4ebb105d7 100644
--- a/native/jawt/jawt.c
+++ b/native/jawt/jawt.c
@@ -116,6 +116,8 @@ static JAWT_DrawingSurfaceInfo*
surface->target);
surface_info_x11->visualID = classpath_jawt_get_visualID (surface->env,
surface->target);
+ surface_info_x11->depth = classpath_jawt_get_depth (surface->env,
+ surface->target);
/* FIXME: also include bounding rectangle of drawing surface */
/* FIXME: also include current clipping region */
diff --git a/native/jni/classpath/classpath_jawt.h b/native/jni/classpath/classpath_jawt.h
index 32a04dc5c..35c734a57 100644
--- a/native/jni/classpath/classpath_jawt.h
+++ b/native/jni/classpath/classpath_jawt.h
@@ -54,6 +54,7 @@ jint classpath_jawt_get_awt_version (void);
Display* classpath_jawt_get_default_display (JNIEnv* env, jobject canvas);
Drawable classpath_jawt_get_drawable (JNIEnv* env, jobject canvas);
VisualID classpath_jawt_get_visualID (JNIEnv* env, jobject canvas);
+int classpath_jawt_get_depth (JNIEnv* env, jobject canvas);
jint classpath_jawt_lock (void);
void classpath_jawt_unlock (void);
diff --git a/native/jni/classpath/jcl.c b/native/jni/classpath/jcl.c
index 607b54d57..cd3f5161d 100644
--- a/native/jni/classpath/jcl.c
+++ b/native/jni/classpath/jcl.c
@@ -58,7 +58,7 @@ static jmethodID rawData_mid = NULL;
/*
* JNI OnLoad constructor.
*/
-jint
+JNIEXPORT jint JNICALL
JNI_OnLoad (JavaVM *vm, void *reserved __attribute__((unused)))
{
JNIEnv *env;
diff --git a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoGraphics2D.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoGraphics2D.c
index 0a35a3f18..11b0426c6 100644
--- a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoGraphics2D.c
+++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoGraphics2D.c
@@ -49,7 +49,6 @@ exception statement from your version. */
#include <stdio.h>
#include <stdlib.h>
-static void install_font_peer(cairo_t *cr, struct peerfont *pfont);
static void update_pattern_transform (struct cairographics2d *gr);
/**
@@ -327,8 +326,6 @@ Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoDrawGlyphVector
pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, font);
g_assert (pfont != NULL);
- install_font_peer(gr->cr, pfont);
-
glyphs = g_malloc( sizeof(cairo_glyph_t) * n);
g_assert (glyphs != NULL);
@@ -354,6 +351,37 @@ Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoDrawGlyphVector
JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoSetFont
+(JNIEnv *env __attribute__ ((unused)), jobject obj __attribute__ ((unused)),
+ jlong pointer, jobject font)
+{
+ struct cairographics2d *gr = NULL;
+ struct peerfont *pfont = NULL;
+ FT_Face face = NULL;
+ cairo_font_face_t *ft = NULL;
+
+ gr = JLONG_TO_PTR(struct cairographics2d, pointer);
+ g_assert (gr != NULL);
+
+ pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, font);
+ g_assert (pfont != NULL);
+
+ face = pango_fc_font_lock_face( (PangoFcFont *)pfont->font );
+ g_assert (face != NULL);
+
+ ft = cairo_ft_font_face_create_for_ft_face (face, 0);
+ g_assert (ft != NULL);
+
+ cairo_set_font_face (gr->cr, ft);
+ cairo_set_font_size (gr->cr,
+ (pango_font_description_get_size (pfont->desc) /
+ (double)PANGO_SCALE));
+
+ cairo_font_face_destroy (ft);
+ pango_fc_font_unlock_face((PangoFcFont *)pfont->font);
+}
+
+JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoSetOperator
(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
jlong pointer, jint op)
@@ -748,45 +776,6 @@ Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoFillRect
cairo_fill(gr->cr);
}
-
-/************************** FONT STUFF ****************************/
-static void
-install_font_peer(cairo_t *cr,
- struct peerfont *pfont)
-{
- cairo_font_face_t *ft;
- FT_Face face = NULL;
-
- g_assert(cr != NULL);
- g_assert(pfont != NULL);
-
- if (pfont->graphics_resource == NULL)
- {
- face = pango_fc_font_lock_face( (PangoFcFont *)pfont->font );
- g_assert (face != NULL);
-
- ft = cairo_ft_font_face_create_for_ft_face (face, 0);
- g_assert (ft != NULL);
-
- cairo_set_font_face (cr, ft);
- /* cairo_font_face_destroy (ft);*/
- cairo_set_font_size (cr,
- (pango_font_description_get_size (pfont->desc) /
- (double)PANGO_SCALE));
- ft = cairo_get_font_face (cr);
- pango_fc_font_unlock_face( (PangoFcFont *)pfont->font );
- pfont->graphics_resource = ft;
- }
- else
- {
- ft = (cairo_font_face_t *) pfont->graphics_resource;
- cairo_set_font_face (cr, ft);
- cairo_set_font_size (cr,
- (pango_font_description_get_size (pfont->desc) /
- (double)PANGO_SCALE));
- }
-}
-
static void
update_pattern_transform (struct cairographics2d *gr)
{
diff --git a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFramePeer.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFramePeer.c
index 766964314..144ca0e8a 100644
--- a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFramePeer.c
+++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFramePeer.c
@@ -188,3 +188,47 @@ Java_gnu_java_awt_peer_gtk_GtkFramePeer_nativeSetIconImage
gdk_threads_leave ();
}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkFramePeer_maximize
+(JNIEnv *env, jobject obj)
+{
+ void *ptr;
+ gdk_threads_enter ();
+ ptr = NSA_GET_PTR (env, obj);
+ gtk_window_maximize (GTK_WINDOW (ptr));
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkFramePeer_unmaximize
+(JNIEnv *env, jobject obj)
+{
+ void *ptr;
+ gdk_threads_enter ();
+ ptr = NSA_GET_PTR (env, obj);
+ gtk_window_unmaximize (GTK_WINDOW (ptr));
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkFramePeer_iconify
+(JNIEnv *env, jobject obj)
+{
+ void *ptr;
+ gdk_threads_enter ();
+ ptr = NSA_GET_PTR (env, obj);
+ gtk_window_iconify (GTK_WINDOW (ptr));
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkFramePeer_deiconify
+(JNIEnv *env, jobject obj)
+{
+ void *ptr;
+ gdk_threads_enter ();
+ ptr = NSA_GET_PTR (env, obj);
+ gtk_window_deiconify (GTK_WINDOW (ptr));
+ gdk_threads_leave ();
+}
diff --git a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkToolkit.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkToolkit.c
index 969b7bc5c..0f868eaed 100644
--- a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkToolkit.c
+++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkToolkit.c
@@ -77,8 +77,10 @@ struct state_table *cp_gtk_native_state_table;
struct state_table *cp_gtk_native_global_ref_table;
static jclass gtkgenericpeer;
+static jclass gtktoolkit;
static JavaVM *java_vm;
static jmethodID printCurrentThreadID;
+static jmethodID setRunningID;
union env_union
{
@@ -99,7 +101,9 @@ GtkWindowGroup *cp_gtk_global_window_group;
double cp_gtk_dpi_conversion_factor;
static void init_glib_threads(JNIEnv *, jint);
-
+static gboolean post_set_running_flag (gpointer);
+static gboolean set_running_flag (gpointer);
+static gboolean clear_running_flag (gpointer);
static void init_dpi_conversion_factor (void);
static void dpi_changed_cb (GtkSettings *settings,
GParamSpec *pspec);
@@ -199,6 +203,10 @@ Java_gnu_java_awt_peer_gtk_GtkToolkit_gtkInit (JNIEnv *env,
cp_gtk_global_window_group = gtk_window_group_new ();
init_dpi_conversion_factor ();
+
+ gtktoolkit = (*env)->FindClass(env, "gnu/java/awt/peer/gtk/GtkMainThread");
+ setRunningID = (*env)->GetStaticMethodID (env, gtktoolkit,
+ "setRunning", "(Z)V");
}
@@ -324,6 +332,9 @@ Java_gnu_java_awt_peer_gtk_GtkToolkit_gtkMain
{
gdk_threads_enter ();
+ gtk_init_add (post_set_running_flag, NULL);
+ gtk_quit_add (gtk_main_level (), clear_running_flag, NULL);
+
gtk_main ();
gdk_threads_leave ();
@@ -502,3 +513,28 @@ gdk_color_to_java_color (GdkColor gdk_color)
return (jint) (0xff000000 | (red << 16) | (green << 8) | blue);
}
+
+static gboolean
+post_set_running_flag (gpointer data __attribute__((unused)))
+{
+ g_idle_add (set_running_flag, NULL);
+ return FALSE;
+}
+
+static gboolean
+set_running_flag (gpointer data __attribute__((unused)))
+{
+ (*cp_gtk_gdk_env ())->CallStaticVoidMethod (cp_gtk_gdk_env (),
+ gtktoolkit,
+ setRunningID, TRUE);
+ return FALSE;
+}
+
+static gboolean
+clear_running_flag (gpointer data __attribute__((unused)))
+{
+ (*cp_gtk_gdk_env ())->CallStaticVoidMethod (cp_gtk_gdk_env (),
+ gtktoolkit,
+ setRunningID, FALSE);
+ return FALSE;
+}
diff --git a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c
index 3f288af5c..aa70b9d2d 100644
--- a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c
+++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c
@@ -44,7 +44,6 @@ exception statement from your version. */
#include <X11/Xatom.h>
#include <gdk/gdkkeysyms.h>
-#define AWT_WINDOW_OPENED 200
#define AWT_WINDOW_CLOSING 201
#define AWT_WINDOW_CLOSED 202
#define AWT_WINDOW_ICONIFIED 203
@@ -55,6 +54,10 @@ exception statement from your version. */
#define AWT_WINDOW_LOST_FOCUS 208
#define AWT_WINDOW_STATE_CHANGED 209
+#define AWT_FRAME_NORMAL 0
+#define AWT_FRAME_ICONIFIED 1
+#define AWT_FRAME_MAXIMIZED_BOTH 6
+
/* Virtual Keys */
/* This list should be kept in the same order as the VK_ field
declarations in KeyEvent.java. */
@@ -1046,7 +1049,6 @@ static gboolean window_delete_cb (GtkWidget *widget, GdkEvent *event,
jobject peer);
static void window_destroy_cb (GtkWidget *widget, GdkEvent *event,
jobject peer);
-static void window_show_cb (GtkWidget *widget, jobject peer);
static void window_focus_state_change_cb (GtkWidget *widget,
GParamSpec *pspec,
jobject peer);
@@ -1322,9 +1324,6 @@ Java_gnu_java_awt_peer_gtk_GtkWindowPeer_connectSignals
g_signal_connect (G_OBJECT (ptr), "destroy-event",
G_CALLBACK (window_destroy_cb), *gref);
- g_signal_connect (G_OBJECT (ptr), "show",
- G_CALLBACK (window_show_cb), *gref);
-
g_signal_connect (G_OBJECT (ptr), "notify::has-toplevel-focus",
G_CALLBACK (window_focus_state_change_cb), *gref);
@@ -1661,16 +1660,6 @@ window_destroy_cb (GtkWidget *widget __attribute__((unused)),
}
static void
-window_show_cb (GtkWidget *widget __attribute__((unused)),
- jobject peer)
-{
- (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
- postWindowEventID,
- (jint) AWT_WINDOW_OPENED,
- (jobject) NULL, (jint) 0);
-}
-
-static void
window_focus_state_change_cb (GtkWidget *widget,
GParamSpec *pspec __attribute__((unused)),
jobject peer)
@@ -1718,41 +1707,24 @@ window_window_state_cb (GtkWidget *widget __attribute__((unused)),
GdkEvent *event,
jobject peer)
{
- jint new_state;
-
- /* Handle WINDOW_ICONIFIED and WINDOW_DEICONIFIED events. */
- if (event->window_state.changed_mask & GDK_WINDOW_STATE_ICONIFIED)
- {
- /* We've either been iconified or deiconified. */
- if (event->window_state.new_window_state & GDK_WINDOW_STATE_ICONIFIED)
- {
- /* We've been iconified. */
- (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
- postWindowEventID,
- (jint) AWT_WINDOW_ICONIFIED,
- (jobject) NULL, (jint) 0);
- }
- else
- {
- /* We've been deiconified. */
- (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
- postWindowEventID,
- (jint) AWT_WINDOW_DEICONIFIED,
- (jobject) NULL, (jint) 0);
- }
- }
-
- /* Post a WINDOW_STATE_CHANGED event, passing the new frame state to
- GtkWindowPeer. */
- new_state = AWT_FRAME_STATE_NORMAL;
-
- if (event->window_state.new_window_state & GDK_WINDOW_STATE_ICONIFIED)
- new_state |= AWT_FRAME_STATE_ICONIFIED;
+ jint new_java_state = 0;
+ /* Put together the new state and let the java side figure out what
+ * to post */
+ GdkWindowState new_state = event->window_state.new_window_state;
+ /* The window can be either iconfified, maximized, iconified + maximized
+ * or normal. */
+ if ((new_state & GDK_WINDOW_STATE_ICONIFIED) != 0)
+ new_java_state |= AWT_FRAME_ICONIFIED;
+ if ((new_state & GDK_WINDOW_STATE_MAXIMIZED) != 0)
+ new_java_state |= AWT_FRAME_MAXIMIZED_BOTH;
+ if ((new_state & (GDK_WINDOW_STATE_MAXIMIZED | GDK_WINDOW_STATE_ICONIFIED))
+ == 0)
+ new_java_state = AWT_FRAME_NORMAL;
(*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
postWindowEventID,
(jint) AWT_WINDOW_STATE_CHANGED,
- (jobject) NULL, new_state);
+ (jobject) NULL, new_java_state);
return TRUE;
}
diff --git a/native/jni/gtk-peer/gtk_jawt.c b/native/jni/gtk-peer/gtk_jawt.c
index 763db8d1e..2348a63fb 100644
--- a/native/jni/gtk-peer/gtk_jawt.c
+++ b/native/jni/gtk-peer/gtk_jawt.c
@@ -122,6 +122,41 @@ classpath_jawt_get_visualID (JNIEnv* env, jobject canvas)
/* Does not require locking: meant to be called after the drawing
surface is locked. */
+int
+classpath_jawt_get_depth (JNIEnv* env, jobject canvas)
+{
+ GtkWidget *widget;
+ GdkVisual *visual;
+ void *ptr;
+ jobject peer;
+ jclass class_id;
+ jmethodID method_id;
+
+ class_id = (*env)->GetObjectClass (env, canvas);
+
+ method_id = (*env)->GetMethodID (env, class_id,
+ "getPeer",
+ "()Ljava/awt/peer/ComponentPeer;");
+
+ peer = (*env)->CallObjectMethod (env, canvas, method_id);
+
+ ptr = NSA_GET_PTR (env, peer);
+
+ widget = GTK_WIDGET (ptr);
+
+ if (GTK_WIDGET_REALIZED (widget))
+ {
+ visual = gtk_widget_get_visual (widget);
+ g_assert (visual != NULL);
+
+ return visual->depth;
+ }
+ else
+ return (VisualID) NULL;
+}
+
+/* Does not require locking: meant to be called after the drawing
+ surface is locked. */
Drawable
classpath_jawt_get_drawable (JNIEnv* env, jobject canvas)
{
diff --git a/native/jni/java-net/Makefile.am b/native/jni/java-net/Makefile.am
index b743f2ffe..1278b946c 100644
--- a/native/jni/java-net/Makefile.am
+++ b/native/jni/java-net/Makefile.am
@@ -13,7 +13,6 @@ libjavanet_la_SOURCES = javanet.c \
java_net_VMInetAddress.c \
java_net_VMNetworkInterface.c \
java_net_VMURLConnection.c \
- gnu_java_net_VMPlainDatagramSocketImpl.c \
gnu_java_net_VMPlainSocketImpl.c \
$(local_sources)
diff --git a/native/jni/java-net/gnu_java_net_VMPlainSocketImpl.c b/native/jni/java-net/gnu_java_net_VMPlainSocketImpl.c
index 6ebb64fa5..53ef04d47 100644
--- a/native/jni/java-net/gnu_java_net_VMPlainSocketImpl.c
+++ b/native/jni/java-net/gnu_java_net_VMPlainSocketImpl.c
@@ -40,6 +40,8 @@ exception statement from your version. */
#include <config.h>
#endif /* HAVE_CONFIG_H */
+#include <config-int.h>
+
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
@@ -47,6 +49,7 @@ exception statement from your version. */
#include <ifaddrs.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
+#include <net/if.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
@@ -56,16 +59,14 @@ exception statement from your version. */
#include <jni.h>
#include <jcl.h>
-/* #include "javanet.h" */
+#include "cpnative.h"
+#include "cpnet.h"
+#include "cpio.h"
+#include "javanet.h"
#include "gnu_java_net_VMPlainSocketImpl.h"
-#define IO_EXCEPTION "java/io/IOException"
-#define SOCKET_EXCEPTION "java/net/SocketException"
-#define BIND_EXCEPTION "java/net/BindException"
-
-#define THROW_NO_NETWORK(env) JCL_ThrowException (env, "java/lang/InternalError", "this platform not configured for network support")
-
+#define THROW_NO_NETWORK(env) JCL_ThrowException (env, "java/lang/InternalError", "this platform not configured for network support")
/*
* Class: gnu_java_net_VMPlainSocketImpl
@@ -102,6 +103,8 @@ Java_gnu_java_net_VMPlainSocketImpl_bind (JNIEnv *env,
if (-1 == ret)
JCL_ThrowException (env, BIND_EXCEPTION, strerror (errno));
+
+ cpio_closeOnExec(ret);
}
@@ -158,7 +161,10 @@ Java_gnu_java_net_VMPlainSocketImpl_listen (JNIEnv *env,
}
-/* These constants are also defined in java/net/SocketOptions.java */
+/* These constants are also defined in java/net/SocketOptions.java.
+ * Except for CPNET_IP_TTL which is defined in
+ * vm/reference/gnu/java/net/VMPlainSocketImpl.java .
+ */
enum java_sockopt {
CPNET_SO_KEEPALIVE = 0x8,
CPNET_SO_LINGER = 0x80,
@@ -173,7 +179,8 @@ enum java_sockopt {
CPNET_IP_MULTICAST_IF = 0x10,
CPNET_IP_MULTICAST_IF2 = 0x1F,
CPNET_IP_MULTICAST_LOOP = 0x12,
- CPNET_IP_TOS = 0x03
+ CPNET_IP_TOS = 0x03,
+ CPNET_IP_TTL = 0x1E61
};
@@ -195,7 +202,7 @@ Java_gnu_java_net_VMPlainSocketImpl_setOption (JNIEnv *env,
struct timeval _timeo;
void *optval = (void *) &_value;
socklen_t optlen = sizeof (int);
-
+
switch (joption)
{
case CPNET_IP_MULTICAST_LOOP:
@@ -209,7 +216,7 @@ Java_gnu_java_net_VMPlainSocketImpl_setOption (JNIEnv *env,
case CPNET_SO_LINGER:
optname = SO_LINGER;
- if (_value == 0)
+ if (_value == -1)
_linger.l_onoff = 0;
else
_linger.l_onoff = 1;
@@ -256,6 +263,11 @@ Java_gnu_java_net_VMPlainSocketImpl_setOption (JNIEnv *env,
optname = IP_TOS;
break;
+ case CPNET_IP_TTL:
+ level = IPPROTO_IP;
+ optname = IP_TTL;
+ break;
+
case CPNET_SO_BINDADDR:
case CPNET_IP_MULTICAST_IF:
case CPNET_IP_MULTICAST_IF2:
@@ -339,6 +351,11 @@ Java_gnu_java_net_VMPlainSocketImpl_getOption (JNIEnv *env,
optname = IP_TOS;
break;
+ case CPNET_IP_TTL:
+ level = IPPROTO_IP;
+ optname = IP_TTL;
+ break;
+
case CPNET_SO_BINDADDR:
case CPNET_IP_MULTICAST_IF:
case CPNET_IP_MULTICAST_IF2:
@@ -349,14 +366,108 @@ Java_gnu_java_net_VMPlainSocketImpl_getOption (JNIEnv *env,
if (getsockopt (fd, level, optname, optval, &optlen) == -1)
JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
+ /* Returns the linger value if it is enabled or -1 in case
+ * it is disabled. This is how the Java API expects it.
+ */
if (joption == CPNET_SO_LINGER)
- return linger.l_linger;
+ return (linger.l_onoff) ? linger.l_linger : -1;
if (joption == CPNET_SO_TIMEOUT)
return (timeo.tv_sec * 1000) + (timeo.tv_usec / 1000);
return value;
}
+JNIEXPORT void JNICALL
+Java_gnu_java_net_VMPlainSocketImpl_setMulticastInterface (JNIEnv *env,
+ jclass c __attribute__((unused)),
+ jint fd,
+ jint optionId __attribute__((unused)),
+ jobject addr)
+{
+ int result;
+ cpnet_address *cpaddr = _javanet_get_ip_netaddr (env, addr);
+
+ if ((*env)->ExceptionOccurred (env))
+ return;
+
+ result = setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF,
+ (struct sockaddr *) cpaddr->data, cpaddr->len);
+
+ cpnet_freeAddress (env, cpaddr);
+
+ if (result == -1)
+ JCL_ThrowException (env, SOCKET_EXCEPTION, cpnative_getErrorString (errno));
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_net_VMPlainSocketImpl_setMulticastInterface6 (JNIEnv *env,
+ jclass c __attribute__((unused)),
+ jint fd,
+ jint optionId __attribute__((unused)),
+ jstring ifname)
+{
+#ifdef HAVE_SETSOCKOPT
+#ifdef HAVE_INET6
+ int result;
+ const char *str_ifname = JCL_jstring_to_cstring (env, ifname);
+ u_int if_index;
+
+ if ((*env)->ExceptionOccurred (env))
+ {
+ JCL_free_cstring(env, ifname, str_ifname);
+ return;
+ }
+
+ if_index = if_nametoindex(str_ifname);
+ if (!if_index)
+ {
+ JCL_free_cstring(env, ifname, str_ifname);
+ JCL_ThrowException (env, SOCKET_EXCEPTION, "interface does not exist");
+ return;
+ }
+
+ result = setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF,
+ (u_int *) &if_index, sizeof(if_index));
+
+ JCL_free_cstring(env, ifname, str_ifname);
+
+ if (result == -1)
+ JCL_ThrowException (env, SOCKET_EXCEPTION, cpnative_getErrorString (errno));
+#else
+ (void) fd;
+ JCL_ThrowException (env, "java/lang/InternalError",
+ "IPv6 support not available");
+#endif /* HAVE_INET6 */
+#else
+ (void) fd;
+ JCL_ThrowException (env, "java/lang/InternalError",
+ "socket options not supported");
+#endif /* HAVE_SETSOCKOPT */
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_java_net_VMPlainSocketImpl_getMulticastInterface (JNIEnv *env,
+ jclass c __attribute__((unused)),
+ jint fd,
+ jint optionId __attribute__((unused)))
+{
+ jobject obj;
+ cpnet_address *cpaddr;
+ int result = cpnet_getMulticastIF (env, fd, &cpaddr);
+
+ if (result != CPNATIVE_OK)
+ {
+ JCL_ThrowException (env, SOCKET_EXCEPTION,
+ cpnative_getErrorString (result));
+ return (0);
+ }
+
+ obj = _javanet_create_inetaddress (env, cpaddr);
+ cpnet_freeAddress (env, cpaddr);
+
+ return obj;
+}
+
/*
* Class: gnu_java_net_VMPlainSocketImpl
@@ -538,7 +649,7 @@ Java_gnu_java_net_VMPlainSocketImpl_leave6 (JNIEnv *env,
(*env)->ReleaseByteArrayElements (env, addr, addr_elems, JNI_ABORT);
- if (-1 == setsockopt (fd, IPPROTO_IPV6, IPV6_JOIN_GROUP,
+ if (-1 == setsockopt (fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP,
&maddr, sizeof (struct ipv6_mreq)))
JCL_ThrowException (env, SOCKET_EXCEPTION, strerror (errno));
#else
@@ -555,8 +666,8 @@ Java_gnu_java_net_VMPlainSocketImpl_leave6 (JNIEnv *env,
#endif /* HAVE_SETSOCKOPT */
}
-static uint32_t getif_address (JNIEnv *env, char *ifname);
-static int getif_index (JNIEnv *env, char *ifname);
+static uint32_t getif_address (JNIEnv *env, const char *ifname);
+static int getif_index (JNIEnv *env, const char *ifname);
/*
* Class: gnu_java_net_VMPlainSocketImpl
@@ -572,10 +683,14 @@ Java_gnu_java_net_VMPlainSocketImpl_joinGroup (JNIEnv *env,
#ifdef HAVE_SETSOCKOPT
struct ip_mreq maddr;
jbyte *addr_elems;
+ const char *str_ifname;
if (ifname != NULL)
{
- maddr.imr_interface.s_addr = getif_address (env, ifname);
+ str_ifname = JCL_jstring_to_cstring(env, ifname);
+ maddr.imr_interface.s_addr = getif_address (env, str_ifname);
+ JCL_free_cstring(env, ifname, str_ifname);
+
if ((*env)->ExceptionCheck (env))
return;
}
@@ -593,6 +708,7 @@ Java_gnu_java_net_VMPlainSocketImpl_joinGroup (JNIEnv *env,
if (-1 == setsockopt (fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
&maddr, sizeof (struct ip_mreq)))
JCL_ThrowException (env, SOCKET_EXCEPTION, strerror (errno));
+
#else
(void) fd;
(void) addr;
@@ -617,10 +733,14 @@ Java_gnu_java_net_VMPlainSocketImpl_joinGroup6 (JNIEnv *env,
#ifdef HAVE_INET6
struct ipv6_mreq maddr;
jbyte *addr_elems;
+ const char *str_ifname;
if (ifname == NULL)
{
- maddr.ipv6mr_interface = getif_index (env, ifname);
+ str_ifname = JCL_jstring_to_cstring(env, ifname);
+ maddr.ipv6mr_interface = getif_index (env, str_ifname);
+ JCL_free_cstring(env, ifname, str_ifname);
+
if ((*env)->ExceptionCheck (env))
return;
}
@@ -666,10 +786,14 @@ Java_gnu_java_net_VMPlainSocketImpl_leaveGroup (JNIEnv *env,
#ifdef HAVE_SETSOCKOPT
struct ip_mreq maddr;
jbyte *addr_elems;
+ const char *str_ifname;
if (ifname != NULL)
{
- maddr.imr_interface.s_addr = getif_address (env, ifname);
+ str_ifname = JCL_jstring_to_cstring(env, ifname);
+ maddr.imr_interface.s_addr = getif_address (env, str_ifname);
+ JCL_free_cstring(env, ifname, str_ifname);
+
if ((*env)->ExceptionCheck (env))
return;
}
@@ -711,10 +835,14 @@ Java_gnu_java_net_VMPlainSocketImpl_leaveGroup6 (JNIEnv *env,
#ifdef HAVE_INET6
struct ipv6_mreq maddr;
jbyte *addr_elems;
+ const char *str_ifname;
if (ifname == NULL)
{
- maddr.ipv6mr_interface = getif_index (env, ifname);
+ str_ifname = JCL_jstring_to_cstring(env, ifname);
+ maddr.ipv6mr_interface = getif_index (env, str_ifname);
+ JCL_free_cstring(env, ifname, str_ifname);
+
if ((*env)->ExceptionCheck (env))
return;
}
@@ -747,7 +875,7 @@ Java_gnu_java_net_VMPlainSocketImpl_leaveGroup6 (JNIEnv *env,
}
static uint32_t
-getif_address (JNIEnv *env, char *ifname)
+getif_address (JNIEnv *env, const char *ifname)
{
#ifdef HAVE_GETIFADDRS
struct ifaddrs *ifaddrs, *i;
@@ -789,7 +917,7 @@ getif_address (JNIEnv *env, char *ifname)
}
static int
-getif_index (JNIEnv *env, char *ifname)
+getif_index (JNIEnv *env, const char *ifname)
{
#ifdef HAVE_GETIFADDRS
struct ifaddrs *ifaddrs, *i;
diff --git a/native/jni/java-net/javanet.c b/native/jni/java-net/javanet.c
index a8213044f..1d2f7202a 100644
--- a/native/jni/java-net/javanet.c
+++ b/native/jni/java-net/javanet.c
@@ -232,7 +232,7 @@ _javanet_create_integer (JNIEnv * env, jint val)
/*
* Builds an InetAddress object from a 32 bit address in host byte order
*/
-static jobject
+jobject
_javanet_create_inetaddress (JNIEnv * env, cpnet_address *netaddr)
{
#ifndef WITHOUT_NETWORK
diff --git a/native/jni/java-net/javanet.h b/native/jni/java-net/javanet.h
index 411c6c651..96dba881b 100644
--- a/native/jni/java-net/javanet.h
+++ b/native/jni/java-net/javanet.h
@@ -81,6 +81,7 @@ exception statement from your version. */
extern int _javanet_get_int_field(JNIEnv *, jobject, const char *);
extern cpnet_address *_javanet_get_ip_netaddr(JNIEnv *, jobject);
+extern jobject _javanet_create_inetaddress (JNIEnv *, cpnet_address *);
extern void _javanet_create(JNIEnv *, jobject, jboolean);
extern void _javanet_close(JNIEnv *, jobject, int);
extern void _javanet_connect(JNIEnv *, jobject, jobject, jint, jboolean);
diff --git a/native/jni/java-nio/gnu_java_nio_VMChannel.c b/native/jni/java-nio/gnu_java_nio_VMChannel.c
index b4f444361..33a4f66de 100644
--- a/native/jni/java-nio/gnu_java_nio_VMChannel.c
+++ b/native/jni/java-nio/gnu_java_nio_VMChannel.c
@@ -40,6 +40,8 @@ exception statement from your version. */
#include <config.h>
#endif
+#include <config-int.h>
+
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
@@ -57,6 +59,7 @@ exception statement from your version. */
#include <jni.h>
#include <jcl.h>
+#include "cpio.h"
#include "gnu_java_nio_VMChannel.h"
#include "javanio.h"
@@ -64,7 +67,9 @@ exception statement from your version. */
#include <fcntl.h>
#endif /* HAVE_FCNTL_H */
+#define CONNECT_EXCEPTION "java/net/ConnectException"
#define IO_EXCEPTION "java/io/IOException"
+#define SOCKET_EXCEPTION "java/net/SocketException"
#define INTERRUPTED_IO_EXCEPTION "java/io/InterruptedIOException"
#define NON_READABLE_CHANNEL_EXCEPTION "java/nio/channels/NonReadableChannelException"
#define NON_WRITABLE_CHANNEL_EXCEPTION "java/nio/channels/NonWritableChannelException"
@@ -101,6 +106,7 @@ void JCL_print_buffer(JNIEnv *, struct JCL_buffer *);
int JCL_init_buffer(JNIEnv *, struct JCL_buffer *, jobject);
void JCL_release_buffer(JNIEnv *, struct JCL_buffer *, jobject, jint);
void JCL_cleanup_buffers(JNIEnv *, struct JCL_buffer *, jint, jobjectArray, jint, jlong);
+int JCL_thread_interrupted(JNIEnv *, jclass);
static jfieldID address_fid;
static jmethodID get_position_mid;
@@ -110,6 +116,7 @@ static jmethodID set_limit_mid;
static jmethodID has_array_mid;
static jmethodID array_mid;
static jmethodID array_offset_mid;
+static jmethodID thread_interrupted_mid;
jmethodID
get_method_id(JNIEnv *env, jclass clazz, const char *name,
@@ -119,7 +126,7 @@ get_method_id(JNIEnv *env, jclass clazz, const char *name,
/* NIODBG("name: %s; sig: %s", name, sig); */
if (mid == NULL)
{
- JCL_ThrowException(env, "java/lang/InternalError", name);
+ JCL_ThrowException(env, "java/lang/InternalError", name);
return NULL;
}
@@ -247,6 +254,13 @@ JCL_cleanup_buffers(JNIEnv *env,
}
+int
+JCL_thread_interrupted(JNIEnv *env, jclass c)
+{
+ return (int) (*env)->CallBooleanMethod(env, c, thread_interrupted_mid);
+}
+
+
/*
* Class: gnu_java_nio_VMChannel
* Method: stdin_fd
@@ -291,7 +305,7 @@ Java_gnu_java_nio_VMChannel_stderr_1fd (JNIEnv *env __attribute__((unused)),
JNIEXPORT void JNICALL
Java_gnu_java_nio_VMChannel_initIDs (JNIEnv *env,
- jclass clazz __attribute__ ((__unused__)))
+ jclass clazz)
{
jclass bufferClass = JCL_FindClass(env, "java/nio/Buffer");
jclass byteBufferClass = JCL_FindClass(env, "java/nio/ByteBuffer");
@@ -316,6 +330,8 @@ Java_gnu_java_nio_VMChannel_initIDs (JNIEnv *env,
has_array_mid = get_method_id(env, byteBufferClass, "hasArray", "()Z");
array_mid = get_method_id(env, byteBufferClass, "array", "()[B");
array_offset_mid = get_method_id(env, byteBufferClass, "arrayOffset", "()I");
+
+ thread_interrupted_mid = get_method_id(env, clazz, "isThreadInterrupted", "()Z");
}
JNIEXPORT void JNICALL
@@ -973,7 +989,8 @@ Java_gnu_java_nio_VMChannel_connect (JNIEnv *env, jclass clazz __attribute__((un
if ((*env)->GetArrayLength (env, addr) != 4)
{
- JCL_ThrowException (env, "java/io/IOException", "expecting 4-byte address");
+ JCL_ThrowException (env, SOCKET_EXCEPTION,
+ "expecting 4-byte address");
return JNI_FALSE;
}
@@ -984,7 +1001,7 @@ Java_gnu_java_nio_VMChannel_connect (JNIEnv *env, jclass clazz __attribute__((un
origflags = fcntl (fd, F_GETFL, 0);
if (origflags == -1)
{
- JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
+ JCL_ThrowException (env, SOCKET_EXCEPTION, strerror (errno));
return JNI_FALSE;
}
/* Set nonblocking mode, if not already set. */
@@ -993,7 +1010,7 @@ Java_gnu_java_nio_VMChannel_connect (JNIEnv *env, jclass clazz __attribute__((un
flags = origflags | O_NONBLOCK;
if (fcntl (fd, F_SETFL, flags) == -1)
{
- JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
+ JCL_ThrowException (env, SOCKET_EXCEPTION, strerror (errno));
return JNI_FALSE;
}
}
@@ -1022,7 +1039,7 @@ Java_gnu_java_nio_VMChannel_connect (JNIEnv *env, jclass clazz __attribute__((un
if (fcntl (fd, F_SETFL, origflags) == -1)
{
/* oops */
- JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
+ JCL_ThrowException (env, SOCKET_EXCEPTION, strerror (errno));
return JNI_FALSE;
}
}
@@ -1033,7 +1050,7 @@ Java_gnu_java_nio_VMChannel_connect (JNIEnv *env, jclass clazz __attribute__((un
ret = cpnio_select (fd + 1, NULL, &wrfds, NULL, &timeo);
if (ret == -1)
{
- JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
+ JCL_ThrowException (env, SOCKET_EXCEPTION, strerror (errno));
return JNI_FALSE;
}
if (ret == 0) /* connect timed out */
@@ -1046,13 +1063,13 @@ Java_gnu_java_nio_VMChannel_connect (JNIEnv *env, jclass clazz __attribute__((un
}
else if (ECONNREFUSED == errno)
{
- JCL_ThrowException (env, "java/net/ConnectException",
+ JCL_ThrowException (env, CONNECT_EXCEPTION,
strerror (errno));
return JNI_FALSE;
}
else
{
- JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
+ JCL_ThrowException (env, SOCKET_EXCEPTION, strerror (errno));
return JNI_FALSE;
}
}
@@ -1063,13 +1080,13 @@ Java_gnu_java_nio_VMChannel_connect (JNIEnv *env, jclass clazz __attribute__((un
return JNI_FALSE;
else if (ECONNREFUSED == errno)
{
- JCL_ThrowException (env, "java/net/ConnectException",
+ JCL_ThrowException (env, CONNECT_EXCEPTION,
strerror (errno));
return JNI_FALSE;
}
else
{
- JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
+ JCL_ThrowException (env, SOCKET_EXCEPTION, strerror (errno));
return JNI_FALSE;
}
}
@@ -1080,7 +1097,7 @@ Java_gnu_java_nio_VMChannel_connect (JNIEnv *env, jclass clazz __attribute__((un
(void) addr;
(void) port;
(void) timeout;
- JCL_ThrowException (env, IO_EXCEPTION, "connect not supported");
+ JCL_ThrowException (env, SOCKET_EXCEPTION, "connect not supported");
return JNI_FALSE;
#endif /* HAVE_CONNECT */
}
@@ -1109,7 +1126,7 @@ Java_gnu_java_nio_VMChannel_connect6 (JNIEnv *env, jclass clazz __attribute__((u
origflags = fcntl (fd, F_GETFL, 0);
if (origflags == -1)
{
- JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
+ JCL_ThrowException (env, SOCKET_EXCEPTION, strerror (errno));
return JNI_FALSE;
}
/* Set nonblocking mode, if not already set. */
@@ -1118,7 +1135,7 @@ Java_gnu_java_nio_VMChannel_connect6 (JNIEnv *env, jclass clazz __attribute__((u
flags = origflags | O_NONBLOCK;
if (fcntl (fd, F_SETFL, flags) == -1)
{
- JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
+ JCL_ThrowException (env, SOCKET_EXCEPTION, strerror (errno));
return JNI_FALSE;
}
}
@@ -1146,7 +1163,7 @@ Java_gnu_java_nio_VMChannel_connect6 (JNIEnv *env, jclass clazz __attribute__((u
if (fcntl (fd, F_SETFL, origflags) == -1)
{
/* oops */
- JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
+ JCL_ThrowException (env, SOCKET_EXCEPTION, strerror (errno));
return JNI_FALSE;
}
}
@@ -1157,7 +1174,7 @@ Java_gnu_java_nio_VMChannel_connect6 (JNIEnv *env, jclass clazz __attribute__((u
ret = cpnio_select (fd + 1, NULL, &wrfds, NULL, &timeo);
if (ret == -1)
{
- JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
+ JCL_ThrowException (env, SOCKET_EXCEPTION, strerror (errno));
return JNI_FALSE;
}
if (ret == 0) /* connect timed out */
@@ -1170,13 +1187,13 @@ Java_gnu_java_nio_VMChannel_connect6 (JNIEnv *env, jclass clazz __attribute__((u
}
else if (ECONNREFUSED == errno)
{
- JCL_ThrowException (env, "java/net/ConnectException",
+ JCL_ThrowException (env, CONNECT_EXCEPTION,
strerror (errno));
return JNI_FALSE;
}
else
{
- JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
+ JCL_ThrowException (env, SOCKET_EXCEPTION, strerror (errno));
return JNI_FALSE;
}
}
@@ -1187,13 +1204,13 @@ Java_gnu_java_nio_VMChannel_connect6 (JNIEnv *env, jclass clazz __attribute__((u
return JNI_FALSE;
else if (ECONNREFUSED == errno)
{
- JCL_ThrowException (env, "java/net/ConnectException",
+ JCL_ThrowException (env, CONNECT_EXCEPTION,
strerror (errno));
return JNI_FALSE;
}
else
{
- JCL_ThrowException (env, "java/io/IOException", strerror (errno));
+ JCL_ThrowException (env, SOCKET_EXCEPTION, strerror (errno));
return JNI_FALSE;
}
}
@@ -1204,7 +1221,7 @@ Java_gnu_java_nio_VMChannel_connect6 (JNIEnv *env, jclass clazz __attribute__((u
(void) addr;
(void) port;
(void) timeout;
- JCL_ThrowException (env, IO_EXCEPTION, "IPv6 connect not supported");
+ JCL_ThrowException (env, SOCKET_EXCEPTION, "IPv6 connect not supported");
return JNI_FALSE;
#endif /* HAVE_CONNECT && HAVE_INET6 */
}
@@ -1338,11 +1355,12 @@ Java_gnu_java_nio_VMChannel_getpeername (JNIEnv *env, jclass clazz __attribute__
*/
JNIEXPORT jint JNICALL
Java_gnu_java_nio_VMChannel_accept (JNIEnv *env,
- jclass clazz __attribute__((unused)),
+ jclass clazz,
jint fd)
{
#ifdef HAVE_ACCEPT
int ret;
+ int tmp_errno = 0;
#ifdef HAVE_INET6
struct sockaddr_in6 addr;
@@ -1355,14 +1373,38 @@ Java_gnu_java_nio_VMChannel_accept (JNIEnv *env,
do
{
ret = cpnio_accept (fd, (struct sockaddr *) &addr, &alen);
+ tmp_errno = errno;
+
+ if (ret == -1)
+ switch (tmp_errno)
+ {
+ case EINTR:
+ /* Check if interrupted by Thread.interrupt(). If not then some
+ * other unrelated signal interrupted the system function and
+ * we should start over again.
+ */
+ if (JCL_thread_interrupted(env, clazz))
+ {
+ JCL_ThrowException (env, "java/net/SocketException", strerror (tmp_errno));
+ return -1;
+ }
+ break;
+#if defined(EWOULDBLOCK) && defined(EAGAIN) && EWOULDBLOCK != EAGAIN
+ case EWOULDBLOCK:
+#endif
+ case EAGAIN:
+ /* Socket in non-blocking mode and no pending connection. */
+ return -1;
+ default:
+ JCL_ThrowException (env, "java/net/SocketException", strerror (tmp_errno));
+ return -1;
+ }
+ else
+ break;
}
- while (ret == -1 && EINTR == errno);
+ while (1);
- if (ret == -1)
- {
- if (EWOULDBLOCK != ret && EAGAIN != ret)
- JCL_ThrowException (env, "java/net/SocketException", strerror (errno));
- }
+ cpio_closeOnExec(ret);
return ret;
#else
@@ -1582,7 +1624,11 @@ Java_gnu_java_nio_VMChannel_lock (JNIEnv *env,
struct flock fl;
fl.l_start = (off_t) pos;
- fl.l_len = (off_t) len;
+ /* Long.MAX_VALUE means lock everything possible starting at pos. */
+ if (len == 9223372036854775807LL)
+ fl.l_len = 0;
+ else
+ fl.l_len = (off_t) len;
fl.l_pid = getpid ();
fl.l_type = (shared ? F_RDLCK : F_WRLCK);
fl.l_whence = SEEK_SET;
diff --git a/native/jni/native-lib/cpio.c b/native/jni/native-lib/cpio.c
index 4d23b7a1f..2777a31b2 100644
--- a/native/jni/native-lib/cpio.c
+++ b/native/jni/native-lib/cpio.c
@@ -473,3 +473,13 @@ int cpio_readDir (void *handle, char *filename)
strncpy (filename, dBuf->d_name, FILENAME_MAX);
return 0;
}
+
+
+int
+cpio_closeOnExec(int fd)
+{
+ if (fcntl (fd, F_SETFD, FD_CLOEXEC) == -1)
+ return errno;
+
+ return 0;
+}
diff --git a/native/jni/native-lib/cpio.h b/native/jni/native-lib/cpio.h
index 97483d294..b388b5b50 100644
--- a/native/jni/native-lib/cpio.h
+++ b/native/jni/native-lib/cpio.h
@@ -64,6 +64,7 @@ JNIEXPORT int cpio_read (int fd, void *data, jint len, jint *bytes_read);
JNIEXPORT int cpio_write (int fd, const void *data, jint len, jint *bytes_written);
JNIEXPORT int cpio_fsync (int fd);
JNIEXPORT int cpio_truncate (int fd, jlong size);
+JNIEXPORT int cpio_closeOnExec(int fd);
#define CPFILE_FILE 0
#define CPFILE_DIRECTORY 1